Aggiungi funzionalità avanzate all'app Web Sender

Interruzioni pubblicitarie

L'SDK Web Sender fornisce supporto per le interruzioni pubblicitarie e gli annunci companion all'interno di un determinato stream multimediale.

Per saperne di più su come funzionano le interruzioni pubblicitarie, consulta la Panoramica delle interruzioni pubblicitarie di Web Receiver.

Anche se le interruzioni possono essere specificate sia sul mittente che sul destinatario, è consigliabile specificarle sul ricevitore web e sul ricevitore Android TV per mantenere un comportamento coerente su tutte le piattaforme.

Sul web, specifica le interruzioni pubblicitarie in un comando di caricamento utilizzando BreakClip e 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)

Utilizzo delle API delle tracce

Una traccia può essere un oggetto di testo (sottotitolo codificato o didascalia) oppure un oggetto di flusso audio o video. Le API Tracks ti consentono di lavorare con questi oggetti nella tua applicazione.

Un oggetto Track rappresenta una traccia nell'SDK. Puoi configurare una traccia e assegnarle un ID univoco in questo modo:

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;

Un elemento multimediale può avere più tracce; ad esempio, può avere più sottotitoli (ciascuno per una lingua diversa) o più flussi audio alternativi (per lingue diverse).

MediaInfo è la classe che modella un elemento multimediale. Per associare una raccolta di oggetti Track a un elemento multimediale, aggiorna la relativa proprietà tracks. Questa associazione deve essere effettuata prima che i contenuti multimediali vengano caricati sul ricevitore:

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;

Puoi impostare le tracce attive nella richiesta activeTrackIds multimediale.

Puoi anche attivare una o più tracce associate all'elemento multimediale dopo il caricamento dei contenuti multimediali chiamando EditTracksInfoRequest(opt_activeTrackIds, opt_textTrackStyle) e passando gli ID delle tracce da attivare in opt_activeTrackIds. Nota: entrambi i parametri sono facoltativi e puoi scegliere quali, tracce o stili attivi, impostare a tua discrezione. Ad esempio, ecco come attivare i sottotitoli in francese (2) e l'audio in francese (3):

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

Per rimuovere tutte le tracce audio o video dal file multimediale corrente, imposta mediaInfo.tracks=null (un array vuoto) e ricarica il file multimediale.

Per rimuovere tutte le tracce di testo dai contenuti multimediali correnti (ad esempio, disattivando i sottotitoli codificati), esegui una delle seguenti operazioni:

  • Aggiorna var activeTrackIds = [2, 3]; (mostrato in precedenza) in modo che includa solo [3], la traccia audio.
  • Imposta mediaInfo.tracks=null. Tieni presente che non è necessario ricaricare i contenuti multimediali per disattivare le didascalie codificate (track.hidden). L'invio di un array activeTracksId che non contiene un trackId precedentemente abilitato disattiva la traccia di testo.

Applicare uno stile alle tracce di testo

TextTrackStyle è l'oggetto che contiene le informazioni di stile di una traccia di testo. Dopo aver creato o aggiornato un oggetto TextTrackStyle esistente, puoi applicarlo all'elemento multimediale attualmente in riproduzione chiamando il relativo metodo editTrackInfo, ad esempio:

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

Puoi monitorare lo stato della richiesta con il risultato dei callback, ovvero esito positivo o errore, e aggiornare di conseguenza il mittente originale.

Le applicazioni devono consentire agli utenti di aggiornare lo stile delle tracce di testo utilizzando le impostazioni fornite dal sistema o dall'applicazione stessa.

Puoi applicare uno stile ai seguenti elementi dello stile delle tracce di testo:

  • Colore e opacità del primo piano (testo)
  • Colore dello sfondo e opacità
  • Tipo di bordo
  • Colore bordo
  • Scala del carattere
  • Famiglia di caratteri
  • Stile carattere

Ad esempio, imposta il colore del testo su rosso con un'opacità del 75% nel seguente modo:

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

Controllo del volume

Puoi utilizzare RemotePlayer e RemotePlayerController per impostare il volume del ricevitore.

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

L'app mittente deve rispettare le seguenti linee guida per il controllo del volume:

  • L'applicazione mittente deve sincronizzarsi con il ricevitore in modo che l'interfaccia utente del mittente riporti sempre il volume in base al ricevitore. Utilizza i callback RemotePlayerEventType.VOLUME_LEVEL_CHANGED e RemotePlayerEventType.IS_MUTED_CHANGED per mantenere il volume sul mittente. Per saperne di più, consulta Aggiornamenti di stato.
  • Le app mittenti non devono impostare il livello del volume a un livello specifico predefinito o impostare il livello del volume sul volume della suoneria/multimediale del dispositivo mittente quando l'app viene caricata sul ricevitore.

Consulta Controlli del volume del mittente nell'elenco di controllo per la progettazione.

Invio di messaggi multimediali al destinatario

Media Messages può essere inviato dal mittente al destinatario. Ad esempio, per inviare un messaggio SKIP_AD al destinatario:

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

Aggiornamenti di stato

Quando più mittenti sono collegati allo stesso destinatario, è importante che ogni mittente sia a conoscenza delle modifiche apportate al destinatario, anche se queste sono state avviate da altri mittenti.

A questo scopo, la tua applicazione deve registrare tutti i listener necessari su RemotePlayerController. Se il TextTrackStyle del media corrente cambia, tutti i mittenti connessi riceveranno una notifica e le proprietà corrispondenti della sessione media corrente, ad esempio activeTrackIds e textTrackStyle del campo MediaInfo verranno inviate ai mittenti nei callback. In questo caso, l'SDK del ricevitore non verifica se il nuovo stile è diverso da quello precedente e notifica comunque tutti i mittenti connessi.

Indicatore avanzamento

Mostrare la posizione di riproduzione con un indicatore di avanzamento sul mittente è un requisito per la maggior parte delle app. Le API Cast utilizzano il protocollo multimediale Cast, che ottimizza il consumo di larghezza di banda per questo e altri scenari, quindi non è necessario implementare la sincronizzazione dello stato. Per l'implementazione corretta di un indicatore di avanzamento per la riproduzione multimediale utilizzando le API, consulta l'app di esempio CastVideos-chrome.

Requisiti CORS

Per lo streaming multimediale adattivo, Google Cast richiede la presenza di intestazioni CORS, ma anche i semplici stream multimediali mp4 richiedono CORS se includono tracce. Se vuoi attivare le tracce per qualsiasi media, devi attivare CORS sia per gli stream delle tracce sia per gli stream dei media. Pertanto, se non hai intestazioni CORS disponibili per i tuoi semplici contenuti multimediali mp4 sul server e poi aggiungi una semplice traccia di sottotitoli codificati, non potrai riprodurre in streaming i tuoi contenuti multimediali a meno che non aggiorni il server in modo da includere le intestazioni CORS appropriate.

Sono necessarie le seguenti intestazioni: Content-Type,Accept-Encoding e Range. Tieni presente che le ultime due intestazioni, Accept-Encoding e Range, sono intestazioni aggiuntive che potresti non aver utilizzato in precedenza.

I caratteri jolly "*" non possono essere utilizzati per l'intestazione Access-Control-Allow-Origin. Se la pagina contiene contenuti multimediali protetti, deve utilizzare un dominio anziché un carattere jolly.

Ripresa di una sessione senza ricaricare la pagina web

Per riprendere un CastSession esistente, utilizza requestSessionById(sessionId) con l'sessionId della sessione a cui stai tentando di partecipare.

Il sessionId si trova sul CastSession attivo utilizzando getSessionId() dopo aver chiamato loadMedia().

L'approccio consigliato è:

  1. Chiama loadMedia() per iniziare la sessione
  2. Memorizzare sessionId localmente
  3. Rientra nella sessione utilizzando requestSessionById(sessionId) quando necessario
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();
  }
});

Passaggi successivi

Con questo si concludono le funzionalità che puoi aggiungere alla tua app mittente web. Ora puoi creare un'app mittente per un'altra piattaforma (Android o iOS) oppure creare un'app ricevitore.