Media Controller
PUBLISHED
You can have your client application communicate with a media server.
To manage the media using the Media Controller API, you have to develop two applications:
- Client that sends requests to the server in order to change, for example, the playback state and position modes.
- Server that directly manages the media on the device.
The main features of the Media Controller API include:
- Setting up the client and server pair
You can set up the client and server pair by creating a new server using the
createServer()
method. On the client side, you can get a client and find active servers using thegetClient()
andfindServers()
methods. - Managing requests
You can send a request from the client to the server to modify various playback attributes. In the server, you can set up a listener to react to the client request and perform the requested task.
- Setting and getting the server icon URI
You can set the server icon URI and read it from the client.
- Receiving notifications from the server
You can receive notifications on changes made by the server by registering a listener with the
addPlaybackInfoChangeListener()
method. - Sending custom commands
You can use the client to send commands with the
sendCommand()
method.To receive and handle incoming commands in the server, use the
addCommandListener()
method. - Sending custom events
You can use the server to send the custom events with the
sendEvent()
method.To receive and handle the incoming events in the client, use the
setCustomEventListener()
method. - Sending and receiving search requests
You can use the media controller client to send the search requests with the
sendSearchRequest()
method.You can use the media controller server to receive the search requests using the
setSearchRequestListener()
method, and return theRequestReply
object to the client who sent the request. - Setting content type for the currently playing media
You can set content type for the currently playing media using the updatePlaybackContentType() server method.
- Setting age rating for the currently playing media
You can set age rating for the currently playing media using the updatePlaybackAgeRating() server method.
- Managing playlists on server side
You can manage playlists on server side by creating, saving, deleting, and getting information about playlists. You can also update the playback item from the playlists item list.
- Managing playlists on client side
You can manage playlists on client side by sending request about the new playback item to the server. You can then add listeners to be invoked when the playlist is updated on the server.
- Managing abilities of the media controller server
You can set the abilities of the media controller server by using the
MediaControllerAbilities
interface (in mobile [1], wearable [2], and tv [3] applications).You can use the
MediaControllerAbilitiesInfo
interface (in mobile [4], wearable [5], and tv [6] applications) to check which features are supported by the server. Information about current status of the media controller server abilities can be gathered bygetLatestServerInfo()
method. - Setting features of the media controller server
You can set the media controller server features using the server interfaces.
Prerequisites
To use the Media Controller API (in mobile [7], wearable [8], and tv [9] applications), the application has to request permission by adding the following privileges to the config.xml
file:
<tizen:privilege name="http://tizen.org/privilege/mediacontroller.client"/> <tizen:privilege name="http://tizen.org/privilege/mediacontroller.server"/>
Getting Client and Server
To manage the media controller features in your application, you must learn to set up the client and server pair:
- Create a media controller server using the
createServer()
method:var mcServer = tizen.mediacontroller.createServer();
- Get the client using the
getClient()
method:
var mcClient = tizen.mediaController.getClient();
- Define a success (and optionally, an error) event handler by implementing the
MediaControllerServerInfoArraySuccessCallback
interface (in mobile [10], wearable [11], and tv [12] applications):
var mcServerInfo; function findSuccessCallback(servers) { console.log('Found ' + servers.length + ' servers'); if (servers.length > 0) { mcServerInfo = servers[0]; } } function findErrorCallback(e) { console.log('Error name: ' + e.name + ' Error message: ' + e.message); }
- To search for all activated media controller servers, use the
findServers()
method of theMediaControllerClient
interface (in mobile [13], wearable [14], and tv [15] applications):
mcClient.findServers(findSuccessCallback, findErrorCallback);
Managing Requests
To manage the media controller features in your application, you must learn to handle requests from the client to the server:
- Create a
MediaControllerChangeRequestPlaybackInfoCallback
object (in mobile [16], wearable [17], and tv [18] applications) to define listeners for getting the requests from a client.Each listener must invoke the appropriate function to perform the related update on the server and send an appropriate notification to the client. For example, the
onplaybackstaterequest
listener must use theupdatePlaybackState()
method to update the playback state.var requestPlaybackInfoCb = { onplaybackstaterequest: function(state, clientName) { console.log('Request to change the playback state to: ' + state); mcServer.updatePlaybackState(state); }, onplaybackpositionrequest: function(position, clientName) { console.log('Request to change the playback position to: ' + position); mcServer.updatePlaybackPosition(position); }, onshufflemoderequest: function(mode, clientName) { console.log('Request to change the playback shuffle mode to: ' + (mode ? 'TRUE' : 'FALSE')); mcServer.updateShuffleMode(mode); }, onrepeatmoderequest: function(mode, clientName) { console.log('Request to change the playback repeat mode to: ' + (mode ? 'TRUE' : 'FALSE')); mcServer.updateRepeatMode(mode); }, onplaybackitemrequest: function(playlistName, index, state, position, clientName) { console.log("Playlist: " + playlistName + " index: " + index + " state: " + state + " position " + position + " requested by " + clientName); } };
- Add the listeners defined in the
MediaControllerChangeRequestPlaybackInfoCallback
object to the server:
var watchId = mcServer.addChangeRequestPlaybackInfoListener(requestPlaybackInfoCb);
The
watchId
variable stores the value, which can be used in the future to remove the listeners from the server using theremoveChangeRequestPlaybackInfoListener()
method. - At the client side, before sending a request, define optional success and error callbacks:
function successCallback() { console.log('Playback has been paused.'); } function errorCallback(e) { console.log('Error name: ' + e.name + ' Error message: ' + e.message); }
- You can send a request from the client using the
sendPlaybackState()
,sendPlaybackPosition()
,sendShuffleMode()
, orsendRepeatMode()
method of theMediaControllerServerInfo
interface (in mobile [19], wearable [20], and tv [21] applications).In the following example, send a request for the changing the playback state to paused using the
sendPlaybackState()
method:mcServerInfo.sendPlaybackState('PAUSE', successCallback, errorCallback);
Setting and Getting Server Icon URI
You can update the icon URI address of a media controller server, which can then be accessed from the client application. The default value of the server icon URI attribute is null. To use the icon URI attribute in your media controller application, follow these steps:
- Set the server icon on the server side:
var mcServer = tizen.mediacontroller.createServer(); mcServer.updateIconURI("icon.png");
- Get the server icon URI on the client side:
var mcClient = tizen.mediacontroller.getClient(); var mcServerInfo = mcClient.getLatestServerInfo(); console.log(mcServerInfo.iconURI);
Receiving Notifications from Server
To manage the media controller features in your application, you must learn to receive notifications from the server:
- Define the needed variable:
var watcherId;
- Define the event handlers for different notifications by implementing the
MediaControllerPlaybackInfoChangeCallback
interface (in mobile [22], wearable [23], and tv [24] applications):
var playbackListener = { onplaybackchanged: function(state, position) { console.log('Current playback state: ' + state); console.log('Current playback position: ' + position); }, onshufflemodechanged: function(mode) { console.log('Shuffle mode changed to: ' + mode); }, onrepeatmodechanged: function(mode) { console.log('Repeat mode changed to: ' + mode); }, onmetadatachanged: function(metadata) { console.log('Playback metadata changed: ' + JSON.stringify(metadata)); } };
- Register the listener to start receiving notifications about playback changes:
watcherId = mcServerInfo.addPlaybackInfoChangeListener(playbackListener);
- To stop receiving notifications, use the
removePlaybackInfoChangeListener()
method:
mcServerInfo.removePlaybackInfoChangeListener(watcherId);
Sending and Receiving Custom Commands
To manage the media controller features in your application, you must learn to send custom commands:
- On the client side:
- Define your custom command:
var exampleCustomCommandData = new tizen.Bundle({ myFilter: 'rock' });
- Define a success (and optionally, an error) callback implementing the
MediaControllerSendCommandSuccessCallback
interface (in mobile [25], wearable [26], and tv [27] applications):
function sendCommandSuccessCallback(data, code) { console.log('Server replied with return data: ' + JSON.stringify(data) + ' and code: ' + code); } function sendCommandErrorCallback(e) { console.log('Error name: ' + e.name + ' Error message: ' + e.message); }
- Send the command to the server using the
sendCommand()
method:
mcServerInfo.sendCommand('myPlaylistFilter', exampleCustomCommandData, sendCommandSuccessCallback, sendCommandErrorCallback);
- Define your custom command:
- On the server side:
- Create the
MediaControllerReceiveCommandCallback
object (in mobile [28], wearable [29], and tv [30] applications) to define a listener for receiving custom commands from a client:var commandReceiveListener = function(client, command, data) { console.log('command: ' + command + ' client: ' + client + ' data: ' + JSON.stringify(data)); return new tizen.mediacontroller.RequestReply(new tizen.Bundle({reply: 'response from server'}), 7); };
The callback within the listener returns the object with the response to the client. The client can obtain this value as an argument of the success callback of the
sendCommand()
method that it used to send the command. - Add the listener defined in the
MediaControllerReceiveCommandCallback
object to the server:
var watcherId = mcServer.addCommandListener(commandReceiveListener);
The
watcherId
variable stores the value, which can be used in the future to remove the listener from the server using theremoveCommandListener()
method.
- Create the
Sending and Receiving Custom Events
Custom command enables the client application to talk to the server application. The communication in the opposite direction is done with the help of custom events.
- To listen to the custom events on the client-side:
- Define your custom event listener callback function:
function eventReceivedCallback(serverId, event, data) { console.log('Event ' + event + ' received from ' + serverId); console.log('Event data: ' + JSON.stringify(data)); var status = 0; var data = {'test': 'data'}; return tizen.mediacontroller.RequestReply(data, status); }
Event handler function can return the
RequestReply
object which will be sent back to the event author.RequestReply
consists of status code integer and bundle data object. - Set the events listener:
mcClient.setCustomEventListener(eventReceivedCallback);
- Disable the events listener, when your application is no longer listening to the custom events:
mcClient.unsetCustomEventListener();
- Define your custom event listener callback function:
- To send the custom events on the server-side:
- Define the name and data of the custom event parameters:
var eventName = 'HelloWorld'; var eventData = new tizen.Bundle({'testKey': 'testValue'});
- Prepare reply callback function:
function eventReplyReceived(data, code) { console.log('client reply code: ' + code); console.log('client reply data: ' + JSON.stringify(data)); }
- Retrieve the recipient client info object:
var recipient = mcServer.getAllClientsInfo()[0];
This example assumes that there is only one client application currently running on the device. Otherwise, iterate all the
MediaControllerClientInfo
objects returned by thegetClientInfo()
method to select the recipient. - Send the event:
recipient.sendEvent(eventName, eventData, eventReplyReceived);
- Define the name and data of the custom event parameters:
Sending and Receiving Search Requests from Client to Server
Client application can send search requests, which consist of a collection of search conditions. Server listens for the incoming search requests and handles them accordingly. After handling a request, server sends a response to the client that sent the request.
Receiving Search Request
To receive and handle search request on the server, follow these steps:
- Get server handle:
var mcServer = tizen.mediacontroller.createServer();
- Define search request callback:
function searchRequestCallback(client, request) { console.log(client); console.log(request); // You can return RequestReply object, which will be sent to the client // who can handle it in search request reply callback. return new tizen.mediacontroller.RequestReply(123, {"someData": "someValue"}); }
- Register search request listener:
mcServer.setSearchRequestListener(searchRequestCallback);
Sending Search Request
To send the search request from the client application, follow these steps:
- Get client handle:
var mcClient = tizen.mediacontroller.getClient();
- Get server connection:
var mcServerInfo = mcClient.getLatestServerInfo();
- Prepare search request, which is an array of SearchFilter objects:
var request = [ new tizen.mediacontroller.SearchFilter('MUSIC', 'TITLE', 'tizen'), new tizen.mediacontroller.SearchFilter('MUSIC', 'ARTIST', 'samsung') ];
- Define reply callback:
function searchReplyCallback(reply) { console.log("server reply status code: " + reply.code); console.log("server reply data: " + reply.data); }
- Send search request:
mcServerInfo.sendSearchRequest(request, searchReplyCallback);
Setting Content Type for Currently Playing Media
Server can set content type for current playback. Client can access this type (read-only) and perform some actions that depend on the content-type, such as displaying different icons for different types of media items.
- Setting content type on the server side:
mcServer.updatePlaybackContentType("VIDEO");
- Accessing content type on the client side:
var type = mcServerInfo.playbackInfo.contentType; if (type == "VIDEO") { console.log("playing video"); } else if (type == "MUSIC") { console.log("playing song"); }
Setting Content Age Rating for Currently Playing Media
Server can set age rating for current playback. Client can access this rating (read-only) and perform some actions such as displaying a warning for underage users.
- Setting content age rating on the server side:
mcServer.updatePlaybackAgeRating("18");
- Accessing content age rating on the client side:
var userAge = 17; // App developer should retrieve actual user age from user profile. var rating = mcServerInfo.playbackInfo.ageRating; if (rating > userAge) { console.log("Warning: this content has age rating " + rating + "+."; }
Managing Playlists on Server Side
To manage the media controller playlists in your server application, you must learn to create, save, and delete playlists.
- To create a media controller playlist, use the
createPlaylist()
method:var playlist = mcServer.createPlaylist("testPlaylistName");
- To add item to playlist, use the
addItem()
method:
var metadata = { title: "testTitle", artist: "testArtist", album: "testAlbum", author: "testAuthor", genre: "testGenre", duration: "testDuration", date: "testDate", copyright: "testCopyright", description: "testDescription", trackNum: "testTrackNum", picture: "testPicture", seasonNumber: 1, seasonTitle: "testSeasonTitle", episodeNumber: 1, episodeTitle: "testEpisodeTitle", resolutionWidth: 1600, resolutionHeight: 900 }; playlist.addItem("index1", metadata);
- To save playlist, use the
savePlaylist()
method:
function successCallback() { console.log("savePlaylist successful."); } function errorCallback(error) { console.log("savePlaylist failed with error: " + error); } mcServer.savePlaylist(successCallback, errorCallback);
- To get information about playlists, use the
getAllPlaylists()
method:
function successCallback(playlists) { playlists.forEach(function(playlist) { console.log("Playlist name: " + playlist.name); }); } function errorCallback(error) { console.log("getAllPlaylists failed with error: " + error); } mcServer.getAllPlaylists(successCallback, errorCallback);
- To get information about playlist items, use the
getItems()
method:
function successCallback(items) { items.forEach(function(item) { console.log("Index: " + item.index + " Title: " + item.metadata.title); }); } function errorCallback(error) { console.log("getItems failed with error: " + error); } playlist.getItems(successCallback, errorCallback);
- To delete playlist, use the
deletePlaylist()
method:
function deleteSuccess() { console.log("deletePlaylist successful."); } function deleteFailure(error) { console.log("deletePlaylist failed with error: " + error); } mcServer.deletePlaylist(playlist.name, deleteSuccess, deleteFailure);
Managing Playlists on Client Side
To manage the media controller playlist in your application, you must handle requests from the client to the server:
- Send a request from the client using the
sendPlaybackItem()
method of theMediaControllerServerInfo
interface (in mobile [19], wearable [20], and tv [21] applications).mcServerInfo.sendPlaybackItem("testPlaylistName", "index1", "PLAY", 0);
- Define the event handlers for different notifications by implementing the
MediaControllerPlaylistUpdatedCallback
interface (in mobile [31], wearable [32], and tv [33] applications):
var listener = { onplaylistupdated: function(playlist) { console.log("updated playlist " + playlist.name); }, onplaylistdeleted: function(playlistName) { console.log("deleted playlist " + playlistName); } };
- Register the listener to start receiving notifications about playlist changes:
watcherId = mcServerInfo.addPlaylistUpdatedListener(listener);
- To stop receiving notifications, use the
removePlaylistUpdatedListener()
method:
mcServerInfo.removePlaylistUpdatedListener(watcherId);
Media Controller Server Abilities
Various abilities can be set to give the information to the clients about the supported features. These abilities can be divided into two groups:
- Media controller simple abilities
Each ability is described by a single value of
MediaControllerAbilitySupport
(in mobile [34], wearable [35], and tv [36] applications) and is not a part of a complex ability structure:- PLAYBACK_POSITION: Changing playback position.
- SHUFFLE: Changing shuffle mode.
- REPEAT: Changing repeat state.
- PLAYLIST: Adding/changing/removing playlists.
- CLIENT_CUSTOM: Receiving custom commands from media controller clients.
- SEARCH: Receiving search requests from media controller clients.
- SUBTITLES: Receiving requests for subtitles mode change from media controller clients.
- MODE_360: Receiving requests for spherical (360°) mode change from media controller clients.
- Media controller complex abilities
Each ability consists of several types:
- playback: Server playback actions.
- displayRotation: Setting display orientations.
- displayMode: Setting display modes.
Setting Media Controller Server Abilities
You can set the media server abilities as follows:
mcServer.abilities.playback.next = "YES"; mcServer.abilities.playback.prev = "YES"; mcServer.abilities.playback.rewind = "NO"; mcServer.abilities.playback.forward = "NO"; mcServer.abilities.playback.saveAbilities(); mcServer.abilities.displayMode.fullScreen = "YES"; mcServer.abilities.displayRotation.rotation180 = "YES";
Checking Media Controller Server Abilities
Using saveAbilities()
is required to save changes of playback abilities into database, otherwise changes will have no effect on the device and clients will not be notified about an update. Other abilities are updated instantly and there is no need to manually save these abilities.
To get abilities of the server on the client side:
var mcClient = tizen.mediacontroller.getClient(); var mcServerInfo = mcClient.getLatestServerInfo(); console.log("ability NEXT: " + mcServerInfo.abilities.playback.next); console.log("ability PREV: " + mcServerInfo.abilities.playback.prev); console.log("ability REWIND: " + mcServerInfo.abilities.playback.rewind); console.log("ability FORWARD: " + mcServerInfo.abilities.playback.forward);
Monitoring Media Controller Server Abilities
You can monitor changes of server abilities using the addAbilityChangeListener
method on client side. You will also receive the notifications about every ability change on the server side:
/* Client-side code */ var mcClient = tizen.mediacontroller.getClient(); var listener = { onplaybackabilitychanged: function(server, ability) { console.log("playback ability changed, server name: " + server.name + ", abilities: "); console.log(JSON.stringify(ability)); }, ondisplayrotationabilitychanged: function(server, ability) { console.log("display rotation ability changed, server name: " + server.name + ", ability: "); console.log(JSON.stringify(ability)); }, ondisplaymodeabilitychanged: function(server, ability) { console.log("displayMode ability changed, server name: " + server.name + ", abilities: "); console.log(JSON.stringify(ability)); }, onsimpleabilitychanged: function(server, type, ability) { console.log(type + " ability changed, server name: " + server.name + ", ability: " + ability); } }; var watchId = mcClient.addAbilityChangeListener(listener); /* Server-side code */ var mcServer = tizen.mediacontroller.createServer(); mcServer.abilities.playback.play = "YES"; mcServer.abilities.playback.saveAbilities(); mcServer.abilities.shuffle = "NO"; mcServer.abilities.repeat = "YES";
You will receive the information about the ability changes in every active media controller server. To receive the information only from selected servers, call subscribe()
:
var mcClient = tizen.mediacontroller.getClient(); var mcServerInfo = mcClient.getLatestServerInfo(); mcServerInfo.abilities.subscribe();
After the first use of subscribe()
, you will stop receiving changes from not subscribed servers.
You can stop monitoring the specific server, using the analogical unsubscribe()
method. In case, if no server is subscribed, notifications from all active servers will be sent.
Media Controller Server Features
Media controller API provides the following methods to change and monitor server features:
- Subtitles
- Mode360
- DisplayMode
- DisplayRotation
From server side, you can monitor the client requests for its features by using the corresponding change request listener:
var watcherId = 0; /* Watcher identifier. */ var mcClient = tizen.mediacontroller.getClient(); var mcServerInfo = mcClient.getLatestServerInfo(); /* Registers to be notified when display rotation changes. */ watcherId = mcServerInfo.displayRotation.addDisplayRotationChangeListener(function( rotation) { console.log(mcServerInfo.name + " server display rotation changed to " + rotation); }); /* Cancels the watch operation. */ mcServerInfo.displayRotation.removeDisplayRotationChangeListener(watcherId);
From the client side you can send the request for changing the specific feature of the server by using the sendRequest()
method. Request can be sent only after enabling specific ability on the server side:
var mcClient = tizen.mediacontroller.getClient(); var mcServerInfo = mcClient.getLatestServerInfo(); var rotation = "ROTATION_180"; mcServerInfo.displayRotation.sendRequest(rotation, function(data, code) { console.log("Server replied with return data: " + JSON.stringify(data) + " and code: " + code); });
Server can reply to the client requests by the RequestReply
object:
var watcherId = 0; /* Watcher identifier. */ var mcServer = tizen.mediacontroller.createServer(); var changeListener = function(clientName, rotation) { console.log("Display rotation change requested to: " + rotation + " by " + clientName); var result = false; /* do some action here and return according to the result */ if (!result) { return new tizen.mediacontroller.RequestReply( new tizen.Bundle({"message" : "Error - Not allowed"}), 13); } return new tizen.mediacontroller.RequestReply( new tizen.Bundle({"message" : "Success"}), 0); }; /* Registers to receive display rotation change requests from clients. */ watcherId = mcServer.displayRotation.addChangeRequestListener(changeListener);