Using Smart View SDK, send a content URL to a DMP(Default Media Player) app available on 2015, 2016 Samsung TVs(and will be expanded to 14 TVs later). Any non-DRM content supported by the HTML5 Video,Audio,Image is supported to watch in a basic player with a fixed UI.
Check Smart View SDK UX guideline for implementing DMP2.0
Launch and manage list of videos on the TV.
Once, the ‘service’ object has been fetched for the TV (to which video(s) have to be casted), it’s been determined that target TV supports DMP.
following core functions can be used to manage the video casting.
Example Android API usage:
VideoPlayer mVideoPlayer; mVideoPlayer = this.mService.createVideoPlayer(“YOUR APP NAME”); VideoPlayer.OnVideoPlayerListener videoPlayerListener = new VideoPlayer.OnVideoPlayerListener(applicationName) { @Override public void onBufferingStart() { //Do something here.. } @Override public void onBufferingComplete() { //Do something here.. } @Override public void onBufferingProgress(int progress) { //Do something here.. } @Override public void onCurrentPlayTime(int progress) { //Do something here.. } }; mVideoPlayer.addOnMessageListener(videoPlayerListener); mVideoPlayer.playContent(Uri.parse(uri), title, Uri.parse(thumbnail), new Result<Boolean>() { @Override public void onSuccess(Boolean r) { Log.v(TAG, "playContent(): onSuccess."); } @Override public void onError(com.samsung.multiscreen.Error error) { Log.v(TAG, "playContent(): onError: " + error.getMessage()); } });
Launch and manage list of audio files on the TV.
Once, the ‘service’ object has been fetched for the TV (to which audio has to be casted), & it’s been determined that target TV supports DMP.
following core functions can be used to manage the audio casting.
AudioPlayer mAudioPlayer; mAudioPlayer = this.mService.createAudioPlayer(); AudioPlayer.OnAudioPlayerListener audioPlayerListener = new AudioPlayer.OnAudioPlayerListener(applicationName) { @Override public void onBufferingStart() { //Do something here.. } @Override public void onBufferingComplete() { //Do something here.. } @Override public void onBufferingProgress(int progress) { //Do something here.. } @Override public void onCurrentPlayTime(int progress) { //Do something here.. } }; mAudioPlayer.addOnMessageListener(audioPlayerListener); mAudioPlayer.playContent(Uri.parse(uri), title, albumName, Uri.parse(albumArt), new Result<Boolean>() { @Override public void onSuccess(Boolean r) { Log.v(TAG, "playContent(): onSuccess."); } @Override public void onError(com.samsung.multiscreen.Error error) { Log.v(TAG, "playContent(): onError: " + error.getMessage()); } });
Launch and manage list of photos on the TV.
Once, the ‘service’ object has been fetched for the TV (to which image have to be casted), & it’s been determined that target TV supports DMP.
following core functions can be used to manage the image casting.
PhotoPlayer mPhotoPlayer; mPhotoPlayer = this.mService.createPhotoPlayer(“YOUR APP NAME”); PhotoPlayer.OnPhotoPlayerListener photoPlayerListener = new PhotoPlayer.OnPhotoPlayerListener(applicationName) { @Override public void onBufferingStart() { //Do something here.. } @Override public void onBufferingComplete() { //Do something here.. } @Override public void onBufferingProgress(int progress) { //Do something here.. } @Override public void onCurrentPlayTime(int progress) { //Do something here.. } }; mPhotoPlayer.addOnMessageListener(photoPlayerListener); mPhotoPlayer.playContent(Uri.parse(uri), title, new Result<Boolean>() { @Override public void onSuccess(Boolean r) { Log.v(TAG, "playContent(): onSuccess."); } @Override public void onError(com.samsung.multiscreen.Error error) { Log.v(TAG, "playContent(): onError: " + error.getMessage()); } });
Following listeners can be used to get events when respective events happen.
mVideoPlayer.setOnConnectListener(new Channel.OnConnectListener() { @Override public void onConnect(Client client) { Log.v(TAG, "setOnConnectListener()"); } }); mVideoPlayer.setOnDisconnectListener(new Channel.OnDisconnectListener() { @Override public void onDisconnect(Client client) { resetService(); Log.v(TAG, "setOnDisconnectListener()"); } }); mVideoPlayer.setOnErrorListener(new Channel.OnErrorListener() { @Override public void onError(com.samsung.multiscreen.Error error) { Log.v(TAG, "setOnErrorListener(): Error: " + error.toString()); } });
Various message Listeners have been added to the SDK.
Create an object of OnVideoPlayerListener / OnAudioPlayerListener / OnPhotoPlayerListener and register it using addOnMessageListener() to get the events, as and when, an event is triggered on TV.
Following are events supported by VideoPlayer / AudioPlayer / PhotoPlayer class.
VideoPlayer.OnVideoPlayerListener videoPlayerListener = new VideoPlayer.OnVideoPlayerListener() { @Override public void onBufferingStart() { Log.v(TAG, "PlayerNotice: onBufferingStart"); } @Override public void onBufferingComplete() { Log.v(TAG, "PlayerNotice: onBufferingComplete"); } @Override public void onBufferingProgress(int progress) { Log.v(TAG, "PlayerNotice: onBufferingProgress: " + progress); } @Override public void onCurrentPlayTime(int progress) { Log.v(TAG, "PlayerNotice: onCurrentPlayTime: " + progress); } @Override public void onStreamingStarted(int duration) { Log.v(TAG, "PlayerNotice: onVideoStreamStart: " + duration); } @Override public void onStreamCompleted() { Log.v(TAG, "PlayerNotice: onStreamCompleted"); } @Override public void onPlay() { Log.v(TAG, "PlayerNotice: onPlay"); } @Override public void onPause() { Log.v(TAG, "PlayerNotice: onPause"); } @Override public void onStop() { Log.v(TAG, "PlayerNotice: onStop"); } @Override public void onForward() { Log.v(TAG, "PlayerNotice: onForward"); } @Override public void onRewind() { Log.v(TAG, "PlayerNotice: onRewind"); } @Override public void onMute() { Log.v(TAG, "PlayerNotice: onMute"); } @Override public void onUnMute() { Log.v(TAG, "PlayerNotice: onUnMute"); } @Override public void onError(com.samsung.multiscreen.Error error) { Log.v(TAG, "PlayerNotice: onError: " + error.getMessage()); } @Override public void onAddToList(JSONObject enqueuedItem) { Log.v(TAG, "PlayerNotice: onAddToList: " + enqueuedItem.toString()); } @Override public void onRemoveFromList(JSONObject dequeuedItem) { Log.v(TAG, "PlayerNotice: onRemoveFromList: " + dequeuedItem.toString()); } @Override public void onClearList() { Log.v(TAG, "PlayerNotice: onClearList"); } @Override public void onGetList(JSONArray queueList) { Log.v(TAG, "PlayerNotice: onGetList: " + queueList.toString()); } @Override public void onCurrentPlaying(JSONObject currentItem, String playerType) { Log.v(TAG, "PlayerNotice: onCurrentPlaying: " + currentItem.toString()); } @Override public void onRepeat(VideoPlayer.RepeatMode mode) { Log.v(TAG, "PlayerNotice: onRepeat: " + mode.toString()); } @Override public void onControlStatus(int volLevel, Boolean muteStatus, Boolean shuffleStatus, VideoPlayer.RepeatMode repeatStatus) { Log.v(TAG, "PlayerNotice: onControlStatus: vol: " + volLevel + ", mute: " + muteStatus + ", shuffle: " + shuffleStatus + ", repeat: " + repeatStatus.name()); } @Override public void onVolumeChange(int level) { Log.v(TAG, "PlayerNotice: onVolumeChange V: " + level); } @Override public void onPlayerInitialized() { Log.v(TAG, "PlayerNotice: onPlayerInitialized"); } @Override public void onPlayerChange(String playerType) { Log.v(TAG, "PlayerNotice: onPlayerChange"); } @Override public void onApplicationResume() { Log.v(TAG, "PlayerNotice: onApplicationResume"); } @Override public void onApplicationSuspend() { Log.v(TAG, "PlayerNotice: onApplicationSuspend"); } }; mVideoPlayer.addOnMessageListener(videoPlayerListener);
Video/Audio/Photo player object provides following APIs to control
Mixed Contents(video,audio,photo) are disabled.
Lists provide ability to manage a list of content which play in sequence.
Sequence is maintained by the order in which content are added to the list.
In order to enlist an item in TV’s list, corresponding player has to have an established connection with TV widget.
Connection with TV widget is established when first playContent() is called & onSuccess() callback is received in setOnConnectListener().
Following are the list specific APIs available to the user.
btnAddToList.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (CastStateMachineSingleton.getInstance().getCurrentCastState() == CastStates.CONNECTED) { mVideoPlayer.addToList(Uri.parse(item.videoUrl), item.videoTitle, Uri.parse(item.thumbnailUrl)); } } }); List<Map<String, String>> list = new ArrayList<Map<String, String>>(); Map<String, String> item = null; try { JSONObject obj = new JSONObject(AssetJSONFile("videolist.json",MainActivity.this)); JSONArray jarray = obj.getJSONArray("videos"); for (int i = 0; i < jarray.length(); i++) { JSONObject json = jarray.getJSONObject(i); item = new HashMap<String, String>(); item.put("url", json.getString("url")); item.put("title", json.getString("title")); item.put("thumbnailUrl", json.getString("thumbUrl")); list.add(item); } } catch(Exception e){ Log.d(TAG, "Error: " + e); } mVideoPlayer.addToList(list);
resumeApplicationInForeground() :
If player is sent to background by any other process or otherwise, android library receives an event – onApplicationSuspend().
To bring the player to foreground (from suspended to active state), API - resumeApplicationInForeground() can be used.
Event onApplicationResume() is received when application is successfully brought to foreground.
btnBringAppToForeground.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mAudioPlayer.resumeApplicationInForeground(); } });
DMP allows developers to show standby-screen(s) and watermarks on DMP application, while content is being casted from mobile application.
Standby-screen is a splash screen shown to the user while they connect to TV. This screen may comprise of either application logo or any other information related to application. Developer may choose to provide up-to 3 images in standby-screen mode. If no standby images are provided, default DMP logo will be shown to the user with app’s connection status.
Watermark will be shown on top-right corner of the display area while the content is being casted on the TV. Ideal size for a watermark image is 150 (width) X 50 (height). Orientation, position & size of the watermark cannot be changed. If a larger image is provided, the image will be scaled to fit the watermark display area.
Following APIs are available for the developers to show their standby screen images & watermark images.
standbyConnect(Uri bgImageUrl1, Uri bgImageUrl2, Uri bgImageUrl3, Result<boolean> result) This API establishes connection with TV and shows provided splash-screen(s) on the TV.
It does not cast any content.
mAudioPlayer.standbyConnect(bgImageUri1, bgImageUri2, bgImageUri3, new Result<Boolean>() { @Override public void onSuccess(Boolean result) { Log.d(TAG, "standbyConnect(): success : "); mPlayerType = PlayerType.STANDBY; } @Override public void onError(com.samsung.multiscreen.Error error) { Log.e(TAG, "standbyConnect(): error : " + error.getMessage()); } });
This API shall be used when user has made the TV selection (i.e. after fetching Service object & before first call to PlayContent() API). This API won’t work if content has already been casted from the application.
setPlayerWatermark(Uri watermarkUrl)
@Override public void onPlayerInitialized() { try { String watermarkUrl = mSettings.getString(mContext.getResources().getString(R.string.watermarkUrl)); if (watermarkUrl != null && watermarkUrl != "") { mAudioPlayer.setPlayerWatermark(Uri.parse(watermarkUrl)); } } catch (Exception e) { Log.e(TAG, "onPlayerInitialized() : Exception : " + e.getMessage()); } }
This API should only be used after DMP has loaded on the TV, i.e. on or after onPlayerInitialized() callback.
removePlayerWatermark()
mAudioPlayer.removePlayerWatermark();
Following are the default media player specific errors for different type of error strings:
Following are the Speaker specific errors for different type of error Message:
'DMP' submisison will be open in early Oct. Until then, please enter the word ‘DMP’ in the ‘Cloud URL’ field, instead.
You must check the 'DMP' checkbox when you submit your application using DMP.
We recommend you to submit you mobile app on Seller office
There is no approval process required to use the DMP, but your mobile app can be tested for basic features and any problems or suggestions will be notified via Seller office.
Please view the source code in DefaultMediaPlayer2.0 to understand the basic workflow when using the SDK.
Downloads Sample Application