Configure SSAI for VOD content

Stitch server-side ads into your VOD delivery

JWP allows you to configure server-side ad insertion (SSAI) for your video-on-demand (VOD) content. By integrating SSAI, ads are seamlessly stitched into the video stream just-in-time, ensuring higher impressions and an improved viewer experience.

Additionally, you can use SSAI session data to enhance and control your advertising.



Prerequisites

Item Notes
Property-level enablement Toggle turning on the feature for an entitled property

Follow these steps to enable SSAI:
  1. On the Properties page, click the name of a property. The property settings appear.
  2. Under Content & ads enhancements, click Media & ads. The Media & ads tab opens.
  3. Under Server-side ad integration, toggle Enable SSAI to ON.
VOD content Video-on-demand media that is hosted on the JW Platform and prepared to stream

Get started with media management in the JW Platform.
Player embed Player library embedded on the web page

You can use the JWP player or a third-party player.

If you are using JWP, learn how to add a cloud-hosted or self-hosted player.
Site ID Unique identifier of the property or site that owns a media item

Follow this step to obtain a site ID:
  1. On the Properties page, in the Property ID column, click to copy the ID.
Media ID Eight-character, alphanumeric ID that uniquely identifies the media

Follow these steps to obtain a media ID:
  1. From the Media library page, click a media item. The media details page appears.
  2. In the Media ID field, click to copy the ID.
Ad config ID Unique identifier of an ad config

Follow these steps to obtain an ad config ID:
  1. On the Advertising page, click the OTT (ad config) tab.
  2. In the ID column, click to copy the ID of your desired ad config.

If you have not already, create an ad config.

NOTE: For VOD, the ad config defines the default timing between ads in your content and the ad tag URL from which ads are fetched.

You can set media-level ad cues to override the ad config’s default timing.

🚧

The default duration for just-in-time (JIT) ad breaks is 2 minutes. This is a property-level setting. Please contact your JWP representative if you require a different ad break duration.



Configure SSAI for VOD

To set up SSAI for your VOD content, you must retrieve the SSAI manifest URL and embed it in your player.

📘

By default, JWP’s SSAI setup stitches ads just-in-time. However, you can preload ads before a break using ad break data.

Follow these steps to configure server-side ads for VOD content:

  1. Fetch the SSAI manifest URL using the site_id, media_id, and ad_config_id parameters associated with your VOD content.

    Each VOD media item has two manifest URLs, one with SSAI enabled and one without ads. The SSAI-enabled manifest URL should follow the format below.

    https://cdn.jwplayer.com/v2/sites/{site-id}/media/{media-id}/ssai.{manifest_extension}?ad_config_id={config-id}
    

    This request returns a 302 redirect with a Location header pointing to the active JIT manifest.

  2. Make a GET call to follow the redirect URL and retrieve the JIT manifest.

    curl --request GET \
         --url https://cdn.jwplayer.com/v2/sites/{site-id}/media/{media-id}/ssai_session/{session-id}/jit.m3u8?ad_break_duration={duration}&ad_break_duration_preroll={duration}&cue_points=0.000%2C30.359%2C43.489&drm_policy_id={policy_id}
    

    This URL returns the SSAI-enabled manifest.

    💡

    This manifest includes #EXT-X-SESSION-DATA that contains the relative URI for retrieving SSAI session data.

    Example HLS URI
    #EXT-X-SESSION-DATA:DATA-ID="com.jwpc.ssai-session-endpoint",URI="info.json"
    
  3. Embed the SSAI manifest in your player.

    Set the file value to the redirect URL that points to the JIT manifest.

    <div id="vod-player"></div>
    <script>
      const playerInstance = jwplayer("vod-player").setup({
        file: "https://cdn.jwplayer.com/v2/sites/{site-id}/media/{media-id}/ssai_session/{session-id}/jit.m3u8?ad_config_id={config-id}",
        autostart: true
      });
    </script>
    

After embedding the manifest, your VOD stream will show server-side ads. You can now use session data to tailor the advertising experience.



Tailor the ad experience

Using the SSAI session and break data, you can customize your viewer’s ad experience with countdowns, ad skips, player controls, and more. Follow these to tailor your advertising:

  1. Retrieve the SSAI session data.
  2. Retrieve data for an ad break.
  3. Customize the viewer experience.

Retrieve SSAI session data

You can enhance your SSAI-enabled VOD content by retrieving SSAI session data. JWP’s session endpoint returns real-time information on ad breaks, durations, and tracking points, which help you tailor the advertising experience to your viewers.

📘

An SSAI-enabled VOD stream will play server-side ads with or without session data.

Follow these steps to retrieve SSAI session data:

  1. In your player configuration, add an event listener for sessiondata.

    At runtime, the player parses the manifest for #EXT-X-SESSION-DATA and emits a sessiondata event when it detects a DATA-ID matching jwpc-ssai-session-endpoint.

    player.addEventListener('sesiondata', (data) => {
      if (DATA-ID === 'com.jwpc.ssai-session-endpoint') {
        logMessage(`session info URL: ${data.uri}`);
        fetchInfoJson(data.uri);
      }
    });
    
  2. When sessiondata fires during playback, fetch the session data. The endpoint will return a JSON representation of the ad breaks in the session.

    📘

    Example JSON before ads are stitched
    This JSON contains the metadata for each ad break in the session, including break durations and tracking events. However, the ads have not yet been stitched for the break (ads_requested equals false).

    You can retrieve the ad break data for a JSON with stitched ads.
    {
      "breaks": [
        {
          "ad_break_tracking_events": null,
          "ads": null,
          "break_id": "break_0_0",
          "duration": 30.72,
          "time_offset": 0,
          "ads_requested": false,
          "url": "profile/mpegts-25-1920-v1/breaks/0/info.json"
        },
        {
          "ad_break_tracking_events": null,
          "ads": null,
          "break_id": "break_1_0",
          "duration": 120.96,
          "time_offset": 62.72,
          "ads_requested": false,
          "url": "profile/mpegts-25-1920-v1/breaks/1/info.json"
        },
        {
          "ad_break_tracking_events": null,
          "ads": null,
          "break_id": "break_2_0",
          "duration": 120.96,
          "time_offset": 195.68,
          "ads_requested": false,
          "url": "profile/mpegts-25-1920-v1/breaks/2/info.json"
        }
      ]
    }
    

You can use your SSAI session information to tailor break countdowns or player controls as needed. For a closer look at a stitched ad break, you can also retrieve ad break data.


Retrieve data for an ad break

JWP allows you to fetch specific ad break data.

By default, JWP stitches ads just-in-time (JIT). However, retrieving the break data triggers the SSAI system to stitch ads in advance.

Preloading ads in this way can reduce the risk of playback buffering or black states, provide tighter control over the timing and behavior of the player UI, and enable developers to fine-tune the ad experience based on session logic or user status. This approach is ideal highly curated or premium content.

Follow these steps to retrieve data for a specific ad break:

  1. Within the returned session data, identify the specific ad break you wish to target.
  2. Copy the url parameter for the specific ad break.
  3. In the session endpoint, replace info.json with the url value.
  4. Make another GET call to the updated endpoint with the appended ad break URL. This call prepares the SSAI system to stitch ads for the targeted break.
    curl --request GET \
         --url https://cdn.jwplayer.com/v2/sites/{site_id}/media/{media_id}/ssai_session/{ssai_session_id}/{appended_break_url}
    
    The endpoint will return a JSON representation of the session with ads stitched for the targeted break.

    📘

    Example JSON after ads are stitched
    This JSON contains the metadata for each ad break in the session, as well as the ads that occur in the preloaded break.
    {
      "breaks": [
        {
          "break_id": "break_0_0",
          "time_offset": 0,
          "duration": 30.72,
          "ads_requested": true,
          "ads": [
            {
              "id": "0",
              "start_time": 0,
              "duration": 7.68
            },
            {
              "id": "7",
              "start_time": 7.68,
              "duration": 9.6
            },
            {
              "id": "17",
              "start_time": 17.28,
              "duration": 9.6
            }
          ],
          "url": "profile/mpegts-25-1920-v1/breaks/0/info.json"
        },
        {
          "break_id": "break_1_0",
          "time_offset": 62.72,
          "duration": 120.96,
          "ads_requested": false,
          "ads": [],
          "url": "profile/mpegts-25-1920-v1/breaks/1/info.json"
        },
        {
          "break_id": "break_2_0",
          "time_offset": 195.68,
          "duration": 120.96,
          "ads_requested": false,
          "ads": [],
          "url": "profile/mpegts-25-1920-v1/breaks/2/info.json"
        }
      ]
    }
    
    

Now that you have fetched your break data, you can perform various actions to control and improve the advertising experience.


Customize the viewer experience

After retrieving session and break data, you can view details about the ads in each break, including their start times, durations, and tracking events. You can then use this information to customize the playback experience with the following actions.

Action Description
Check fill status of an ad break Determine whether a break is fully or partially filled and take appropriate action

Follow these steps:
  1. After retrieving the break-level session JSON, inspect the ads array.
  2. Sum the duration of each ad in the break.
  3. Compare the total to the break’s duration field.
  4. If the ad durations fall short of the break duration, treat it as partially unfilled.
Skip unused filler time Improve viewer experience by skipping black slates or unfilled ad slots

Follow these steps:
  1. Check ads_requested and compare total ads[].duration to the break’s duration.
  2. If ads_requested is false or total ad time is shorter, programmatically skip to the end of the break.
  3. Use your player API (such as the seek() or play()) to jump to the break end time.
Display ad countdowns Show viewers how much ad time remains to improve transparency and UX

Follow these steps:
  1. Extract the ads list from the break-level JSON.
  2. Track the current playback position.
  3. Subtract elapsed time within the break from total ad durations to display a real-time countdown.
Control playback UI during ads Comply with advertiser requirements and improve viewer engagement

Follow these steps:
  1. Use the break’s start_time and duration to detect when an ad in playing.
  2. Temporarily disable player controls like seeking or skipping using your player API.
  3. Optionally show a “Skip Ad” button based on timing logic or tracking events (such as appearing after 5 seconds).



FAQ

Will an ad be requested again if the user scrubs back?

No. Once an ad is stitched into the stream, it behaves like regular video content. If a user scrubs back, the same ad content will replay as part of the stitched video, but a new ad request will not be sent.

This helps maintain session consistency and avoids duplicate ad requests.




© 2007- Longtail Ad Solutions, Inc.