為 Web Sender 應用程式新增進階功能

廣告插播

Web Sender SDK 支援特定媒體串流中的廣告插播和隨播廣告。

如要進一步瞭解廣告插播的運作方式,請參閱網路接收器廣告插播總覽

雖然可以在傳送端和接收器上指定廣告插播,但還是建議您在網路接收器Android TV 接收器上指定廣告插播時間點,以便在不同平台間維持一致的行為。

在網站上使用 BreakClipBreak,在載入指令中指定廣告插播時間點:

let breakClip1 = new BreakClip('bc0');
breakClip1.title = 'Clip title'
breakClip1.posterUrl = 'https://www.some.url';
breakClip1.duration = 60;
breakClip.whenSKippable = 5;

let breakClip2 = ...
let breakClip3 = ...

let break1 = new Break('b0', ['bc0', 'bc1', 'bc2'], 10);

let mediaInfo = new chrome.cast.media.MediaInfo(<contentId>, '<contentType');
...
mediaInfo.breakClips = [breakClip1, breakClip2, breakClip3];
mediaInfo.breaks = [break1];

let request = new chrome.cast.media.LoadRequest(mediaInfo);

cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(request)

使用追蹤 API

音軌可以是文字 (字幕或字幕) 物件,或是音訊或影片串流物件。Tracks API 可讓您在應用程式中使用這些物件。

Track 物件代表 SDK 中的曲目。您可以設定測試群組,並為其指派專屬 ID,如下所示:

var englishSubtitle = new chrome.cast.media.Track(1, // track ID
  chrome.cast.media.TrackType.TEXT);
englishSubtitle.trackContentId = 'https://some-url/caption_en.vtt';
englishSubtitle.trackContentType = 'text/vtt';
englishSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
englishSubtitle.name = 'English Subtitles';
englishSubtitle.language = 'en-US';
englishSubtitle.customData = null;

var frenchSubtitle = new chrome.cast.media.Track(2, // track ID
  chrome.cast.media.TrackType.TEXT);
frenchSubtitle.trackContentId = 'https://some-url/caption_fr.vtt';
frenchSubtitle.trackContentType = 'text/vtt';
frenchSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
frenchSubtitle.name = 'French Subtitles';
frenchSubtitle.language = 'fr';
frenchSubtitle.customData = null;

var frenchAudio = new chrome.cast.media.Track(3, // track ID
  chrome.cast.media.TrackType.AUDIO);
frenchAudio.trackContentId = 'trk0001';
frenchAudio.trackContentType = 'audio/mp3';
frenchAudio.subtype = null;
frenchAudio.name = 'French Audio';
frenchAudio.language = 'fr';
frenchAudio.customData = null;

一個媒體項目可能有多個音軌;例如,媒體項目可以有多個字幕 (不同語言各自使用) 或多個替代音訊串流 (不同語言)。

MediaInfo 是建立媒體項目模型的類別。如要將 Track 物件集合與媒體項目建立關聯,您必須更新其 tracks 屬性。媒體載入至接收器之前,必須先建立關聯:

var tracks = [englishSubtitle, frenchSubtitle, frenchAudio];
var mediaInfo = new chrome.cast.media.MediaInfo(mediaURL);
mediaInfo.contentType = 'video/mp4';
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.customData = null;
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.duration = null;
mediaInfo.tracks = tracks;

您可以在媒體 activeTrackIds 要求中設定使用中的測試群組。

您也可以呼叫 EditTracksInfoRequest(opt_activeTrackIds, opt_textTrackStyle) 並傳遞要在 opt_activeTrackIds 中啟用的曲目 ID,以啟用與媒體項目相關聯的一或多個音軌。請注意,這兩個參數都是選用參數,您可以自行決定哪些是有效的音軌或樣式。以下舉例說明如何啟用法文字幕 (2) 和法文音訊 (3):

var activeTrackIds = [2, 3];
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(activeTrackIds);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

如要從目前媒體中移除所有音訊或視訊軌,只需設定 mediaInfo.tracks=null (空陣列),然後重新載入媒體即可。

如要從目前媒體中移除所有文字軌 (例如關閉字幕),請執行下列任一操作:

  • 更新 var activeTrackIds = [2, 3]; (如先前所示),僅包含 [3] 音軌。
  • 請設定 mediaInfo.tracks=null。請注意,無須重新載入媒體即可關閉文字說明文字 (track.hidden)。傳送「不含」先前啟用的 trackIdactiveTracksId 陣列會停用文字軌。

設定文字軌樣式

TextTrackStyle 是封裝文字軌樣式資訊的物件。建立或更新現有的 TextTrackStyle 物件後,您可以呼叫其 editTrackInfo 方法,將該物件套用至目前播放的媒體項目,如下所示:

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(textTrackStyle);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

您可以透過回呼追蹤要求的狀態 (成功或錯誤),並據此更新來源傳送者。

應用程式應允許使用者使用系統提供的設定或應用程式本身提供的設定,更新文字軌的樣式。

您可以為下列文字軌樣式元素設定樣式:

  • 前景 (文字) 顏色和透明度
  • 背景色彩和透明度
  • 邊緣類型
  • 邊緣顏色
  • 字型縮放
  • 字型系列
  • 字型樣式

例如,將文字顏色設為紅色、透明度 75%,如下所示:

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
textTrackStyle.foregroundColor = '#80FF0000';

音量控制

您可以使用 RemotePlayerRemotePlayerController 設定接收器音量。

function changeVolume(newVolume) {
  player.volumeLevel = newVolume;
  playerController.setVolumeLevel();
  // Update sender UI to reflect change
}

傳送者應用程式應遵循下列控制音量指南:

  • 傳送者應用程式必須與接收器保持同步,讓傳送端 UI 一律回報每個接收端的音量。請使用 RemotePlayerEventType.VOLUME_LEVEL_CHANGEDRemotePlayerEventType.IS_MUTED_CHANGED 回呼來維持傳送者的音量。詳情請參閱狀態更新
  • 傳送者應用程式不得以預先定義的特定音量設定音量,也不得在接收器上載入應用程式時,將音量設為傳送者裝置的鈴聲/媒體音量。

請參閱設計檢查清單中的寄件者音量控制項

傳送媒體訊息給接收器

Media Messages 可以從傳送方傳送給接收方。舉例來說,如要將 SKIP_AD 訊息傳送給接收器:

// Get a handle to the skip button element
const skipButton = document.getElementById('skip');
skipButton.addEventListener("click", function() {
  if (castSession) {
    const media = castSession.getMediaSession();
    castSession.sendMessage('urn:x-cast:com.google.cast.media', {
      type: 'SKIP_AD',
      requestId: 1,
      mediaSessionId: media.mediaSessionId
    });
  }
});

狀態更新

當多個寄件者連線至相同的接收器時,每個寄件者都必須瞭解接收方變更的情況,即使這類變更是由其他傳送者發起也一樣。

為此,應用程式應在 RemotePlayerController 上註冊所有必要的事件監聽器。如果目前媒體的 TextTrackStyle 有所變更,系統會通知所有已連結的傳送者,並通知目前媒體工作階段的對應屬性,例如 MediaInfo 欄位的 activeTrackIdstextTrackStyle,會傳送至回呼中的傳送者。在這種情況下,接收器 SDK 不會驗證新樣式是否與前一個樣式不同,無論新樣式是否與之前樣式不同,都會通知所有已連線的傳送者。

進度指標

大多數應用程式都需要在傳送端顯示進度指標的播放位置。Cast API 使用 Cast 媒體通訊協定,可針對此情況和其他情境的頻寬用量進行最佳化,因此您不必自行實作狀態同步處理作業。想瞭解如何使用 API 正確實作媒體播放的進度指標,請參閱 CastVideos-chrome 範例應用程式。

CORS 需求

針對自動調整媒體串流,Google Cast 需要 CORS 標頭,但即使是簡單的 mp4 媒體串流如果含有曲目,就需要使用 CORS。如要為任何媒體啟用測試群組,您必須為測試群組和媒體串流啟用 CORS。因此,如果伺服器上的簡易 mp4 媒體沒有 CORS 標頭,然後您新增簡單的字幕追蹤,除非您更新伺服器來加入適當的 CORS 標頭,否則將無法串流媒體。

您需要下列標頭:Content-TypeAccept-EncodingRange。 請注意,最後兩個標頭 (Accept-EncodingRange) 是您先前可能不需要的其他標頭。

萬用字元「*」無法用於 Access-Control-Allow-Origin 標頭。如果網頁含有受保護的媒體內容,則必須使用網域而不是萬用字元。

在不重新載入網頁的情況下恢復工作階段

如要繼續執行現有的 CastSession,請使用 requestSessionById(sessionId) 搭配要加入的工作階段的 sessionId

呼叫 loadMedia() 後,您可以使用 getSessionId() 在有效的 CastSession 上找到 sessionId

建議做法為:

  1. 呼叫 loadMedia() 來啟動工作階段
  2. sessionId 儲存在本機
  3. 如有需要,請使用 requestSessionById(sessionId) 重新加入工作階段
let sessionId;

function rejoinCastSession() {
  chrome.cast.requestSessionById(sessionId);

  // Add any business logic to load new content or only resume the session
}

document.getElementById('play-button').addEventListener(("click"), function() {
  if (sessionId == null) {
    let castSession = cast.framework.CastContext.getInstance().getCurrentSession();
    if (castSession) {
      let mediaInfo = createMediaInfo();
      let request = new chrome.cast.media.LoadRequest(mediaInfo);
      castSession.loadMedia(request)

      sessionId = CastSession.getSessionId();
    } else {
      console.log("Error: Attempting to play media without a Cast Session");
    }
  } else {
    rejoinCastSession();
  }
});

後續步驟

以上就是可新增至 Web Sender 應用程式的功能。您現在可以為其他平台 (AndroidiOS) 建構傳送者應用程式,或是建構接收端應用程式