View as Markdown

Ad controller

OpenVideo:OpenVideoAdController is the render-thread playback and ad state machine. It owns your Video node's playback fields, stream resolution, ad break routing, bookmarks, the app session and video-start analytics. It does not own focus, trick-play chrome, end cards, dialogs, layout, or the screen you return to after playback.

Create it only after the library reports loadStatus = "ready":

controller = CreateObject("roSGNode", "OpenVideo:OpenVideoAdController")
controller.player = m.video
controller.config = m.cfg
controller.callFunc("startSession")

Input fields

Field Type Description
player node Required. Your Video node. The controller sets content, control and seek, observes state and position, and shows or hides the node. You keep its size, position, z-order and focus.
adFacade node Optional full-screen Group RAF renders over. If omitted, the controller creates a hidden 1920x1080 group with a backdrop colored from config.theme.surfaceBase.
config assocarray See Configuration.
bookmarksEnabled bool Default true. When false, resume and completed reads return empty values and writes are skipped.

Functions

Function Arguments Description
startSession none Starts the once-per-launch app session. Call during boot, before the first playback.
play { videoId, streamUrl?, metadata?, resumePosition?, isAutoplay } Starts playback: resolves the stream, loads video context, applies the resume position, runs a preroll when one is due, and starts content. metadata can carry title, description, posterUrl, pageUrl, durationSeconds, captions and adBreaks.
stopPlayback { reason } user, error, endcard or finished. endcard tears down without emitting stopped; finished skips saving a bookmark.
pause, resume, togglePause none Content playback control. No-ops during ad breaks.
seekRelative seconds Relative seek; repeated presses coalesce.
seekTo content seconds Absolute seek in content time (stitched ad breaks are accounted for).
streamToContentSeconds stream seconds Converts stream time to content time, for hosts that observe player.position during stitched playback.
getContentDurationSeconds none Content duration, excluding stitched ad breaks.
getResumePosition, clearResumePosition, isCompleted videoId Bookmark helpers for your UI.
listContinueWatching none The continue-watching list, most recent first.
markInterrupted none Records that an ad break was interrupted, so the next session makes it good with a preroll.

Output fields

All output fields notify on every write.

Field Type Description
state string idle → resolving → zero or more adBreakStart/adBreakEnd pairs → contentStart → playing / paused / buffering → finished, stopped or error. error is followed by stopped. A client-side midroll resumes as adBreakEnd → buffering → playing, without a second contentStart.
adBreak assocarray { type, lane, podIndex, rendered }; type is preroll or midroll, lane is csai (client-side) or ssai (stitched).
error assocarray { code, message, fatal }. Non-fatal ad errors fall through to content.
controlsHint assocarray { action, seekTarget? }, action is show, hide or hideSeekThumb. Map it to your own transport chrome, or ignore it.
currentVideo assocarray The playing video after enrichment, plus related when available.

Typical host mapping

Controller output Your channel
resolving Show a loading state.
adBreakStart Hide content controls.
contentStart / adBreakEnd Restore your preferred focus target.
controlsHint Show or hide controls, update the seek preview.
finished Show an end card, or call stopPlayback({ reason: "finished" }).
error Show a playback dialog.
stopped Return to the screen you came from.