Amazon Music Playback

Playback & DRM Overview

Overview

This document is intended for developers who are integrating their devices with Amazon Music via the Amazon Music Device API.

When a user taps PLAY on their device or app, the media they have requested should immediately begin playing. It should continue to play without interruption, even if bandwidth fluctuates. In addition, only authorized users should have access to the stream, and it should not be possible for the media to be downloaded or copied for use outside of Amazon Music.

Amazon Music uses several different technologies to achieve this user experience.

In order to support varying network conditions, streaming files are broken into short segments (sometimes called 'chunks'). Multiple versions of each chunk are provided in several different levels of quality, bit-rates, and codecs. To keep the experience seamless, lower quality chunks can be requested for faster download. Once bandwidth improves, higher quality chunks can be requested once more. These are all packaged together in a Manifest file, which is an XML file defined by the MPEG-DASH format (.mpd). Amazon Music also offers media in a variety of high-definition and ultra-high-definition streaming formats. Segments in these higher-quality formats will be contained within the Manifest if requested by the client.

Additionally, all segments in the Manifest are encrypted by DRM technology to protect against unauthorized downloading and copying. The exception to this is that the first 30 seconds of a track are sent unencrypted, to allow playback to begin quickly and to provide an additional buffer to avoid latency. Segments after that are encrypted. A license is required to decrypt these segments. The license is obtained via a 'license challenge,' a special request sent to the Amazon Music license server.

Amazon Music’s Big Screen HTML5 app and its Auto app handle DRM and Playback automatically. However, partners building apps for their own devices will need to take steps to implement this functionality.

The following sections will explain these steps in detail.

Prerequisites

Music playback from the Amazon Music catalog is only available for authorized consumer electronic devices. To be certified for Amazon Music playback implementation, device clients must meet the following requirements:

  • Playback must NOT occur on any computing platform or device where the end user has the ability to install any custom software; gain access to the file system; or install alternate trusted certificates that may be used to validate an HTTPS request.
  • All HTTP calls used to retrieve Amazon Music content or keys must:
    • Be authenticated with Login with Amazon (LWA) credentials.
    • Connect using TLS 1.2 or later.
    • Connect to Amazon Music over HTTPS/SSL.
    • During the SSL handshake, validate that
      1. The host name of the SSL certificate presented by the host matches the name of the host in the URL
      2. The certificate presented by the host is signed by a known root certificate authority.
  • The client must support the OPUS codec for standard-definition playback at a minimum. If HD, UHD, or Spatial Audio playback is supported, the client must support codecs for those as well.
  • The client must support DASH streaming on their devices. DASH manifests contain byte-ranges, and the client must support the range header when retrieving content. See the Manifest section for more details.
  • All devices must be able to report playback events to the API.
  • The client must support Widevine L3 or better (see below).
  • Devices must be certified by Amazon Music.

What is DRM?

DRM stands for Digital Rights Management. DRM technology controls who has access to digital media content. Think of DRM as the digital equivalent of a lock on a secure box, ensuring that only those with the right key can open it. DRM protects Amazon Music's streaming audio and ensures that only authorized users have access to it. It also protects against unauthorized downloading or copying.

DRM primarily relies on encryption. Amazon Music's content streams are encrypted and cannot be played without being decrypted. To playback content, clients must send a license request to a license server. If the request is valid, the server will send back a license key. The license allows the client's media player to decrypt the content and play it.

Music exposed through the Amazon Music APIs is protected with Widevine DRM. To implement Widevine DRM, developers need to onboard with Widevine and request the Widevine library.

Widevine

What is Widevine?

Widevine is a DRM technology provided by Google. Amazon Music's streaming media files are compatible with Widevine. In order to receive decryption licenses from Widevine's license server, developers must enroll with Widevine as a licensee. Widevine has restricted access to its documentation and SDKs to licensees only. It is recommended that developers contact Widevine and work on acquiring a license before beginning engineering efforts.

Widevine allows for three different levels of security: L1, L2, and L3. L1 is the highest, most secure level of protection. L1 and L2 require the device to have a hardware-based Trusted Execution Environment (TEE). Devices certified for L3 do not have this requirement.

Certification Level Widevine L1 Widevine L2 Widevine L3
DRM hardware required? Yes Yes No
TEE required? All content processing and decryption performed in TEE Decryption performed in TEE No TEE. Software based.

Onboarding with Widevine

Amazon Music has collaborated with Widevine to establish a process to assist with onboarding and acquiring the Widevine library components.

  1. Contact Widevine support here:
    1. Click on General Questions.
    2. Select the second option, “I have a general inquiry or am interested in completing a License Agreement”
    3. Fill out the rest of the information.
    4. In the Full Description box at the bottom, describe a few details on the API integration and put <Your Company Name> IS AN AMAZON MUSIC PARTNER.
  2. Widevine will reach out to you to have you sign a license agreement with Widevine.
  3. Widevine will provide you with the Widevine SDK and documentation.

Security model and architecture

The following is an overview of how a client should interact with Widevine's DRM services during playback.

There are four main components in this model:

  • License Server: Widevine's license server validates keys and provides the license that will be used to decrypt DRM-encrypted media.
  • Client Application: Proxies requests to and from the license Server
  • Media Player: The media player facilitates exchanges between the license server and the Content Decryption Module. However, it cannot decrypt license information or media. Widevine supports players for Android, iOS, Chrome, Linux, and more. It will also support OEM devices on a licensed request basis.
  • Content Decryption Module (CDM): A CDM must be installed on any device that will play back DRM-encrypted content. The CDM generates license requests and, once the license is received from the License Server, passes it to the OEMCrypto Module. It does not decrypt content itself.
  • OEMCrypto Module: This module uses encrypted license information to decrypt content. Decrypted content is passed back up the stack to the Media Player.

Playback Workflow with Widevine DRM

The following steps then need to occur for playback of Widevine DRM encrypted content to be successful:

  1. Client app must provision the CDM if it has not been provisioned already 1.1. Client app gets provisioning request from the Widevine CDM. 1.2. Client app sends Provisioning request to Provisioning server 1.3. Client app sends the provisioning response to the CDM
  2. Client app registers the a callback with the CDM, used to request licenses when needed.
  3. Client app makes a request to the Amazon Music service for playable asset using the URI provided by the API.
  4. Client app uses the URI specified in audio.uri of the audio object to get the MPEG-DASH manifest.
  5. Client app parses manifest for protected representations and extracts the license url for the key server.
  6. Client App loops through the segment list in the manifest requesting the appropriate audio segments. (this can be done asynchronously of the decryption and playback below)
  7. Client app creates a session in the Widevine CDM, the session is context for a particular license key, client apps may choose diffrent schemes to manage and cache session for optimization. Licenses are unique for tracks, each track will require a session.
  8. The CDM calls the get license callback registered earlier, to have the application proxy the license challenge to the license server.
  9. Client app requests the license using the license url extracted from the manifest, the headers from the audio object and the license challenge from the CDM callback.
  10. The Client app updates the license on the CDM.
  11. The client app passes each segment of the encrypted media to the media player.
  12. The Media player calls decrypt() on the CDM which returns decrypted content for the media player to play.
  13. Client app reports playback status to the Amazon Music API.
  14. The Client app closes the session with the CDM
Amazon Music Playback with DRM workflow
Amazon Music Playback with DRM workflow

The Widevine License Server will respond with an error code if for some reason it is unable to validate the License Challenge. See License Response HTTP Error Codes for a list of error codes and the meaning of each.

Headers for audio object request

Clients must specify the desired audio quality levels when making requests to the Amazon Music API. Use the X-Amzn-Audio-Device-Capability header for this purpose. The DRM type should also be specified using the X-Amzn-Audio-DrmType header. At this time the only available type is WIDEVINE.

The playback URL returned by the Amazon Music API will point to a XML manifest file with filtered content based on the highest quality audio requested by the client. A client requesting HD quality will not receive Ultra HD representations in the manifest.

The client should determine the audio quality that is best for the user's situation and request it. Factors to consider include the user's preferences, device capability, and current bandwidth. The manifest will include the requested audio quality as well as lower audio quality levels if available. Be aware that not all tracks in the Amazon Music catalog are available in all formats. The client should not make fixed assumptions that the manifest will contain the requested audio quality.

Audio object

The client will receive information about the audio object from the Amazon Music Device API in a JSON response. The audio object will contain HTTP headers in three lists: key, manifestHeaders, and audioSegmentHeaders. The client will need these headers to make certain types of resource requests. Use the headers as follows:

Example of an audio object returned:

"httpHeaders":
  {
   "audioSegmentHeaders": 
     [
       {
         "name": "Cookie",
         "value": "rid=4d1837b0-12e9-4390-a951-ac4c1219289b"
		 "value": "rid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
       }
	 ],
   "keyHeaders": 
     [
       {
         "name": "x-amz-music-rid",
         "value": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
       },
       {
         "name": "x-amz-music-asin",
         "value": "B0B4TYM52Y"
         "value": "xxxxxxxxxx"
       },
       {
         "name": "x-amz-target",
         "value": "com.amazon.digitalmusiclocator.DigitalMusicLocatorServiceExternal.getLicenseForPlaybackV3"
       },
       {
         "name": "x-amz-music-device-type",
         "value": "xxxxxxxxxxxxxx"
       },
       {
         "name": "x-amz-music-device-id",
         "value": "xxxxxxxxxxxxxxxx"
       },
       {
         "name": "x-amz-music-customer-id",
         "value": "xxxxxxxxxxxxx"
       },
       {
         "name": "x-amz-music-drm-type",
         "value": "WIDEVINE"
       },
       {
         "name": "Cookie",
         "value": "rid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
       }
	 ],
    "manifestHeaders": 
	  [
        {
          "name": "Cookie",
          "value": "rid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        }
      ]
  },
  "expires": null
  "uri": "https://d29r7idq0wxsiv.cloudfront.net/DigitalMusicDeliveryService/DashDrm.mpd?dmid=123456789&c=cf&sd=false&hd=false&uhd=false&3d=false&ra360=false&v=opus_flac_e&drm=wv&h=a12bc3456d789efg123h4i567j89k0lm123456np7"

Learn more about the audio object here.

Expiration

Note that the streaming URI and headers of the audio object is non-persistent. Their expiration date (UTC format) is specified by the expires property. After that time, the client needs to retrieve a refreshed audio object by calling the API endpoint providing the parent track definition again.

Audio Formats

Amazon Music offers a wide variety of music formats. In addition to standard audio, some songs in the Amazon Music catalog are available in high-definition lossless formats and even in spatial audio formats. Please note that not every audio track is available in all formats.

See a complete list of formats and codecs here.

Playback URLs vended from the Amazon Music API point to an XML manifest that conforms to the MPEG-DASH specification. The manifest for standard definition and high-definition audio will contain multiple audio-quality versions of the track, ranging from 16-bit/44.1kHz up to the highest resolution Amazon Music has available for the particular track. For UHD and Spatial audio, the manifest only contains the highest-quality version of the track.

HD and UHD representations are encoded with the FLAC audio codec. The spatial audio codecs are Dolby Atmos and Sony 360 RA. The manifest containing HD, UHD, and spatial audio will also refer to standard quality representations using the OPUS codec to allow players to fall back to a lower bandwidth variant if current network conditions cannot sustain high-definition streams.

The Manifest

Getting the manifest

The file returned will be an XML manifest that conforms to the MPEG-DASH specification (DASH stands for Dynamic Adaptive Streaming over HTTP). When requesting the manifest, pass the headers under audio.headers.manifestHeaders from the audio object response described previously.

Sample manifest file XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MPD minBufferTime="PT2S" type="static" mediaPresentationDuration="PT206.68173217773438S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:amz-music="urn:amazon:music:drm:2019" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:amz="urn:amazon:music:3p:music:2020">
    <Period id="0">
        <AdaptationSet id="1" contentType="audio" selectionPriority="2000">
            <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="89063a39-f6d2-463c-c906-61ac3c9bb158" value="cenc"/>
            <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
                <cenc:pssh>ABC123...XYZ789</cenc:pssh>
                <amz:LicenseUrl>https://music.amazon.com/NA/api/dmlvs/v1/getLicenseForPlaybackV3</amz:LicenseUrl>
            </ContentProtection>
            <SupplementalProperty schemeIdUri="urn:mpeg:mpegB:cicp:ProgramLoudness" value="-7.8 LUFS"/>
            <SupplementalProperty schemeIdUri="amz-music:trackType" value="HD"/>
            <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="2"/>
            <SupplementalProperty schemeIdUri="urn:mpeg:mpegB:cicp:AnchorLoudness" value="-7.6 LUFS"/>
            <Representation id="1" qualityRanking="4" codecs="flac" audioSamplingRate="44100" bandwidth="1087077" mimeType="audio/mp4">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
                <SupplementalProperty schemeIdUri="amz-music:bitDepth" value="16"/>
                <SupplementalProperty schemeIdUri="tag:amazon.com,2019:dash:StreamName" value="HD"/>
                <BaseURL>https://d17vo8z6jop21h.cloudfront.net/123abc...xyz.mp4</BaseURL>
                <SegmentList timescale="44100" duration="441000">
                    <Initialization range="0-1067"/>
                    <SegmentURL mediaRange="1352-1079003"/>
                    <SegmentURL mediaRange="1079004-2164530"/>
                    ...
                    <SegmentURL mediaRange="24564679-25179667"/>
                </SegmentList>
            </Representation>
            <Representation id="2" qualityRanking="0" codecs="flac" audioSamplingRate="44100" bandwidth="1792775" mimeType="audio/mp4">
                ...
            </Representation>
        </AdaptationSet>
        <AdaptationSet id="2" contentType="audio" selectionPriority="1000">
            ...
        </AdaptationSet>
    </Period>
</MPD>

Sample Manifest Files

The links below contain sample manifest files for a track in HD (16-bit / 44.1kHz), Ultra HD (24-bit / 44.1kHz), RA 360 and Dolby Atmos.

Understanding the manifest file

The important objects to note in this example are the <AdaptationSet> object and the <Representation> object. Each <Representation> object describes one bitrate option using a particular codec. An <AdaptationSet> object contains multiple <Representation> objects. Each has a different bitrate, but generally all <Representation> objects in an <AdaptationSet> use the same codec.

  • The trackType attribute of the <AdaptationSet> can have the values SD, HD, or 3D.
    • The HD adaptation set will contain all HD and Ultra HD (UHD) representations
    • The 3D adaptation set will contain either RA360 or DA representations

To pull down the actual audio asset, identify the <Representation> object in the manifest that you wish to request. The key attributes are codecs and qualityRanking, which is the bandwidth attribute of a <Representation> object. For the codecs attribute, the following are possible values:

  • OPUS Lossy "standard definition" (SD) quality representations
  • FLAC Lossless HD or UHD representations
  • MHA1 RA 360 representations
  • EC-3 Dolby Atmos representations

For a given codec type, an <AdaptationSet> will contain one or more bitrate representations using that codec. Bitrates are ranked from lowest to highest in ascending order of qualityRanking. A higher quality ranking number means a lower bitrate. The bandwidth attribute can also be used to infer bitrate. The bandwidth value is a worst case (highest) bitrate needed to sustain the stream. In general, they correlate with the average stream bitrates but can in some cases spike much higher than expected.

The License

Creating license challenge

Each <AdaptationSet> in the manifest file will include a header called ContentProtection that will in turn include two objects that are required for generating a license: pssh and LicenseUrl.

<ContentProtection schemeIdUri="urn:uuid:abde123f4-56a7-8bcd-e8f9-0abc-d1e2-34fab56c78de">
    <cenc:pssh>AAABBBCde1fAAAAAA2b+CdEfABc1deFab2C3d4FAAAB0SE12cd/EfABcD3T5gh7IJKabcC9GgYVwxabcd11dd3ihgjkWAQp68Cdkadhsp</cenc:pssh>
	<amz:LicenseUrl>https://music.amazon.com/NA/api/dmlvs/v1/getLicenseForPlaybackV3</amz:LicenseUrl>
</ContentProtection>

The device must parse the pssh and LicenseUrl from the manifest to create a license challenge. This license challenge will be used to retrieve the key. An example of the function call the media player should make to the CDN is createLicenseChallenge(pssh).

Getting the license

The device must send a POST request to the license vending Url (LicenseUrl) with the license challenge. The LWA token and the User-Agent along with the headers described in audio.headers.key need to be passed through as header parameters.

curl --location --request POST 'https://music.amazon.com/NA/api/dmlvs/v1/getLicenseForPlaybackV3' \
--header 'x-amz-music-asin: B098Z4XHTT' \
--header 'x-amz-music-rid: acaffd86-2266-424f-ad19-67a1aa33873b' \
--header 'x-amz-music-customer-id: A2UVA8V9BOYUMQ' \
--header 'Cookie: rid=acaffd86-2266-424f-ad19-67a1aa33873b' \
--header 'x-amz-music-drm-type: WIDEVINE' \
--header 'x-amz-music-device-id: MusicSDK' \
--header 'x-amz-music-device-type: A3DNCSDVBULX7K' \
--header 'x-amz-target: com.amazon.digitalmusiclocator.DigitalMusicLocatorServiceExternal.getLicenseForPlaybackV3' \
--header 'Authorization: Bearer <LWA bearer token>' \
--header 'User-Agent: DeveloperMac/1 Postman/2' \
--header 'Content-Type: application/json' \
--data-raw '{ \
  "licenseChallenge": "<Base64 License Challenge>" \
}'

Note that User-Agent should be <device name>/<device version> for devices or <app name>/<app version> for apps. User-Agent is used for metrics and troubleshooting.

License response

The license response will be in JSON and will contain one field such as:

HTTP/1.1. 200 OK

Content-Type: application/json 
{ 
  "license": "Ah8aALK3eh44dhgok9ViaRn"
}

The license is base64 encoded.

License Response HTTP Error Codes

This is not an exhaustive list of HTTP error codes, just the error codes related to DRM license fetching and what it means in the context of DRM license fetching:

Error Code Description
400 Bad Request
401 Unable to authorize, token invalid.
403 License denied (CDM revoked) or ineligible content or customer.
500 Internal Service Error
503 Service Unavailable (retry-able if network connectivity issues.)

License Expiration Testing

To simulate license expiration for testing, the player will set the expiration header, x-amz-music-license-expiration-secs, when requesting the license. The value of this header would indicate the time in seconds after which the returned license will expire. When the license server receives a license request with this header, the license server will return a license that will expire after the duration set in the header.

License Expiration Example

Requesting a license expiring in 60 seconds:

curl --location --request POST '<licenseURL>'\
--header 'Authorization: Bearer <LWA_TOKEN>'\
--header 'User-Agent: <User_agent>'
--header 'x-amz-music-asin: <track_asin>'\
--header 'x-amz-request-id: <requestId>'\
--header 'x-alexa-music-license-expiration-test-duration-secs: 60'\
-header 'Content-Type: application/json'\
--data-raw '{
 "licenseChallenge": "<base64 license challenge>"
}'

License Expiration Response

HTTP/1.1. 200 OK

Content-Type: application/json 
{ 
  "license": "Ah8aALK3eh44dhgok9ViaRn"
}

Decrypting the media

In response to the above request, the license vending URL will perform eligibility checks and if successful, the client device will be provided with a license that can be used to decrypt the audio file (BaseURL of each representation). This is done when calling the decryptAudioSegment function of the CDM.

Requesting segments

The client can request segments of audio by providing the desired byte ranges using the attribute mediaRange. While requesting the audio segments, pass the headers in audioSegmentHeaders.

The clear lead

To facilitate faster playback, the first 30 seconds of each track are un-encrypted. This is called the clear lead. When testing decryption, always make sure to playback more than the the first thirty seconds of a track.

Media player integration

For devices using a modern version of Android or running in a Chromium-based browser, an L3 CDM is pre-installed. Pre-built Widevine CDMs are available for many other media players as well. For these players, partners can download the compatible Widevine library and compile the player with it. Devices with built-in Widevine L1 functionality also already have a CDM.

In rare cases where a Widevine CDM does not already exist for a platform or device, Widevine will work with licensees to build compatible binaries. The steps to build integration into a media player are available in documentation available from Widevine.