Stay organized with collections
Save and categorize content based on your preferences.
This guide shows how to implement bookmarking using the IMA DAI SDK
when using Dynamic Ad Insertion (DAI) for video-on-demand (VOD) streams.
This assumes a working IMA DAI implementation, such as the one presented in
Get Started.
What is bookmarking?
Bookmarking is the ability to save and then return to a specific point
in the content stream. Suppose a user watches five minutes of content,
leaves the video stream, and then returns to it. Bookmarking saves the
user's position in the stream so the stream can pick up from where it
left off, providing a seamless experience to the viewer.
DAI bookmarking under the hood
When bookmarking a DAI stream, you must record the stream id and time
when the user leaves the video. When the user returns, re-request the
stream and seek to the saved time. Since each instance of the requested
stream can have ad breaks of different durations simply saving the stream
time won't work. What you really want to do is continue from the same
content time.
Conversion methods to the rescue
The IMA DAI SDK provides a pair of methods to request the content time
for a given stream time and the stream time for a given content
time. Using these conversion methods you can store the bookmarked
content time and then seek to the corresponding stream time in
the new instance of the stream. Here's the approach, including a link
to a sample app that shows a working bookmarking implementation.
Save and load ad stream bookmarks
Save a bookmark when the content player is paused.
functionloadUrl(url){hls.on(Hls.Events.MANIFEST_PARSED,()=>{varstartTime=0;if(bookmarkTime){varstartTime=streamManager.streamTimeForContentTime(bookmarkTime);//SeekingonloadtriggerstheonSeekEndevent,sotreatthisseekas//ifit's snapback. Without this, resuming at a bookmark kicks you//backtotheadbeforethebookmark.isSnapback=true;}hls.startLoad(startTime);videoElement.addEventListener('loadedmetadata',()=>{videoElement.play();});});hls.loadSource(url);hls.attachMedia(videoElement);}
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-20 UTC."],[[["\u003cp\u003eThis guide explains how to implement bookmarking in video-on-demand (VOD) streams using the IMA DAI SDK for a seamless viewing experience when users return to previously watched content.\u003c/p\u003e\n"],["\u003cp\u003eBookmarking with DAI involves saving the content time, not the stream time, to ensure accurate resumption due to potential ad break variations.\u003c/p\u003e\n"],["\u003cp\u003eThe IMA DAI SDK provides methods \u003ccode\u003econtentTimeForStreamTime\u003c/code\u003e and \u003ccode\u003estreamTimeForContentTime\u003c/code\u003e to convert between stream and content time for bookmarking functionality.\u003c/p\u003e\n"],["\u003cp\u003eA sample app demonstrating a working bookmarking implementation is available for download and reference.\u003c/p\u003e\n"]]],[],null,["# Save and load ad stream bookmarks\n\nThis guide shows how to implement bookmarking using the IMA DAI SDK\nwhen using Dynamic Ad Insertion (DAI) for video-on-demand (VOD) streams.\nThis assumes a working IMA DAI implementation, such as the one presented in\n\n[Get Started](/interactive-media-ads/docs/sdks/html5/dai-quickstart).\n\n\nWhat is bookmarking?\n--------------------\n\nBookmarking is the ability to save and then return to a specific point\nin the content stream. Suppose a user watches five minutes of content,\nleaves the video stream, and then returns to it. Bookmarking saves the\nuser's position in the stream so the stream can pick up from where it\nleft off, providing a seamless experience to the viewer.\n\nDAI bookmarking under the hood\n------------------------------\n\nWhen bookmarking a DAI stream, you must record the stream id and time\nwhen the user leaves the video. When the user returns, re-request the\nstream and seek to the saved time. Since each instance of the requested\nstream can have ad breaks of different durations simply saving the stream\ntime won't work. What you really want to do is continue from the same\n**content time**.\n\nConversion methods to the rescue\n--------------------------------\n\nThe IMA DAI SDK provides a pair of methods to request the **content time**\nfor a given **stream time** and the **stream time** for a given **content\ntime** . Using these conversion methods you can store the bookmarked\n**content time** and then seek to the corresponding **stream time** in\nthe new instance of the stream. Here's the approach, including a link\nto a sample app that shows a working bookmarking implementation.\n\nSave and load ad stream bookmarks\n---------------------------------\n\nSave a bookmark when the content player is paused. \n\n onPause() {\n var bookmarkTime = Math.floor(\n streamManager.contentTimeForStreamTime(videoElement.currentTime));\n }\n\nLoading bookmarks\n-----------------\n\nLoad the bookmark when re-requesting a stream. \n\n function loadUrl(url) {\n hls.on(Hls.Events.MANIFEST_PARSED, () =\u003e {\n var startTime = 0;\n if (bookmarkTime) {\n var startTime = streamManager.streamTimeForContentTime(bookmarkTime);\n // Seeking on load triggers the onSeekEnd event, so treat this seek as\n // if it's snapback. Without this, resuming at a bookmark kicks you\n // back to the ad before the bookmark.\n isSnapback = true;\n }\n hls.startLoad(startTime);\n videoElement.addEventListener('loadedmetadata', () =\u003e { videoElement.play(); });\n });\n hls.loadSource(url);\n hls.attachMedia(videoElement);\n }\n\nSample app\n----------\n\n[Download the Sample app](//github.com/googleads/googleads-ima-html5-dai)\nto see a bookmarking implementation."]]