I'm working on a tvOS application that plays video content using TVMLKit/TVJS. I'm trying to integrate Google IMA SDK to show pre-roll, mid-roll, and post-roll ads in my app.
Here’s what I’ve done so far:
- Video playback is handled through JavaScript in application.js.
- Ads are managed in Swift using Google IMA SDK.
- I use the evaluateJavaScript bridge to control video playback from Swift.
- I pause and resume the TVJS player (Player object) using a function like startPlayingVideo(value) from Swift based on the ad lifecycle.
Current Flow:
- When the video is about to start, I call loadAds() from JS.
- This presents a Swift ViewController that handles IMA ad requests.
- On adsManagerDidRequestContentPause, I pause the video using JS via the bridge.
- On adsManagerDidRequestContentResume, I resume the video.
The Issue:
- This setup doesn't behave consistently:
- Sometimes the ad plays in the background and video started playing as well but can not see the ad.
- Not able to see the post-roll ads
Relevant Code Snippets:
application.js
function startPlayingVideo(value) {
if (playerReference != undefined) {
if (value == true) {
playerReference.play();
else {
playerReference.pause();
}
}
}
function playVideo(videoURL) {
setup playerReference, push mediaItem, etc.
loadAds();
player.present();
}
AppDelegate.swift
let loadAds: @convention(block) () -\> Void = {
DispatchQueue.main.async {
let adManagerVC = ViewController()
AppDelegate.tvController?.navigationController.present(adManagerVC, animated: true)
}
}
let updateVideoPlayTime: @convention(block) (Double) -\> Void = { time in
CustomContentPlayhead.shared.currentTime = TimeInterval(time)
}
ViewController.swift
func adsManagerDidRequestContentPause(\_ adsManager: IMAAdsManager) {
showAdUI()
playerViewController.player?.pause()
}
func adsManagerDidRequestContentResume(\_ adsManager: IMAAdsManager) {
hideAdUI()
// Expecting JS video to resume via bridge
}
And yeah my IMSDK Implementation is working fine if I am using it with swift AVPlayer.
What I Need Help With:
- Best practice for coordinating video playback between JS (Player) and Swift (IMAAdsManager).
- How can I sync the playhead reliably between JS and Swift?
- Is there a better way to pause/resume TVJS player from Swift during ad lifecycle?
- How to reliably insert mid-roll ads when the playback is primarily controlled in JS?
Any insights, code examples, or recommended architecture improvements would be greatly appreciated!