0

在实现 Google 交互式媒体广告 (IMA) SDK 协议时,我的 mediaPlayer/audioManager(它是一个 AVPlayer 对象)在 adsManagerDidRequestContentPause 委托方法期间不会暂停。我的 mediaPlayer 符合 ObservableObject,这是我认为问题出在哪里,但我不是 100% 肯定的。

当我按下播放按钮时,我会播放音频并从我的 adsManager 类中请求广告。问题是预卷视频播放,但来自内容播放器的音频在预卷上播放。内容播放器的音频应该在预卷播放时暂停,并在结束后恢复。正如您将在代码中看到的,AudioManager 也是一个单例类。

这是用户按下播放时的代码。

@ObservedObject var manager = AudioManager.sharedInstance

func didTapPlayButton(){
    isPlaying.toggle()
    if isPlaying {
        audioManager.playLiveStream(with: pageInfo.tritonMount)
        adManager.requestAds()
    } else {
        audioManager.pause()
    }
}

这是带有 Google IMA 委托方法的 adManager 类。在每个委托方法设置断点后,我发现对 audioManager 的每次调用都被成功调用,但是,来自 audioManager 的音频实际上并没有暂停。

@ObservedObject var manager = AudioManager.sharedInstance

func setUpContentPlayer() {
    contentPlayhead = IMAAVPlayerContentPlayhead(avPlayer: player)
    // Create a player layer for the player.
    playerLayer = AVPlayerLayer(player: player)
    playerLayer!.frame = videoView.underlyingView.layer.bounds
    videoView.underlyingView.layer.addSublayer(playerLayer!)
}

func setUpAdsLoader() {
    adsLoader = IMAAdsLoader(settings: nil)
    adsLoader!.delegate = self
}

func requestAds() {
    // Create an ad display container for ad rendering.
    let adDisplayContainer = IMAAdDisplayContainer(adContainer: videoView.underlyingView, companionSlots: nil)

    // Create an ad request with our ad tag, display container, and optional user context.
    let request = IMAAdsRequest(
        adTagUrl: kLivePrerollVastTag,
        adDisplayContainer: adDisplayContainer,
        contentPlayhead: contentPlayhead,
        userContext: nil)

    adsLoader!.requestAds(with: request)
}

func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) {
    // Grab the instance of the IMAAdsManager and set ourselves as the delegate
    adsManager = adsLoadedData.adsManager
    adsManager!.delegate = self

    // Create ads rendering settings and tell the SDK to use the in-app browser.
    let adsRenderingSettings = IMAAdsRenderingSettings()

    adsRenderingSettings.webOpenerPresentingController = viewController

    // Initialize the ads manager.
    adsManager!.initialize(with: adsRenderingSettings)
}

//Ads Manager recieved ad request and is loading and starting ad
func adsManager(_ adsManager: IMAAdsManager!, didReceive event: IMAAdEvent!) {
    if (event.type == IMAAdEventType.LOADED) {
        // When the SDK notifies us that ads have been loaded, play them.
        adsManager.start()
    }
}

//Ads manager failed to receive ad request
func adsLoader(_ loader: IMAAdsLoader!, failedWith adErrorData: IMAAdLoadingErrorData!) {
    print("Error loading ads: \(String(describing: adErrorData.adError.message))")
    audioManager.resume()
}

func adsManager(_ adsManager: IMAAdsManager!, didReceive error: IMAAdError!) {
    // Something went wrong with the ads manager after ads were loaded. Log the
    // error and play the content.
    NSLog("AdsManager error: \(String(describing: error.message))")
    audioManager.resume()
}

/*Ads manager received request, initiated avplayer and is now
requesting player be paused in order or the Ads manager to play preroll*/
func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager!) {
    // The SDK is going to play ads, so pause the content.
    audioManager.pause()
}
/*Ads manager received request, played the preroll and is now
 requesting avplayer to resume live stream*/
func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager!) {
    // The SDK is done playing ads (at least for now), so resume the content.
    audioManager.resume()
}

音频管理器类:

    /// Upon setting this property any observers for 'currentItem' as well as any time observers will
/// be removed from the old value where applicable and added to the new value where applicable.
var player: AVPlayer? {
    didSet {
        oldValue?.removeObserver(self, forKeyPath: "currentItem", context: &AudioManager.ObserveAVPlayerCurrentItem)
        oldValue?.removeObserver(self, forKeyPath: "rate", context: &AudioManager.ObserveAVPlayerRate)
        guard let player = self.player else { return }

        player.addObserver(self, forKeyPath: "currentItem", options: [.initial, .new], context: &AudioManager.ObserveAVPlayerCurrentItem)
        player.addObserver(self, forKeyPath: "rate", options: [.initial, .new], context: &AudioManager.ObserveAVPlayerRate)
        player.automaticallyWaitsToMinimizeStalling = false
        if let tmpObs = timeObserver {
            print("Already have timeobserver, removing it")
            oldValue?.removeTimeObserver(tmpObs)
            timeObserver = nil
        }

        timeObserver = player.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1,preferredTimescale: 1),
            queue: nil,
            using: timeObserverCallback) as AnyObject?
    }

}
4

0 回答 0