為網路寄件者應用程式加入進階功能

廣告插播

網路傳送者 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,並為該 ID 指派專屬 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)。傳送 activeTracksId「不會」包含先前啟用的 trackId 停用文字音軌。

設定文字樣式

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 有所變更,系統就會通知所有已連線的寄件者,且目前媒體工作階段的對應屬性 (例如 MediaInfoactiveTrackIdstextTrackStyle) 會在回呼中傳送給傳送者。在這種情況下,接收器 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() 即可找到 sessionIdCastSession

建議做法:

  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();
  }
});

後續步驟

可以知道可新增至網站寄件者應用程式的功能。您現在可以為其他平台 (AndroidiOS) 建構傳送端應用程式,或是建構接收器應用程式