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

廣告插播

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

如要進一步瞭解廣告插播的運作方式,請參閱「Web 接收端廣告插播總覽」。

雖然傳送端和接收端都可以指定廣告插播,但建議在網路接收端和 Android TV 接收端指定,以維持跨平台的一致行為。

在網頁上,使用 BreakClip 和 Break 在載入指令中指定廣告插播:

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)

使用 Tracks 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) 時,不需要重新載入媒體。傳送「不」包含先前啟用 trackId 的 activeTracksId 陣列,即可停用文字軌。

設定文字軌樣式

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';

音量控制項

您可以使用 RemotePlayer 和 RemotePlayerController 設定接收器音量。

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

控制音量時,傳送端應用程式應遵循下列規範:

  • 傳送端應用程式必須與接收端同步,這樣傳送端使用者介面才會一律根據接收端回報音量。使用 RemotePlayerEventType.VOLUME_LEVEL_CHANGED 和 RemotePlayerEventType.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 欄位的 activeTrackIds 和 textTrackStyle) 傳送至回呼中的傳送端。在這種情況下,接收端 SDK 不會驗證新樣式是否與舊樣式不同,而是會通知所有已連結的傳送端。

進度指標

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

CORS 規定

如果是自動調整媒體串流,Google Cast 需要 CORS 標頭,但即使是簡單的 MP4 媒體串流,只要包含音軌,也需要 CORS。如要為任何媒體啟用字幕軌,必須同時為字幕軌串流和媒體串流啟用 CORS。因此,如果伺服器上的簡易 MP4 媒體沒有可用的 CORS 標頭,而您新增了簡易字幕軌,則必須更新伺服器,加入適當的 CORS 標頭,才能串流媒體。

您需要下列標頭:Content-Type、Accept-Encoding 和 Range。請注意,最後兩個標頭 Accept-Encoding 和 Range 是額外標頭,您先前可能不需要。

萬用字元「*」無法用於 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();
  }
});

後續步驟

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