top

Using AVPlay

This document shows you how to write media playing in your application.
You can play audio or video from locally path or from remote URL, all using AVPlay APIs.

Overview

Samsung Smart TV provides Multimedia player functionalities through AVPlay APIs.

Important

AVPlay supports common media type(MP4/AVI/MP3/WMV and etc), but we highly recommend that you use video(audio) tags for common media playback.

AVPlay is a solution for special media playback which is not supported by the video(audio) tags. as follows:

This guide explains how to playing common media. It is the base for special media playback.

Life Cycle and States of AVPlay

The following diagram shows the states and life cycle of an AVPlay driven by supported playback control operations. States of AVPlay is shown in oval figure. Arrows represent the playback control operations which drives AVPlay state transition. There are two types of arcs. The straight arrows represent synchronous method calls, while others represent asynchronous method calls.

From the below state diagram, it is clear that AVPlay has following states:

figure 1. AVPlay object states

figure 1. AVPlay object states

Tagle 1. States of AVPlay
State Description
NONE Before AVPlay instance creation. When webapis.avplay.close() is called AVPlay instance is removed.
IDLE When webapis.avplay.open() is called, which creates instance with media URL.
READY Once webapis.avplay.prepareAsync() or webapis.avplay.prepare() is called, buffering event(start/progress/complete) occur and AVPlay comes in READY state. You can get duration value of media using webapis.avplay.getDuration()
PLAYING When webapis.avplay.play() is called, current playtime event occur with valid values and AVPlay comes in PLAYING state.
PAUSED When webapis.avplay.pause() is called, AVPlay comes in PAUSED state.

Supported Media Formats

This section presents the media container, streaming, DRM combination and network protocol refer General Features

Valid and Invalid States of AVPlay Method

Table 2. States of AVPlay Method
Method name Valid States Invalid States Comments
getVersion any {} This method can be called in any state. State does not change after successful call this method.
open {NONE,IDLE} {READY,PLAYING,PAUSED} Successful call this method in a valid state, state comes in IDLE
prepare {IDLE} {NONE,READY,PLAYING,PAUSED} Successful call this method in a valid state, state comes in READY state.
prepareAsync {IDLE} {NONE,READY,PLAYING,PAUSED} Successful call this method in a valid state, state comes in READY state.
play {READY,PAUSED} {NONE,IDLE,PLAYING} Successful call this method in a valid state, state comes in PLAYING state.
pause {PLAYING} {NONE,IDLE,READY,PAUSED} Successful call this method in a valid state, state comes in PAUSED state.
stop {IDLE,READY,PLAYING,PAUSED} {NONE} Successful call this method in a valid state, state comes in IDLE state.
close any {} This method can be called in any state. Successful call this method, state comes in NONE state.
setDisplayRect {IDLE,PLAYING,PAUSED} {NONE,READY} State does not change after successful call this method in a valid state.
seekTo {IDLE,READY,PLAYING,PAUSED} {NONE} State does not change after successful call this method in a valid state.
jumpForward {READY,PLAYING,PAUSED} {NONE,IDLE} State does not change after successful call this method in a valid state.
jumpBackward {READY,PLAYING,PAUSED} {NONE,IDLE} State does not change after successful call this method in a valid state.
getState any {} This method can be called in any state. State does not change after successful call this method.
getDuration {READY,PLAYING,PAUSED} {NONE,IDLE} State does not change after successful call this method in a valid state.
getCurrentTime {READY,PLAYING,PAUSED} {NONE,IDLE} State does not change after successful call this method in a valid state.
setListener {IDLE} {NONE,READY,PLAYING,PAUSED} State does not change after successful call this method in a valid state.
setSpeed {READY,PLAYING,PAUSED} {NONE,IDLE,READY} State does not change after successful call this method in a valid state.
setDrm {IDLE} {NONE,READY,PLAYING,PAUSED} State does not change after successful call this method in a valid state.
setSoundAnalysisListener {IDLE} {NONE,READY,PLAYING,PAUSED} State does not change after successful call this method in a valid state.
unsetSoundAnalysisListener {PLAYING} {NONE,IDLE,READY,PAUSED} State does not change after successful call this method in a valid state.
setExternalSubtitlePath {IDLE,PAUSED} {NONE,READY,PLAYING} State does not change after successful call this method in a valid state.
setSubtitlePosition {PLAYING} {NONE,IDLE,READY,PAUSED} State does not change after successful call this method in a valid state.
setSilentSubtitle {READY,PLAYING,PAUSED} {NONE,IDLE} State does not change after successful call this method in a valid state.
setDisplayMethod {IDLE,READY,PLAYING,PAUSED} {NONE} State does not change after successful call this method in a valid state.
setSelectTrack {PLAYING,PAUSED} {NONE,IDLE,READY} State does not change after successful call this method in a valid state.
getTotalTrackInfo {READY,PLAYING,PAUSED} {NONE,IDLE} State does not change after successful call this method in a valid state.
getCurrentStreamInfo {READY,PLAYING,PAUSED} {NONE,IDLE} State does not change after successful call this method in a valid state.
setStreamingProperty {IDLE} {NONE,READY,PLAYING,PAUSED} State does not change after successful call this method in a valid state.
getStreamingProperty {PLAYING,PAUSED} {NONE,IDLE,READY} State does not change after successful call this method in a valid state.
setBufferingParam {IDLE} {NONE,READY,PLAYING,PAUSED} State does not change after successful call this method in a valid state.
suspend {READY,PLAYING,PAUSED} {NONE,IDLE} State does not change after successful call this method in a valid state.
restore {PLAYING,PAUSED} {NONE,IDLE,READY} State does not change after successful call this method in a valid state.

Config.xml Declarations

Before starting development on your application using avplay, make sure your “config.xml” has the appropriate declaration to allow use of related features.

Access external network resources

If you are using AVPlay to stream network-based media, your application must set policy(contents security policy(CSP) or W3C Access Requests Policy(WARP))

Important

"<tizen:privilege name=“http://developer.samsung.com/privilege/avplay”/>" privilege is not used in Samsung Smart TV for Tizen Platform.
If your application used avplay privilege in “config.xml”, MUST REMOVE It. It is deprecated privilege spec since 15" Samsung Smart TV.

Playing Media

Almost the whole AVPlay APIs have a state limitation. So the sequence of calling is very important.
You can play media as follows:

  1. Add the webapis library in your Application to call AVPlay APIs.

     <!-- HTML CODE -->
     <head>
     ...
     <script type="text/javascript" src="$WEBAPIS/webapis/webapis.js"></script>
     ...
     </head>
    
  2. Insert object tag( type attribute value is “application/avplayer” ) which is make rectangle hole in your application. You can see the playback video image in that. It is mean, if you change media display area using setDisplayRect() during playback media, you also have to change object tag style with same area value.

    var objElem = document.createElement('object');
    objElem.type = 'application/avplayer';
    
    /*
    //If you change Object tag style, it make rectangle hole in your application 
    //by CSS style value.
    objElem.style.left = 100 + 'px';
    objElem.style.top = 200 + 'px';
    objElem.style.width = 600 + 'px';
    objElem.style.height = 400 + 'px';
    */
    
    //You can append object tag in your document.
    document.body.appendChild(objElem);
    
  3. Call webapis.avplay.open() with your media URI(locally path / remote URL)
    You need to call open() method first in the AVPlay methods because after called this method AVPlay state change to IDLE. And Many AVPlay methods have a vaild state after IDLE. AVPlay supports locally path and remote URL base on network. But in case of locally path is supported only absolute path. Please note that this method doesn’t support relative path.

    webapis.avplay.open('yourMediaURI');
    
  4. Set handle AVPlay Event with webapis.avplay.setListener()
    Various events are sent when handing media that are embedded in AVPlay. This step lists them and provider some helpful information about using them.

    Table 3. Description of Event
    Event name Description
    onbufferingstart Sent when start buffering of media data.
    onbufferingprogress Sent when media buffering is in progress. The progress unit is persentage.
    onbufferingcomplete Sent when complete buffering of media data.
    onstreamcompleted Sent when playback completes.You should call webapis.avplay.stop()
    oncurrentplaytime Sent current playback time during PLAYING state. The time unit is millisecond(ms)
    onerror Sent when an error occurs during media playback
    onevent TBD
    onsubtitlechange Sent when subtitle text change during media playback. You get subtitle data value.
    ondrmevent TBD
    var listener = {
    	onbufferingstart: function () {
    		console.log("Buffering start.");
    	},
    	onbufferingprogress: function (percent) {
    		console.log("Buffering progress data : " + percent);
    	},
    	onbufferingcomplete: function () {
    		console.log("Buffering complete.");
    	},
    	onstreamcompleted: function () {
    		console.log("Stream Completed");
    		webapis.avplay.stop();
    	},
    	oncurrentplaytime: function (currentTime) {
    		console.log("Current playtime: " + currentTime);
    	},
    	onerror: function (eventType) {
    		console.log("event type error : " + eventType);
    	},
    	onevent: function (eventType, eventData) {
    		console.log("event type: " + eventType + ", data: " + eventData);
    	},
    	onsubtitlechange: function(duration, text, data3, data4) {
    		console.log("subtitleText: " + text);
    	},
    	ondrmevent: function (drmEvent, drmData) {
    		console.log("DRM callback: " + drmEvent + ", data: " + drmData);
    	}
    };
    
    webapis.avplay.setListener(listener);
    
  5. Set media display area with webapis.avplay.setDisplayRect()(Used only for video)
    It needs 4-parameters(left,top,width,height) that always uses 1920 x 1080 coordinate system regardless your application resolution. Even if you scale up(down) your document with viewport or any other way.
    So if your application resolution is 1920 x 1080, you can set same position value in your rectangle hole style(made by object tag).
    If not, you MUST change display position value to 1920 x 1080 coordinate. After display area set, video is displayed full screen mode which is default mode.
    You can change display mode to fit mode with webapis.avplay.setDisplayMethod('PLAYER_DISPLAY_MODE_LETTER_BOX')

    // For example, video positon is left:100px / top:200px / width:600px / height:400px
    
    // Case 1 your application resolution 1920 x 1080
    webapis.avplay.setDisplayRect(100,200,600,400);
    
    // Case 2 other resolution
    
    // Base resolution of avplay
    var avplayBaseWidth = 1920; 
    
    // Calculate ratio as base resolution
    var ratio = avplayBaseWidth / window.document.documentElement.clientWidth; 
    
    // Convert rect as base resolution
    var newLeft = 100 * ratio; 
    var newTop = 200 * ratio;
    var newWidth = 600 * ratio;
    var newHeight = 400 * ratio;
    
    webapis.avplay.setDisplayRect(newLeft,newTop,newWidth,newHeight);
    
  6. Call webapis.avplay.prepare() / webapis.avplay.prepareAsync()
    When AVPlay starts preparing the media, onbufferingstart event function, configured through parameter of setListener() is called. The call to prepare() can take a long time to execute, because it might involve fetching and decoding media data. So, as is the case with any method that may take long to execute, you should never call it from your application’s UI thread.
    Doing that will cause the UI to hang until the method done, which is a very bad user experience. To avoid hanging your UI, AVPlay supplies a convenient way to accomplish this task by using the prepareAsync() method. This method starts preparing the media in the background and returns immediately. When the media is done preparing, successCallback function, configured through parameter of prepareAsync() is called.
    And AVPlay state change to READY. In READY state, You can get information of media.(duration / resolution etc)

    // Case 1 Synchronous preparation
    webapis.avplay.prepare();
    
    // Case 2 Asynchronous preparation
    var successCallback = function() {
    	console.log('The media is done preparing');
    }
    
    var errorCallback = function() {
    	console.log('The media is failure preparing');
    }
    
    webapis.avplay.prepareAsync(successCallback,errorCallback);
    
  7. Call webapis.avplay.play()
    The call to play() can playback of media start. It is also supported resume playback after a prior pause(). When the media begins to play(playback), oncurrentplaytime event function, configured through parameter of setListener() is called.
    And AVPlay state change to PLAYING.

    webapis.avplay.play();
    
  8. Call webapis.avplay.pause()
    The call to pause() can pause of media. And AVPlay state change to PAUSED

    webapis.avplay.pause();
    
  9. Call webapis.avplay.stop()
    The call to stop() can stop of media. And AVPlay state change to IDLE.
    If you want same media replay after stop media, you call prepare() and play() because AVPlay keep to configured set(media URL / display area / event listener etc).
    You want to initialization, call close().
    When playback completes, onstreamcompleted event function, configured through parameter of setListener() is called.
    You should call stop() when onstreamcompleted is occured. Because last picture would be remained and oncurrentplaytime method is called until the stop() method call, which is a very bad user experience.

    webapis.avplay.stop();
    

Controlling Media

Seeking Media

AVPlay has two way to seek the media. First way is moved relative from current time, the other way is moved absolute from given time. Parameter unit is milliseconds. When you seek the media has a range of valid. Which is greater than 0 and less the media duration time. If you want to change the playback start time of media, call webapis.avplay.seekTo() before prepare().

//Case 1 Seeks the media during media playback(pause)
var successCallback = function() {
	console.log('The media is done moved');
}

var errorCallback = function() {
	console.log('The media is failure moved');
}

var currentTime = webapis.avplay.getCurrentTime(); 
var newTime = currentTime + 5000;

webapis.avplay.seekTo(newTime,successCallback,errorCallback);


//Case 2 Change playback start time
var successCallback = function() {
	console.log('The media is done moved');
}

var errorCallback = function() {
	console.log('The media is failure moved');
}
webapis.avplay.open('yourMediaURI');
...
//Move the playback start time to 10 minutes.
webapis.avplay.seekTo(600000,successCallback,errorCallback); 
...
webapis.avplay.prepare();
  • Using webapis.avplay.jumpFoward() / webapis.avplay.jumpBackward()
    jumpFoward() / jumpBackward() seeks the media to the new time which is moved relative based on the current time. jumpFoward() use to Fast-Forward and jumpBackward() use to rewind. In the case of relative, you should be confirm that the value of the parameter does not violate the seek media valid range based on the current time.

    //Seeks the media during media playback(pause)
    var successCallback = function() {
    	console.log('The media is done moved');
    }
    
    var errorCallback = function() {
    	console.log('The media is failure moved');
    }
    
    //Case 1 Fast-Forward
    webapis.avplay.jumpFoward(5000,successCallback,errorCallback);
    
    //Case 2 Rewind
    webapis.avplay.jumpBackward(5000,successCallback,errorCallback);
    

Trick Play Media

webapis.avplay.setSpeed() set the current playback speed. You can use positive or negative numbers as parameter. If the parameter is set to negative, the media starts playback in the reverse direction. For positive case, media playback in forward direction. Trick play has limited range based on streaming type. The tables below describe the trick play limited range into the AVPlay.

Table 4. Limited Rage of Trick Play
Streaming Type Speed Range
Widevine -32x ~ +32x
Smooth Streaming -16x ~ +16x
http(s) -8x ~ +8x
Dash -8x ~ +8x
HLS Not supported
//For example, you set speed to 2x in forword direction.

webapis.avplay.setSpeed(2);

Multiple Audio in Media

If your media supported multiple audio, you can change audio track during media playback. First, you need find audio track list in media. AVPlay has webapis.avplay.getTotalTrackInfo() which is get whole track informaiton(contain audio track) of media. It has a state limitation after READY state. getTotalTrackInfo() return Array type value, each Array item is object type which has three property.

  • type : It has three possible values that is “VIDEO”, “AUDIO”, "TEXT"
    You can find audio track using “AUDIO”
  • index : It is used to select audio track with setSelectTrack()
  • extra_info : It has more detailed information(language/channels etc) about each track which is object type.
var totalTrackInfo = webapis.avplay.getTotalTrackInfo();

for(var i=0; i<totalTrackInfo.length;i++) 
{
    if(totalTrackInfo.type =='AUDIO')
    {
        console.log('Find audio track.');
        console.log('audio track index is ' + totalTrackInfo.index);
        console.log('audio track language is ' + totalTrackInfo.extra_info.language);
    }
}

You can choose audio track using audio track index number in media. Call webapis.avplay.setSelectTrack() with audio track index number.

//For example, you choose audio track index number 2.

webapis.avplay.setSelectTrack('AUDIO',2);

Sample Application