Remote Audio Data (RAD)
V3.5 Spec
This document should be considered an “Internet-Draft”, as defined by the IETF, therefore it may be updated, replaced or obsoleted by other documents at any time and should not be cited other than as "work in progress.”
This document outlines the specification as used by on-demand audio clients for a client implementation of Remote Audio Data (RAD) framework. RAD requires a custom ID3 tag encoded with event metadata to allow clients to report valuable listening data to podcast content producers and sponsors.
Documentation for V1 of the Remote Audio Data (RAD) spec can be found on the NPR Dev Center. V2 of the RAD spec was developed in collaboration with working groups formed out of a RAD Winter Summit in February 2018. That document is still a working draft specification and should be referenced for context and historical background only.
Note: The encoded ID3 tags will not affect audio playback for any non-RAD clients.
Please see the Appendix for more detail on the RAD life cycle and the interaction of these parties.
All RAD data requests and responses should use the JSON data interchange format and are required to be sent over HTTPS. The HTTPS requirement also includes any publisher-provided tracking URLs.
RAD metadata is encoded as a parsable JSON string into custom ID3 tag named “RAD”,[a][b][c][d][e] which may be readable by anyone who chooses to inspect the tag within the audio file. Metadata shall be encoded as value for “remoteAudioData” JSON key. Publishers that desire an additional layer of security may choose to encrypt the values within the JSON payload before encoding their RAD metadata into the ID3 tag. The tracking URLs and events timestamps must be readable by the client framework. (Encryption is, however, out of scope for this document.)
A series of listening events are saved as objects within the "events":[ ] array of the encoded RAD metadata.
RAD event labels (JSON keys) and their values may be customized to fit the needs of the publisher; examples might include a percentage of completed listening, segment breaks or advertising spots.
Mandatory keys: remoteAudioData, trackingUrls, events, eventTime
Example of metadata with mandatory info (JSON keys) only:
(RAD)
{
"remoteAudioData": {
...
"trackingUrls": [
"https://tracking.publisher.org/remote_audio_data",
...
],
"events": [
{
"eventTime":"hh:mm:ss.sss",
...
},
...
]
}
}
Note: ellipsis (...) suggest that additional custom JSON key-value pairs may be added at discretion
Example metadata for RAD custom tag
(RAD)
{
"remoteAudioData": {
"podcastId":"510298",
"episodeId":"497679856",
"trackingUrls": [
"https://tracking.publisher1.org/remote_audio_data",
"https://tracking.publisher2.org/remote_audio_data",
"https://tracking.publisherN.org/remote_audio_data",
],
"events": [
{
"eventTime":"00:00:00.000",
"label":"podcastDownload",
"spId":"0",
"creativeId":"0",
"adPosition":"0",
"eventNum":"0"
},
{
"eventTime":"00:00:05.000",
"label":"podcastStart",
"spId":"0",
"creativeId":"0",
"adPosition":"0",
"eventNum":"1"
},
{
"eventTime":"00:05:00.000",
"label":"breakStart",
"spId":"123456",
"creativeId":"1234567",
"adPosition":"1",
"eventNum":"2"
},
{
"eventTime":"00:05:15.000",
"label":"breakEnd",
"spId":"123456",
"creativeId":"1234567",
"adPosition":"1",
"eventNum":"3"
}
]
}
}
Errors can occur in the transmission of RAD data from the client or to the tracking URL. Appropriate HTTP status codes should be used in response to client requests, and clients should respond with the agreed upon course of action:
The RAD spec currently supports implementation for MP3 and MP4 audio formats.
RAD-enabled clients will be required to:
When reporting, listened RAD events shall include the following data:
Example of reporting network request body:
{
"audioSessions": [
{
"podcastId": "510313",
"episodeId": "525083696",
"sessionId": "A489C3AD-04AA-4B5F-8289-4D3D2CFE4CFB",
"events": [
{
"sponsorId": "0",
"creativeId": "0",
"eventTime": "00:00:00.000",
"adPosition": "0",
"label": "podcastDownload",
"eventNum": "0",
"timestamp": "2018-10-24T11:23:07+04:00"
},
{
"sponsorId": "0",
"creativeId": "0",
"eventTime": "00:00:05.000",
"adPosition": "0",
"label": "podcastStart",
"eventNum": "1",
"timestamp": "2018-10-24T11:23:08+04:00"
},
{
"sponsorId": "111128",
"eventTime": "00:00:05.000",
"adPosition": "1",
"label": "breakStart",
"creativeId": "1111132",
"eventNum": "2",
"timestamp": "2018-10-24T11:23:09+04:00"
},
{
"label": "breakEnd",
"sponsorId": "111128",
"eventTime": "00:00:05.000",
"adPosition": "1",
"creativeId": "1111132",
"eventNum": "3",
"timestamp": "2018-10-24T11:23:10+04:00"
}
]
},
{
"podcastId": "510314",
"episodeId": "525083697",
"sessionId": "778A4569-4B06-469B-8686-519C3B43C31F",
"events": [
{
"sponsorId": "0",
"eventTime": "00:00:00.000",
"adPosition": "0",
"creativeId": "0",
"eventNum": "0",
"timestamp": "2018-10-24T11:23:11+04:00"
}
]
},
{
"podcastId": "510315",
"episodeId": "525083698",
"sessionId": "F825BE2B-9759-438A-A67E-9C2D54874B4F",
"events": [
{
"sponsorId": "0",
"eventTime": "00:00:00.000",
"adPosition": "0",
"label": "podcastDownload",
"creativeId": "0",
"eventNum": "0",
"timestamp": "2018-10-24T11:23:12+04:00"
}
]
}
]
}
Parameter | Default value | Description |
submission interval | 1 hour | the minimum time between executed requests to analytics server |
batch size | 100 events | the maximum number of events which may be sent to server within a request |
expiration time interval | 2 weeks (14 days based on Gregorian calendar) | the amount of time for which events are still relevant |
request header fields | none | key-values pairs that will be added to network request header fields |
RAD-enabled clients should support offline mode; RAD events should be stored on local persistent storage and be reported to tracking URLs when network connectivity re-establishes.
These stored RAD events should be deleted from local persistent storage; if the age is greater than the configuration parameter (expiration time interval) they should not be reported to the tracking URL.
Android RAD implementation must locate the remoteAudioData tag from media file metadata and parse the content.
Android RAD framework is designed to be integrated into client applications that are using ExoPlayer version 2.9.1. Clients implementing custom players will need to customize their implementation of RAD library accordingly.
The parsing is done asynchronously while the framework is monitoring the playback of the media player. The extracted remoteAudioData, together with the playback events and session details, are sent to a persistence service (Android IntentService) to be persisted in a local SQLite database. The framework is also comprised of a reporting service that is scheduled at a configurable interval of time to report the persisted events.
The iOS media player supports the parsing of custom fields in the ID3 tags by default, so no extra effort is needed on the part of the client to locate and parse the metadata encoded into a tag within the file.
iOS RAD framework is designed to be integrated into client applications that are using AVPlayer. Clients implementing custom players will need to customize their implementation of library RAD accordingly.
RAD is not intended to replace download statistics as a point of measurement for the on-demand audio industry; rather, the reported listening events will complement this metric.
Publishers must provide a tracking URLs where clients can report RAD events and choose their own method for storing and analyzing client-reported RAD data. A tracking URL may point to an in-house analytics solution or to a solution provided by a third party.
By grouping listening events by UUID, the data consumer can determine his/her own analytics methods and protocols.
Listened RAD events can be grouped by listening sessions defined on the client. These listening sessions are distinguished by a session ID, which is an UUID generated per media file within 24 hours. There is one required session ID and one optional.
Required mediaSessionID: A GUID generated by the client for each played media file per day per client. A mediaSessionID remains constant for that media file until the next day. For example, if a user listens to five media files in one day, there will be five mediaSessionIDs. If they listen to the same media file on their phone and then on their tablet, there will be two mediaSessionIDs. If they listen to one media file twenty times in one day, there will be one mediaSessionID.
Optional sessionID: A GUID generated by the client per day per client. A sessionID remains constant for a client until the next day. For example, if a user listens to five media files in one day, there will be one sessionID. If they listen to the same media file on their phone and then on their tablet, there will be two sessionIDs. If they listen to one media file twenty times in one day, there will be one sessionID. The definition of “per day” can vary client to client; a rolling 24-hour window is recommended, though not required.
Publishers may download the reported data to an analytics solution, which may involve a text parser that classifies listening events by download in a queryable form. Ideally, the solution would allow for querying listening events by podcast download and for querying specific listening events across all downloads. A complementary database with podcast information would allow for more complicated queries.
At least one valid tracking URL must be included in the encoded ID3 tag so that a RAD-enabled client may report listened RAD events. The tracking URLs will not be visible to the standard audio consumer, however publishers should be aware that they can be seen to anyone who inspects a ID3 tag.
Publishers may wish to include more than one tracking URL in the encoded ID3 tag so that a client can directly share event data.
Tracking URLs must be HTTPS; HTTP is not supported.
While publishers may configure listening events to track advertising playback, it is not currently in scope to include third-party tracking pixels from advertisers. Tracking URLs should be limited to publishers or vendor(s) designated by the publisher.
NPR’s RAD V1 pilot used existing web server resources, configured with an Apache virtual host entry similar to the following:
<VirtualHost *>
ServerName tracking.example.org
CustomLog /var/logs/apache2/tracking.example.org-access.log combined
ErrorLog /var/logs/apache2/tracking.example.org-error.log
DefaultType image/gif
RewriteEngine on
RewriteRule .* - [R=204,NS,L]
</VirtualHost>
Specific server configurations and CPU requirements will depend upon expected traffic and any preexisting system setup.
The RAD spec is not intended as a means to target individual listening behavior, but to provide anonymized, aggregated analytics information. Clients and publishers should adhere to applicable law, such as the EU’s General Data Protection Regulation’s data processing, privacy by design and privacy by default requirements.
Data Flow
[a]Shouldn't this be clarified? Or is it already and I'm just missing it? I checked a RAD:ed mp3 file with Eyed3 to find out what kind of frame is used.
[b]What would you recommend? Thanks!
[c]The information here simply isn't enough for anyone to be able to write RAD information to a mp3 file. Looking at a file processed through the online editor, I can see that the RAD data is stored in a TXXX frame with the description "RAD", and I would assume that's what supporting apps use to locate the information. That information should be in here somewhere, or at least linked to if available elsewhere.
[d]_Marked as resolved_
[e]_Re-opened_