Now Playing metadata that is sent to our platform is used automatically by our web players but can also be accessed manually for programmatic integration into other websites and apps.
Web player
While valid metadata is being received, our embedded web player will automatically display this to listeners during stream playback. This includes the stream pages on our website and the player inside our mobile apps.
This data is also used to perform an automated album artwork lookup by the web player. This behaviour can be disabled via the "Stream settings" on the "Streaming" page of the publisher dashboard.
Access metadata with HTTPS
To integrate "Now Playing" directly into a website or custom mobile app, the metadata can be retrieved using an HTTPS GET request:
curl --request GET https://edge.iono.fm/xmetadata/<stream_id>
This will return the latest available metadata for the specified stream as a JSON object. See the "Endpoint data fields" section for details on the supported field names and values.
Example contents:
{
event: "song",
dt: "2016-08-12T14:51:16-0200",
artist: "AC/DC",
title: "Black in Black",
duration: 185
}
Implementation notes
Please take note of these items when using this endpoint in your own players and client applications:
- While metadata input is offline and not being received from the station, requests will respond with the
404 Not Foundstatus code. - All fields except
eventmay be empty based on input from the station. - Client polling intervals must never be less than 15 seconds, 30 seconds recommended. We retain the right to rate-limit and/or disable access to any applications that have higher polling rates to prevent unnecessary overheads on our servers. Rate limited requests will respond with the
429 Too Many RequestsHTTP status code. - The endpoint can return HTTP
304 Not Modifiedresponses if theIf-Last-Modifiedheader is used in requests. ETag headers are also available. Clients are urged to make use of this information to ensure low overheads. - Responses will include the CORS header
Access-Control-Allow-Origin: *to enable direct consumption from Javascript clients. - Clients are recommended to only poll for this information while a listener is actively listening to the stream.
- We reserve the right to change the contents or location of this response in the future to allow extending it with more data.
Reference: Javascript example to poll a metadata endpoint
<!doctype html>
<html lang="en">
<script>
// Javascript to load and display "Now playing" metadata from iono.fm
// Requires HTML element: <div id="nowplayingtitle"></div>
// Define where do we load data from
const metadataUrl = 'https://edge.iono.fm/xmetadata/<your-stream-id>';
// How many seconds to wait before check.
// NOTE: New data only available every 30 seconds recommend no less than 10 seconds
const pollSeconds = 30;
// Function that load and displays "now playing" metadata
const loadAndRenderNowPlaying = async _ => {
console.log('Loading now playing data: ' + metadataUrl);
// Load URL
const response = await fetch(metadataUrl);
if (!response.ok) {
console.log('Could not load now playing data');
return;
}
// Parse the JSON data returned
console.log('Received response', response);
const responseJson = await response.json();
if (responseJson.artist === "" && responseJson.title === "") {
// Empty artist and title field means we're not currently in a song, clear the element
document.getElementById("nowplayingtitle").textContent = "-";
} else {
// Show the artist and song title on an HTML element with the id "nowplayingtitle"
document.getElementById("nowplayingtitle").textContent = responseJson.artist + ' - ' + responseJson.title;
}
};
</script>
<head>
<title>Now playing example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
Now playing:
<div id="nowplayingtitle">
</div>
</body>
<script>
// load and show the metadata on page load
loadAndRenderNowPlaying();
// start polling: load and display any updated metadata every few seconds
const poller = setInterval(loadAndRenderNowPlaying, pollSeconds * 1000);
// to end polling can call:
// clearInterval(poller);
</script>
</html>