VAST XML for Samsung Tizen Smart TV
Samsung Smart TVs run Tizen OS and account for a large share of global Smart TV ad inventory. Ad playback on Tizen apps is handled either by the Google IMA SDK for Cast/CTV or by a custom VAST parser built on top of Tizen's native AVPlay media engine. Both paths share the same core VAST requirements.
Quick reference
| VAST versions | 2.0, 3.0, 4.0, 4.1 (IMA SDK); 2.0–3.0 (AVPlay native) |
| VPAID | Completely blocked |
| Wrapper chain limit | 4 hops (IMA); 3 hops recommended (AVPlay) |
| Required media format | MP4 H.264 + AAC; HLS supported |
| HTTPS | Required for all URLs |
AVPlay state machine and lifecycle
Tizen's webapis.avplay object exposes a state machine. Calling a method in the wrong state throws an InvalidStateError.
| State | Description |
|---|---|
| NONE | Player not yet created. No URL loaded. |
| IDLE | Player created after open(); not yet prepared. |
| READY | Prepared and buffered; ready to play. |
| PLAYING | Actively playing media. |
| PAUSED | Playback paused. |
The typical ad playback lifecycle:
// 1. Open with the ad media URL (NONE → IDLE)
webapis.avplay.open('https://cdn.example.com/ad.mp4');
// 2. Set display region (must be called in IDLE state)
webapis.avplay.setDisplayRect(0, 0, 1920, 1080);
// 3. Register playback callbacks before prepare()
webapis.avplay.setListener({
onbufferingstart: function() { console.log('Buffering started'); },
onbufferingcomplete: function() { console.log('Buffering complete'); },
onstreamcompleted: function() {
// Ad finished — resume content
webapis.avplay.stop();
webapis.avplay.close();
resumeContent();
},
onerror: function(eventid) {
console.error('AVPlay error:', eventid);
resumeContent(); // fall back to content
},
oncurrentplaytime: function(currentTime) {
// currentTime is in milliseconds
},
});
// 4. Prepare (IDLE → READY) — use prepareAsync for non-blocking
webapis.avplay.prepareAsync(
function() {
// Success: now READY → PLAYING
webapis.avplay.play();
},
function(error) {
console.error('Prepare failed:', error);
resumeContent();
}
);
// Cleanup after ad:
// webapis.avplay.stop();
// webapis.avplay.close();Playback callbacks
setListener() accepts an AVPlayPlaybackCallback object. Implement the relevant methods:
| Callback | When fired |
|---|---|
onbufferingstart() | Buffering begins (show spinner) |
onbufferingprogress(percent) | Buffering percentage update |
onbufferingcomplete() | Initial buffering done; playback will start |
oncurrentplaytime(ms) | Periodic playback position update in milliseconds |
onstreamcompleted() | End of stream reached |
onevent(eventid, data) | Miscellaneous events including PLAYER_MSG_BITRATE_CHANGE, PLAYER_MSG_CUE_TAG_INFO |
onerror(eventid) | Player error (see AVPlayError enum) |
ondrmevent(type, data) | DRM challenge data received; app must fetch license and call setDrm() |
Adaptive bitrate control
For HLS or MPEG-DASH ad streams, call setStreamingProperty(“ADAPTIVE_INFO”, ...)in IDLE state (after open(), before prepare()) to constrain the bitrate range:
webapis.avplay.open('https://cdn.example.com/ad/playlist.m3u8');
// Cap bitrate between 1 Mbps and 8 Mbps; start at the lowest available
webapis.avplay.setStreamingProperty(
'ADAPTIVE_INFO',
'STARTBITRATE=LOWEST|BITRATES=1000~8000'
);
webapis.avplay.setDisplayRect(0, 0, 1920, 1080);
webapis.avplay.prepareAsync(function() {
webapis.avplay.play();
}, errorHandler);The bitrate range format is minKbps~maxKbps (kilobits per second).STARTBITRATE accepts LOWEST, HIGHEST, or AVERAGE, or a numeric kbps value.
DRM support
AVPlay supports PlayReady and Widevine CDM for encrypted ad streams. Set up DRM in IDLE state before calling prepare():
// PlayReady
webapis.avplay.open('https://cdn.example.com/ad-pr.mp4');
webapis.avplay.setDrm(
'PLAYREADY',
'SetProperties',
JSON.stringify({
LicenseServer: 'https://license.example.com/pr',
// GenChallenge: false — AVPlay fetches license automatically
})
);
// Widevine CDM
webapis.avplay.open('https://cdn.example.com/ad-wv.mp4');
webapis.avplay.setDrm(
'WIDEVINE_CDM',
'SetProperties',
JSON.stringify({
LicenseServer: 'https://license.example.com/widevine',
AppSession: 'session-id',
DataType: 'MPEG-DASH',
})
);
// For Widevine, handle the ondrmevent() callback to install the license:
// webapis.avplay.setDrm('WIDEVINE_CDM', 'widevine_license_data', base64EncodedLicense);HLS ad cue tags
If the content stream uses HLS SCTE-35 ad markers, AVPlay fires a PLAYER_MSG_CUE_TAG_INFO event through the onevent() callback. The event data contains the cue-out/cue-in timestamps:
webapis.avplay.setListener({
onevent: function(eventid, data) {
if (eventid === 'PLAYER_MSG_CUE_TAG_INFO') {
// data example:
// "CUE_TAG_INFO: {CUEOUT-> timestamp : 18000, Expected AdDuration : 18000}"
// " {CUEIN-> timestamp : 36000, Actual AdDuration : 18000}"
console.log('Ad cue tag:', data);
// Parse and use to trigger VAST ad request at the right moment
}
},
});This is relevant for server-side ad insertion (SSAI) workflows where the VAST ad is stitched into the HLS manifest.
VPAID is blocked
Tizen's media layer does not execute JavaScript in the ad pipeline. Whether the app uses IMA SDK or AVPlay directly, any <MediaFile> with apiFramework="VPAID" is silently discarded. Always include a native MP4 creative.
→ vastlint rule: VAST-4.1-vpaid-in-interactive-context
Media file requirements
Samsung Smart TVs require MP4 H.264 video with AAC audio. HLS adaptive streams are supported and preferred for longer creatives or variable-bandwidth living-room connections. Provide at least a 1080p and a 720p variant.
<MediaFiles>
<MediaFile type="video/mp4" width="1920" height="1080"
bitrate="5000" delivery="progressive">
<![CDATA[https://cdn.example.com/ad-1080p.mp4]]>
</MediaFile>
<MediaFile type="video/mp4" width="1280" height="720"
bitrate="2500" delivery="progressive">
<![CDATA[https://cdn.example.com/ad-720p.mp4]]>
</MediaFile>
</MediaFiles>AVPlay native VAST parsers
Some Tizen apps implement a custom lightweight VAST parser using AVPlay rather than integrating the full IMA SDK. These parsers often support only VAST 2.0 and 3.0, and may not process VAST 4.x elements like <UniversalAdId> or <AdVerifications>. If you are unsure which integration a publisher uses, target VAST 3.0 for maximum compatibility.
Custom parsers also have varying behaviour around wrapper chain depth. Treat 3 hops as the safe maximum when targeting Samsung Smart TV inventory without knowing the player.
HTTPS requirement
All URLs in your VAST tag must use https://. Tizen OS blocks HTTP network requests in streaming contexts. This includes media files, impression pixels, wrapper URIs, and all event tracking URLs.
Duration format
<Duration> must use HH:MM:SS format. Both IMA SDK and most AVPlay-based parsers reject bare integer values.
→ vastlint rule: VAST-2.0-duration-format
Pre-flight checklist for Samsung Tizen
- No VPAID creatives — native MP4 or HLS only
- Target VAST 3.0 if publisher's player integration is unknown
- All URLs use HTTPS
- Wrapper chain ≤ 3 hops
- MP4 H.264
<MediaFile>at 1080p and 720p <Duration>inHH:MM:SSformat<Impression>with HTTPS URL presentversionattribute on root<VAST>element- Call
webapis.avplay.setListener()beforeprepare() - Call
webapis.avplay.setDisplayRect()in IDLE state - Always
stop()andclose()after ad playback - For encrypted streams: configure DRM with
setDrm()in IDLE state