<jupyter_start><jupyter_text>Dolby.io  Media APIs 101 - Getting Started Getting Started **Agenda**1. The Media API workflow and your Dolby.io account ~ 10 minutes2. The Enhance API ~ 10 minutes3. The Diagnose API ~ 5 minutes4. The Transcode API ~ 10 Minutes5. The Analyze API ~ 2 minutes6. The Music Mastering API ~ 2 minutes7. Webhooks ~ 5 minutes8. Questions ~ 10 minutes  The Media API Workflow **What are media APIs**- The Media APIs bring programmatic solutions to challenges faced in the Media and Content space...- - Poor audio quality- - Converting between audio and video codecs - - Mastering music- - Deriving insight and data from audio- - And more...- The Dolby.io Media APIs adhere to REpresentational State Transfer or REST architecture style. This means they can be interacted with in an language or framework, be that Kotlin, Python or C.  ![Workflow](images/workflow.PNG) Every request with the API requires:- A URL to direct the request to: "https://api.dolby.com/media/input"- A Header to authenticate the request:<jupyter_code>headers = {
    "x-api-key": "api_key",
    "Content-Type": "application/json",
    "Accept": "application/json",
}<jupyter_output><empty_output><jupyter_text>- and a Body containing the payload:<jupyter_code>body = {
    "url": input_url,
}<jupyter_output><empty_output><jupyter_text>API Keys & Dolby.iohttps://dashboard.dolby.io/signin  What can we use the Dolby.io Media APIs for? First, let's set our variables.<jupyter_code>import IPython

# Enter your Dolby.io Media API Key here.
api_key = "your_api_key"
# Enter your name here to customize the output URL later.
name = "Braden"

print("API Key and Name set!")<jupyter_output>API Key and Name set!<jupyter_text>Upload local filesLet's say our files are not currently accessible on a public URL. While you can use your cloud storage providers to [presign URLs temporarily](https://docs.dolby.io/media-apis/docs/media-input-and-output), this doesn't solve the local file issue. In comes the Input APIs.We will begin with a file already stored locally: `white_noise_demo.wav` as seen in the sidebar.<jupyter_code># Example Local File
IPython.display.Audio("white_noise_demo.wav")<jupyter_output><empty_output><jupyter_text>We can take this file and upload it with another API call!<jupyter_code>import requests

# Set or replace these values

file_path = "white_noise_demo.wav"
input_url = f"dlb://in/input-{name}.wav" # Setting the input URL to have a different location based on your name!

url = "https://api.dolby.com/media/input"
headers = {
    "x-api-key": api_key,
    "Content-Type": "application/json",
    "Accept": "application/json",
}

# Declare the dlb:// location we want to store the file in
body = {
    "url": input_url,
}

response = requests.post(url, json=body, headers=headers)
response.raise_for_status()
data = response.json()
presigned_url = data["url"]

# Upload your media to the pre-signed url response

print("Uploading {0} to {1}".format(file_path, presigned_url))
with open(file_path, "rb") as input_file:
  requests.put(presigned_url, data=input_file)<jupyter_output><empty_output><jupyter_text>And now the file can be accessed via our new `dlb://` url. This media is stored in an isolated location that only you can access with your API key. It is encrypted at rest and while in transit with https. Access to the production system is controlled and audited to prevent unauthorized use.> Note: this storage is TEMPORARY and will be removed within 24 - 48 hours.For Output, also note that you can save the files directly to your cloud provider of choice when done processing, no need to download every complete job! Read more at the documentation for your Cloud Storage Provider of choice here: https://docs.dolby.io/media-apis/docs/media-input-and-output  Enhance We can fine tune Enhance with a few different parameters to optimize for common audio issues including:- Noise reduction- Speech leveling and isolation- Loudness correction- Content tuning- Sibilance reduction- Plosive reduction- Dynamic equalization- Tone shaping- Hum reduction- Mouth click reduction**When defining the body**- Input location- Output locationInput and output can be a cloud storage provider.- Content type    - conference    - interview    - lecture    - meeting    - mobile_phone    - music    - podcast    - studio    - voice_over or voice_recording    Content type can be left undefined. Enhance will work it out.- Audio parameters    - loudness    - dynamics    - noise    - filter    - speech    - music    Audio parameters can be left undefined, all objects will default to enabled.Audio parameters have sub-features, for example:- Speech    - isolation     - sibilance (harsh consonant sound like "s", "sh", "x", "ch", "t", and "th")    - plosive (pops from "p" and "b")    - clickSee more: https://docs.dolby.io/media-apis/docs/speech**Lots to choose from depending on your use case****Let's see an example**<jupyter_code>#URL changes
url = "https://api.dolby.com/media/enhance"

output_url = f"dlb://out/output-{name}.wav" # Setting the input URL to have a different location based on your name!

#Header stays the same
headers = {
  "x-api-key": api_key,
  "Content-Type": "application/json",
  "Accept": "application/json"
}

body = {
  "input" : input_url,
  "output" : output_url,
  "content" : {
      "type": "voice_over"},
  "audio" : {
    "noise": {
      "reduction": {
        "amount": "max"
      }
    },
    "filter":{
      "hum": {
        "enable": True
      }
    },
    "speech": {
      "isolation": {
          "enable": True,
          "amount": 70
      },
      "sibilance": {
        "reduction": {
              "enable": True,
              "amount": "medium"
        }
      },
      "plosive": {
        "reduction": {
              "enable": True,
              "amount": "medium"
        }
      },
      "click": {
        "reduction": {
              "enable": False,
              "amount": "medium"
        }
      }
    }
  }
}

response = requests.post(url, json=body, headers=headers)
print(response.json())<jupyter_output><empty_output><jupyter_text>**Checking the status once again:**<jupyter_code>params = {
  "job_id": response.json()["job_id"]
}

stat = requests.get(url, params=params, headers=headers)
print(stat.json())<jupyter_output><empty_output><jupyter_text>**Download the output**<jupyter_code>url = "https://api.dolby.com/media/output"

params = {
    "url": output_url
}

import shutil #Package for file operations
output_path = "white_noise_demo-enhanced.wav"

with requests.get(url, params=params, headers=headers, stream=True) as response:
    response.raw.decode_content = True
    print("Downloading from {0} into {1}".format(response.url, output_path))
    with open(output_path, "wb") as output_file:
        shutil.copyfileobj(response.raw, output_file)<jupyter_output><empty_output><jupyter_text>`white_noise_demo-enhanced.wav` will appear in the sidebar when complete.**Lets give it a listen**<jupyter_code>IPython.display.Audio("white_noise_demo-enhanced.wav")<jupyter_output><empty_output><jupyter_text>**Original**<jupyter_code>IPython.display.Audio("white_noise_demo.wav")<jupyter_output><empty_output><jupyter_text>Questions?https://docs.dolby.io/media-apis/docs/enhance-api-guide  Diagnose (*Beta*) - Provides General Media Info- Audio Quality - Noise Score- Clipping- Loudness- Content ClassificationDiagnose is **fast**, and doesn't require a file to be downloaded - the results are in the same API call as the status.Read more about audio quality here: https://docs.dolby.io/media-apis/docs/audio-quality**Let's look at some code**<jupyter_code># Note the new URL endpoint
url = "https://api.dolby.com/media/diagnose"

headers = {
    "x-api-key": api_key,
    "Content-Type": "application/json",
    "Accept": "application/json"
}

body = {
    "input"  : input_url
}

response = requests.post(url, json=body, headers=headers)
job_id  = response.json()["job_id"]
print(response.json())<jupyter_output><empty_output><jupyter_text>**Checking Status and Getting Results**<jupyter_code>url = "https://api.dolby.com/media/diagnose"
headers = {
    "x-api-key": api_key,
    "Content-Type": "application/json",
    "Accept": "application/json"
}

params = {
    "job_id" : job_id,
}

stat = requests.get(url, params=params, headers=headers)
IPython.display.JSON(stat.json()) # Display interactive JSON element instead of just printing<jupyter_output><empty_output><jupyter_text>You should see a response with collapsible objects like the following:![diagnose output](./images/diagnose_output.png) An example workflow of how these APIs would be used in a real world setting might be the following:![flow](./images/flow.jpg)  Questions?https://docs.dolby.io/media-apis/docs/diagnose-api-guide  A quick note on other languages & our API reference - cURL Designed to transfer data using various network protocols- Works great with REST APIs like the Dolby.io Media APIs- Run through the terminal or PowerShell **Examples for many languages in the docs:** (Shell, JavaScript, Ruby, PHP, etc.)- https://docs.dolby.io/media-apis/reference/media-diagnose-post- https://docs.dolby.io/media-apis/reference/media-diagnose-getEasiest to do in Postman Collection:https://www.postman.com/dolbyio/workspace/dolby-io-media-apis/overview > **Keep your API keys private**https://docs.dolby.io/media-apis/docs/authenticationHave the option to use OAuth2 Tokens instead if you want it to expire naturally. Rotate your API keys often, as you have an API key for each application on your Dashboard!   Transcoding- Convert media of a particular file type to another- Transizing video media to different resolutions- Transrating audio media to different sample rates or bit ratesThe goal of Transcoding is to convert from one media format to another, from one media format to many variations, or in generating streaming media such as HLS or DASH.![formats](./images/formats.png)- Containers host video and audio compression codecs.- HLS: HTTP Live Streaming- DASH: Dynamic Adaptive Streaming over HTTP**Lets check out some code**!Making the Transcode request to convert a mp4 video to a wav audio file:<jupyter_code>url = "https://api.dolby.com/media/transcode"

headers = {
    "x-api-key": api_key,
    "Content-Type": "application/json",
    "Accept": "application/json",
}

# Convert the file to a WAV file
body = {
    "inputs": [{ "source" : "https://dolbyio.s3-us-west-1.amazonaws.com/public/shelby/indoors.original.mp4"}],
    "outputs": [
        {
            "id" : "my_mp4",
            "destination" : "dlb://out/airplane-transcoded.wav",
            "kind" : "wav"
        }
    ]
}

response = requests.post(url, json=body, headers=headers)
print(response.json())<jupyter_output><empty_output><jupyter_text>**Checking the status:**<jupyter_code>params = {
    "job_id": response.json()["job_id"]
}
stat = requests.get(url, params=params, headers=headers)
print(stat.json())<jupyter_output><empty_output><jupyter_text>**Downloading the output:**<jupyter_code>url = "https://api.dolby.com/media/output"
output_path = "airplane-example.wav"
params = {
    "url": "dlb://out/airplane-transcoded.wav",
}

with requests.get(url, params=params, headers=headers, stream=True) as response:
    response.raise_for_status()
    response.raw.decode_content = True
    print("Downloading from {0} into {1}".format(response.url, output_path))
    with open(output_path, "wb") as output_file:
        shutil.copyfileobj(response.raw, output_file)<jupyter_output><empty_output><jupyter_text>You should now see `airplane-example.wav` in the side bar!<jupyter_code>IPython.display.Audio("airplane-example.wav")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11691860961653429, 'fraction_numerical': 0.003501579981211034, 'mean_word_length': 4.154049295774648, 'pattern_counts': {'":': 49, '<': 64, '<?xml version=': 0, '>': 66, 'https://': 20, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '131090', 'license': 'CC0-1.0', 'n_tokens_mistral': 3707, 'n_tokens_neox': 3586, 'n_words': 1111, 'path': 'Workshop_Part_2.ipynb', 'repo_name': 'dolbyio-samples/Workshop-Getting-Started-Media-APIs', 'size': '11709'}