How to Optimize CSAI on Tizen and WebOS in 3 Steps

One notable change as the globe struggles with the pandemic's effects is the rise of OTT consumption through smart TVs. As more people turn to their living room TVs for entertainment, businesses have a unique opportunity to reap benefits from this trend. However, tapping into the advertising potential of smart TV platforms comes with its own set of challenges, especially in terms of client-side ad insertion (CSAI) optimization for systems like webOS and Tizen.

How to Optimize CSAI on Tizen and WebOS in 3 Steps (1)

Why invest in an offering for smart television applications?

Generally speaking, you can monetize video content in two ways: either the end-user (partly) pays for it, and/or you get the revenue by attracting a pool of companies willing to pay to sponsor a promoted message. Amidst the corona pandemic, consumption of media content through smart TVs surged significantly. 

According to the latest  State of Streaming report of Conviva (Q1 2021), viewing time on smart televisions has shown a year-over-year growth of a whopping 115%.

While OTT consumption through smart televisions is still a young, developing segment, it has been growing consistently over the last years, making it an interesting new market to invest in. If your business model is based on advertising revenue, it also raises other questions: can I use sponsored content here as well? And are there quirks? 

On more established platforms such as desktop and mobile devices, client-side is still the dominant approach compared to server-side ad insertion. If you are unsure what the difference is, make sure to read this article.

On smart TV web applications, we observed additional challenges getting client side ad insertion working. In this article, we take a deep dive into the biggest problem we encountered: start-up performance. 

Challenge: Higher start-up time

We observed that on platforms such as Tizen, the start-up time of advertisements in progressive download formats (such as MP4 or WEBM) tend to be significantly higher. With slower, we mean up to 8-10 seconds time-to-first frame. As a typical ad break exists of multiple ads, this makes this experience unbearable. 

Progressive downloads also pose a second challenge: you cannot change the quality of advertisement videos while you play them. If the bandwidth changes, the advertisement cannot scale up or down to match this without redownloading the full advertisement. As 4k is becoming the new standard resolution for televisions, picking a low conservative size to avoid issues is not desirable. 

Our investigation efforts were mostly focused on Tizen, as the start-up time was the highest on these devices. We figured out that WebOS has similar limitations and that a broader solution would be justified.


We noticed that the Tizen platform only allows one active video element at the same time. When you interact with a second element, it simply deactivates the first one. This means that the content is rendered as a black rectangle and has to be reactivated by the player. This introduces a visual glitch we wanted to avoid. 

Interestingly, there is a difference between versions: Tizen 3.0 does not allow preloading through video elements across the board. Tizen 5.0 is more tolerant and only deactivates the main content when you assign a new source to another video element. 

As a cross-platform player, we need to support the lower versions. This would force us to assign the ad source at the very last moment. No preload means extra delays. Combine this with factors as extra network latency and decoding time, and the delays count up to eight to ten seconds. Mainly the download turned out to be the biggest culprit. 

It is plausible that the start-up time could be further increased by variances in how the segment is encoded. For instance: if essential data is stored at the end, the platform needs to do a full download. In our testing, we did not observe such a deviation. 

We understand the value of advertising for our customers, so we investigated if there is a better way to make this work. After all, the high start-up time would drive end-users away and result in less revenue.


Upon further investigation, we figured out that two approaches worked like a charm: 

Preloading through a native player (f.i. AVPlay on Tizen), where one instance plays the current ad and the other preloads the next one. They would then swap as the ad pod plays. 

2 Using streaming advertisements variants found in VAST-manifests, by downloading the streaming manifest and segments up-front, but only append it when switching to an ad break. The advertisement would then play via MSE on the video element. 

We weighed both options and settled on streaming advertisements. The reasoning was practical: AVPlay would be restricted to just the Tizen platform, while the latter approach would work on all platforms that support MSE. 

Other considerations included: 

  1. The AVPlay-pipeline uses a different API, which would require us to internally bridge the differences between the AVPlay pipeline and our own universal API. 
  2. We would not have any control over the AVPlay-pipeline in case anything would not work out in the longer term. With our own MSE-based pipelines we have full control, making it easier to anticipate future requirements. 
  3. The AVPlay-implementation differs across versions. This may introduce inconsistencies, especially because native support for HLS and MPEG DASH differs vastly.
Implementing the solution

We approached this project in three steps. The first two were preparation steps. The last one was glueing everything together. Luckily, we were able to reuse big parts of our code-base, making the development process much shorter. 

Step 1: enable streaming advertisements

Previously, we played advertisements based on the native video playback capabilities of the platform. In practice, this meant we played them back in MP4 or WEBM-formats, among others. For the initial phase, we wanted to also enable the usage of our own streaming playback capabilities (MPEG-DASH and HLS). 

As this would be an impactful change, we made this option allowedMimeTypes an opt-in. We already had the API in our player configuration for the Google IMA integration. We added support for this option in our own VAST ad playback system so APIs would be consistent. 

Finally, we added a preference picker: when both MPEG DASH and HLS are allowed, the player will pick the MPEG DASH variant. If this is not possible, it falls back to HLS. If neither is allowed, the player picks a progressive media file the exact same way it used to do until now. 

Why MPEG-DASH over HLS? In HLS, it is quite common to have MPEG-TS segments. Remuxing these takes time and CPU cycles, things that aren’t abundantly available on most smart TV platforms. With MPEG-DASH, this transmuxing step is often not needed. 

In order to avoid having to spend CPU cycles on remuxing, MPEG-DASH became our go-to choice. In the end, we were able to play streaming advertisements, but without the optimizations of preloading the advertisements yet.

Step 2: Allow the caching API to store segment in RAM

Given the smart TV platform limitations, we wanted advertisements to start loading before we append data to the . When we considered the different mediabuffer 

options, we figured out that the most efficient way was to internally reuse the Caching API. This API allows us to cache parts of a stream up-front and do offline playback. Instead of using Cachi API in a standard way, which stores data on the disk, we wanted to store it in non-persistent (RAM) memory. 

In this phase, we internally extended the Caching API to allow such capabilities. 

Storing data in a non-persistent way allowed us to work around writing complex logic for handling edge cases such as handling insufficient storage memory, or cleaning ups segments if the application would close unexpectedly. 

Step 3: Implementing ad pre loading 

The last part was glueing everything together. At this point, we were already able to play streaming advertisements and indicate that we want to download a stream up-front without appending it to a mediabuffer .

What remained was integrating the components together and fine-tuning the package. In our own ad VAST ad player, we download VAST metadata slightly before the adbreak starts. So we added logic to hook into this and download the first ad when the VAST data is available. 

A streaming advertisement download will only start when: 

The VAST manifest contains streaming variants The -configuration enables it allowedMimeTypes (disabled by default) The platform supports one of the allowed streaming mime-types. 

When an advertisement is too short - less than five seconds - we download the start of the consecutive streaming ad as well. As ads play, we clean up the cached data and schedule the upcoming advertisements until the end of the ad break is ended. As we only preload the start of the advertisement, the rest of the asset follows regular ABR logic. When the bandwidth changes, the player can anticipate this and switch quality. This was not possible with ads in a progressive download format, such as MP4. 

The result works quite well, as the start-up time is noticeable faster. We don’t have exact metrics, but in our testing lab, we noticed the start-up time would down to a maximum of two seconds. Coming from eight or more, this is a significant reduction. As our playback pipelines are continuously improved, the ad player will be able to reap the benefits from this as well. 

This change is available in our web SDK as of 2.84.0. iOS and Android SDKs are, for now, disabled from this offering.

Alternative approaches

We went all the way to support this use case, but it certainly is not the only way to do advertising on smart televisions. For completeness, we list alternatives: 

Server-side ad insertion is a viable alternative for targeting smart televisions, although it is slightly more complex to set up. In this scenario, the advertisements are part of the stream. The player integrates with metadata provided by the SSAI server to build a full ad experience. This includes adding a link to a landing page, adjusting the user interface, showing how long advertisements still take and tracking progress using standard ad beaconing. 

The set-up for SSAI is more complex than client-side ad insertion but pays itself back in a higher fill rate and better user experience. 

There are less common alternatives as well: static non-media advertisements, such as non-linear (banners) or companion ads (ads shown outside the player). Thinking out of the box, there are much more options to earn money from free content: sponsored product placement, paid bonus content, selling merchandise… You could even show a non-intrusive banner advertisement while the content is paused.

Let's get in touch!

If you want to try out our new streaming CSAI-ads, feel free to contact one of our experts to help you get started.

Any questions left? Contact our THEO experts.


Subscribe by email