Coda

Panoramica

L'SDK Ricevitore web supporta l'inserimento in coda con la coda predefinita fornita dall'SDK QueueData e QueueManager oppure utilizza una coda personalizzata implementando gli aggiornamenti cast.framework.QueueBase e QueueManager per gli aggiornamenti.

L'API Queueing consente alle applicazioni di integrarsi meglio con Google Cast fornendo le seguenti funzionalità:

  • Il supporto dell'implementazione delle code cloud di Google e dei suoi partner consente di caricare direttamente sui dispositivi di trasmissione le code archiviate e create esternamente.
  • Meccanismi che consentono l'impaginazione di elementi in coda anziché caricare tutto contemporaneamente.
  • Supporto di nuovi messaggi come il passaggio all'elemento successivo, l'elemento precedente, il recupero di una finestra di elementi e il recupero di informazioni multimediali relative a un insieme di elementi in coda.
  • La QueueManager per gestire l'inserimento, la rimozione e l'aggiornamento degli elementi in coda.

Coda predefinita

L'SDK del ricevitore web fornisce un supporto predefinito per le code sotto forma di coda predefinita.

Per utilizzare la coda predefinita, fornisci il valore queueData in LoadRequestData dei caricamenti lato mittente o invia una richiesta di caricamento locale utilizzando PlayerManager#load. Vedi anche Caricamento contenuti multimediali.

Sul lato destinatario, la coda può essere modificata utilizzando QueueManager dopo il caricamento del contenuto iniziale.

Coda personalizzata

Se la coda predefinita non fornisce la funzionalità di coda richiesta per l'app, è possibile creare una coda personalizzata che offre più funzionalità e flessibilità.

Gli sviluppatori di applicazioni possono creare una coda laterale del ricevitore web implementando cast.framework.QueueBase.

Di seguito è riportato un esempio di base di una semplice coda in cui la chiamata initialize viene sovrascritta e il dispositivo di trasmissione fornisce un elenco di elementi in coda insieme alle relative descrizioni.

Vedi anche Caricamento contenuti multimediali.

// Creates a simple queue with a combination of contents.
const DemoQueue = class extends cast.framework.QueueBase {
 constructor() {
   super();

   /**
    * List of media urls.
    * @private @const {!Array<string>}
    */
   this.myMediaUrls_ = [...];
 }
 /**
  * Provide a list of items.
  * @param {!cast.framework.messages.LoadRequestData} loadRequestData
  * @return {!cast.framework.messages.QueueData}
  */
 initialize(loadRequestData) {
   const items = [];
   for (const mediaUrl of this.myMediaUrls_) {
     const item = new cast.framework.messages.QueueItem();
     item.media = new cast.framework.messages.MediaInformation();
     item.media.contentId = mediaUrl;
     items.push(item);
   }
   let queueData = loadRequestData.queueData;
   // Create a new queue with media from the load request if one doesn't exist.
   if (!queueData) {
     queueData = new cast.framework.messages.QueueData();
     queueData.name = 'Your Queue Name';
     queueData.description = 'Your Queue Description';
     queueData.items = items;
     // Start with the first item in the playlist.
     queueData.startIndex = 0;
     // Start from 10 seconds into the first item.
     queueData.currentTime = 10;
   }
   return queueData;
 }
};

In questo esempio, l'elenco delle voci nella chiamata initialize viene fornito nella chiamata costruttore QueueBase del provider. Tuttavia, per un'implementazione della coda cloud, la logica personalizzata del ricevitore Web può recuperare gli elementi esternamente e restituirli come parte della chiamata di inizializzazione.

Per dimostrare l'utilizzo più completo dell'API di coda, ecco una coda demo che implementa la maggior parte della classe QueueBase.

const DemoQueue = class extends cast.framework.QueueBase {
 constructor() {
   /** @private {} */
   super();
   YourServer.onSomeEvent = this.updateEntireQueue_;
 }

 /**
  * Initializes the queue.
  * @param {!cast.framework.messages.LoadRequestData} loadRequestData
  * @return {!cast.framework.messages.QueueData}
  */
 initialize(loadRequestData) {
   let queueData = loadRequestData.queueData;
   // Create a new queue with media from the load request if one doesn't exist.
   if (!queueData) {
     queueData = new cast.framework.messages.QueueData();
     queueData.name = 'Your Queue Name';
     queueData.description = 'Your Queue Description';
     // Put the first set of items into the queue
     const items = this.nextItems();
     queueData.items = items;
     // Start with the first item in the playlist.
     queueData.startIndex = 0;
     // Start from 10 seconds into the first item.
     queueData.currentTime = 10;
   }
   return queueData;
 }

 /**
  * Picks a set of items from remote server after the reference item id and
  * return as the next items to be inserted into the queue. When
  * referenceItemId is omitted, items are simply appended to the end of the
  * queue.
  * @param {number} referenceItemId
  * @return {!Array<cast.framework.QueueItem>}
  */
 nextItems(referenceItemId) {
   // Assume your media has a itemId and the media url
   return this.constructQueueList_(YourServer.getNextMedias(referenceItemId));
 }

 /**
  * Picks a set of items from remote server before the reference item id and
  * return as the items to be inserted into the queue. When
  * referenceItemId is omitted, items are simply appended to beginning of the
  * queue.
  * @param {number} referenceItemId
  * @return {!Array<cast.framework.QueueItem>}
  */
 prevItems(referenceItemId) {
   return this.constructQueueList_(YourServer.getPrevMedias(referenceItemId));
 }

 /**
  * Constructs a list of QueueItems based on the media information containing
  * the item id and the media url.
  * @param {number} referenceItemId
  * @return {!Array<cast.framework.QueueItem>}
  */
 constructQueueList_(medias) {
   const items = [];
   for (media of medias) {
     const item = new cast.framework.messages.QueueItem(media.itemId);
     item.media = new cast.framework.messages.MediaInformation();
     item.media.contentId = media.url;
     items.push(item);
   }
   return items;
 }

 /**
  * Logs the currently playing item.
  * @param {number} itemId The unique id for the item.
  * @export
  */
 onCurrentItemIdChanged(itemId) {
   console.log('We are now playing video ' + itemId);
   YourServer.trackUsage(itemId);
 }
};

Nell'esempio precedente, YourServer è il server della coda cloud e include la logica su come recuperare determinati elementi multimediali.

Per utilizzare la coda QueueBase implementata, uno imposta l'opzione di coda in CastReceiverContext:

const context = cast.framework.CastReceiverContext.getInstance();
context.start({queue: new DemoQueue()});

Gestione di una coda

La QueueManager offre agli sviluppatori flessibilità nello sviluppo delle proprie soluzioni di coda, fornendo metodi per accedere all'elenco di elementi della coda attualmente memorizzati e all'elemento in riproduzione. Fornisce anche operazioni come inserimento, rimozione e aggiornamento di elementi in coda. Il seguente snippet mostra come accedere a un'istanza di QueueManager:

const context = cast.framework.CastReceiverContext.getInstance();
const queueManager = context.getPlayerManager().getQueueManager();

Gestione predefinita delle code

Una volta caricata la coda iniziale, è possibile utilizzare QueueManager per eseguire azioni quali il recupero dell'elemento corrente, il recupero di tutti gli elementi in coda e l'aggiornamento degli elementi in coda utilizzando insertItems, removeItems e updateItems.

Gestione personalizzata delle code

Di seguito è riportato un esempio di implementazione di una coda personalizzata che utilizza i metodi di inserimento e rimozione basati su qualche evento. L'esempio mostra anche l'utilizzo di updateItems in cui gli sviluppatori possono modificare gli elementi della coda nella coda esistente, ad esempio rimuovendo le interruzioni pubblicitarie.

const DemoQueue = class extends cast.framework.QueueBase {
  constructor() {
    super();

    /** @private @const {!cast.framework.QueueManager} */
    this.queueManager_ = context.getPlayerManager().getQueueManager();
  }

  /**
   * Provide a list of items.
   * @param {!cast.framework.messages.LoadRequestData} loadRequestData
   * @return {!cast.framework.messages.QueueData}
   */
  initialize(loadRequestData) {
    // Your normal initialization; see examples above.
    return queueData;
  }

  /** Inserts items to the queue. */
  onSomeEventTriggeringInsertionToQueue() {
    const twoMoreUrls = ['http://url1', 'http://url2'];
    const items = [];
    for (const mediaUrl of twoMoreUrls) {
      const item = new cast.framework.QueueItem();
      item.media = new cast.framework.messages.MediaInformation();
      item.media.contentId = mediaUrl;
      items.push(item);
    }
    // Insert two more items after the current playing item.
    const allItems = this.queueManager_.getItems();
    const currentItemIndex = this.queueManager_.getCurrentItemIndex();
    const nextItemIndex = currentItemIndex + 1;
    let insertBefore = undefined;
    if (currentItemIndex >= 0 &&
        currentItemIndex < allItems.length - 1) {
      insertBefore = allItems[nextItemIndex].itemId;
    }
    this.queueManager_.insertItems(items, insertBefore);
  }

  /** Removes a particular item from the queue. */
  onSomeEventTriggeringRemovalFromQueue() {
    this.queueManager_.removeItems([2]);
  }

  /** Removes all the ads from all the items across the entire queue. */
  onUserBoughtAdFreeVersion() {
    const items = this.queueManager_.getItems();
    this.queueManager_.updateItems(items.map(item => {
      item.media.breaks = undefined;
      return item;
    }));
  }
};

Messaggi in entrata e in uscita

Per supportare completamente il recupero della coda lato destinatario come fonte attendibile, i seguenti messaggi di coda aggiuntivi vengono introdotti e gestiti dall'SDK del destinatario CAF:

Messaggio in arrivo Parametri Messaggio risposta in uscita Invio
AVANTI Nessun parametro necessario. STATO_MEDIA Il destinatario cercherà di recuperare gli elementi successivi (se necessario) e avvierà la riproduzione dell'elemento successivo.
PRECEDENTE Nessun parametro necessario. STATO_MEDIA Il destinatario web (recupero tramite prevItem(), se necessario) e inizierà a riprodurre l'elemento precedente.
ELEMENTI_FETCH FetchItemRequestData MODIFICA_QUEUE Un elemento cast.framework.messages.QueueChange. Ad esempio, per un caso di inserimento, il campo items nel file JSON conterrà l'elenco dei nuovi elementi recuperati.
INFO_INFO_GET GetItemInfoRequestData con itemIds: Array<number> ELEMENTI_INFORMAZIONI cast.framework.messages.itemsInfo con informazioni sugli elementi della coda.
ID_GETE_QUEUE Nessun parametro necessario. ID_QUEUE cast.framework.messages.QueueIds.

Per NEXT/PREVIOUS, se la rappresentazione della coda esistente sul ricevitore web non ha altri elementi, QueueBase.nextItems() o QueueBase.prevItems() vengono richiamati automaticamente per ricevere altri elementi.

Per FETCH_ITEM, la funzione corrispondente fetchItems nell'implementazione di QueueBase viene chiamata per le code cloud, che recupera i dati pertinenti da restituire al Ricevitore web per archiviare.

Ogni volta che vengono recuperati altri elementi, viene attivato un nuovo tipo di messaggio QUEUE_CHANGE e inviato nuovamente al mittente. Visualizza i vari tipi di modifiche della coda.

Per GET_ITEMS_INFO, l'implementazione di QueueBase non viene attivata e il destinatario web restituisce le informazioni multimediali già note all'elenco di ID.

Riproduzione casuale di una coda

Per impostare la riproduzione casuale degli elementi in coda, imposta il flag shuffle di QueueData su true durante il caricamento degli elementi in coda.

Se utilizzi un'implementazione di QueueBase, utilizza il metodo shuffle per restituire un elenco casuale di elementi.

Per eseguire la riproduzione casuale di una coda esistente, utilizza il flag shuffle di QUEUE_UPDATE MessageType anziché il comando QUEUE_SHUFFLE. Per ulteriori informazioni, consulta la pagina QueueUpdateRequestData.

Modalità di ripetizione

Per impostare la ripetizione degli elementi in coda, imposta la proprietà repeatMode di QueueData sul valore desiderato RepeatMode durante il caricamento degli elementi in coda.

Per modificare il RepeatMode di una coda esistente, utilizza la proprietà repeatMode della QueueUpdateRequestData, che utilizza la QUEUE_UPDATE QUEUE_UPDATEMessageType.