儲存及載入廣告串流書籤

選取平台: HTML5 Android iOS tvOS Roku

本指南說明使用隨選影片 (VOD) 串流的動態廣告插播 (DAI) 時,如何使用 IMA DAI SDK 導入書籤功能。這假設您已實作 IMA DAI,例如「開始使用」一文所述的實作方式。

什麼是書籤?

書籤功能可用來儲存內容串流中的特定位置,讓使用者稍後再回到該位置。假設使用者觀賞內容 5 分鐘後離開該視訊串流,之後再回頭繼續觀賞,這時書籤功能會儲存使用者在該串流中停止的位置,如此該串流就能從上次停止的地方繼續播放,方便觀眾順暢觀賞內容。

DAI 書籤功能的運作原理

為 DAI 串流加上書籤時,您必須記錄使用者離開影片時的串流 ID 和時間。使用者返回時,請重新要求串流,並搜尋儲存的時間。由於所要求串流的每個執行個體可能會有不同時長的廣告插播,因此單純儲存串流時間無法解決問題。你真正想做的是從相同的內容時間繼續觀看。

轉換方法來救援

IMA DAI SDK 提供一組方法,可針對指定串流時間請求內容時間,以及針對指定內容時間請求串流時間。使用這些轉換方法,您可以儲存已加入書籤的內容時間,然後在新的串流例項中,搜尋對應的串流時間。以下是相關做法,包括範例應用程式的連結,可顯示運作中的書籤實作方式。

正在儲存書籤

在活動暫停時儲存書籤。

Objective-C

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];
  [self.contentPlayer pause];
  // Ignore this if we're presenting a modal view (e.g. in-app clickthrough).
  if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) {
    // Don't save bookmark if we're playing a live stream.
    if (self.video.streamType != StreamTypeLive) {
      NSTimeInterval contentTime = [self.streamManager
          contentTimeForStreamTime:CMTimeGetSeconds(self.contentPlayer.currentTime)];
      [self.delegate videoViewController:self didReportSavedTime:contentTime forVideo:self.video];
    }

Swift

override func viewWillDisappear(_ animated: Bool) {
  super.viewWillDisappear(animated)
  contentPlayer.pause()
  if isMovingFromParent {
    // Only save bookmark if we're playing a VOD stream.
    if let vodStream = stream as? VODStream, let streamManager = streamManager {
      let contentTime = streamManager.contentTime(
        forStreamTime: contentPlayer.currentTime().seconds)
      if contentTime.isFinite, contentTime > 0 {
        delegate?.videoViewController(self, didReportBookmarkedTime: contentTime, for: vodStream)
      }
    }
    if trackingContent {
      removeContentPlayerObservers()
    }
    streamManager?.destroy()
    adsLoader?.contentComplete()
    streamManager = nil
    adsLoader = nil
  }
}

正在載入書籤

重新要求串流時載入書籤。這是實作 VideoStreamPlayer 介面的一部分。

Objective-C

case kIMAAdEvent_STREAM_LOADED: {
  if (self.video.streamType == StreamTypeVOD) {
    [self addContentPlayerObservers];
    if (self.video.savedTime > 0) {
      NSTimeInterval streamTime =
          [self.streamManager streamTimeForContentTime:self.video.savedTime];
      [self.IMAVideoDisplay seekStreamToTime:streamTime];
      self.video.savedTime = 0;
    }
  }

Swift

case .STREAM_LOADED:
  guard let stream else { return }
  addContentPlayerObservers()
  if let vodStream = stream as? VODStream, vodStream.bookmarkTime > 0 {
    bookmarkStreamTime = streamManager.streamTime(forContentTime: vodStream.bookmarkTime)
    if let time = bookmarkStreamTime {
      pendingBookmarkSeek = true
      logMessage(
        "STREAM_LOADED: Bookmark pending for contentTime: \(String(format: "%.2f", vodStream.bookmarkTime)) (streamTime: \(String(format: "%.2f", time)))"
      )
      vodStream.bookmarkTime = 0
    }
  }

範例應用程式

範例應用程式