Enfileiramento

Visão geral

O SDK do receptor da Web oferece suporte à fila com a fila padrão fornecida pelo SDK usando QueueData e QueueManager ou usando uma fila personalizada implementando cast.framework.QueueBase e usando QueueManager para atualizações.

Com a API Queueing, os aplicativos se integram melhor ao Cast fornecendo os seguintes recursos:

  • Suporte à implementação de fila de nuvem do Google e do parceiro para que as filas criadas e armazenadas externamente possam ser carregadas diretamente em dispositivos de transmissão.
  • Mecanismos que permitem a paginação dos itens na fila em vez de carregar tudo de uma vez.
  • Suporte a novas mensagens, como ir para o próximo item, o item anterior, buscar uma janela de itens e receber informações de mídia relacionadas a um conjunto de itens da fila.
  • O QueueManager para gerenciar a inserção, a remoção e a atualização de itens da fila.

Fila padrão

O SDK do receptor da Web oferece suporte limitado à fila por padrão na forma de uma fila padrão.

Para usar a fila padrão, forneça o queueData no LoadRequestData dos carregamentos do lado do remetente ou envie uma solicitação de carregamento local usando PlayerManager#load. Consulte também Como carregar mídia.

No lado do receptor, a fila pode ser modificada usando o QueueManager após o carregamento da mídia inicial.

Fila personalizada

Se a fila padrão não fornecer a funcionalidade de enfileiramento necessária para{101}seu aplicativo, a capacidade de criar uma fila personalizada estará disponível, permitindo mais{101}recursos e flexibilidade.

Os desenvolvedores de aplicativos podem criar uma fila lateral de receptor da Web implementando cast.framework.QueueBase.

Confira um exemplo básico de uma fila simples em que a chamada initialize é substituída. Em seguida, uma lista de itens de fila com descrições é fornecida ao dispositivo de transmissão.

Consulte também Como carregar mídia.

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

Nesse exemplo, a lista de itens na chamada initialize é fornecida na chamada do construtor QueueBase do provedor. No entanto, para uma implementação de fila de nuvem, a lógica personalizada do receptor da Web pode buscar os itens externamente e depois retorná-los como parte da chamada de inicialização.

Para demonstrar um uso mais abrangente da API de fila, esta é uma fila de demonstração que implementa a maior parte da 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);
 }
};

No exemplo acima, YourServer é o servidor de filas na nuvem e tem lógica sobre como buscar determinados itens de mídia.

Para usar a fila implementada por QueueBase, defina a opção de fila em CastReceiverContext:

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

Como gerenciar uma fila

O QueueManager oferece aos desenvolvedores flexibilidade para desenvolver as soluções de filas, fornecendo métodos para acessar a lista de itens da fila atualmente armazenada e o item em reprodução. Ele também fornece operações como inserção, remoção e atualização de itens na fila. O snippet a seguir mostra como acessar uma instância de QueueManager:

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

Gerenciamento de filas padrão

Depois que a fila inicial tiver sido carregada, o QueueManager pode ser usado para executar ações como recuperar o item atual, recuperar todos os itens na fila e atualizar os itens na fila usando insertItems, removeItems e updateItems.

Gerenciamento personalizado de filas

Veja um exemplo de implementação de fila personalizada que usa os métodos de inserção e remoção com base em algum evento. O exemplo também demonstra o uso de updateItems em que os desenvolvedores podem modificar os itens da fila na fila existente, como remover intervalos de anúncios.

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

Mensagens recebidas e enviadas

Para oferecer suporte total à busca da fila do lado do receptor como fonte da verdade, as outras mensagens de fila em fila são introduzidas e processadas pelo SDK do receptor CAF:

Mensagem recebida Parâmetros Mensagem de resposta enviada Enter
PRÓXIMA Não é preciso usar parâmetros. MEDIA_STATUS (em inglês) O destinatário vai precisar buscar a função nextItems(), se necessário, e começar a tocar no próximo item.
ANTERIOR Não é preciso usar parâmetros. MEDIA_STATUS (em inglês) O receptor da Web (buscará por prevItems(), se necessário) e começará a reproduzir o item anterior.
FETCH_ITEMS. FetchItemsRequestData QUEUE_CHANGE. Um cast.framework.messages.QueueChange. Por exemplo, para um caso de inserção, o campo "items" no JSON conterá a lista de novos itens buscados.
GET_ITEMS_INFO GetItemsInfoRequestData contendo itemIds: Array<number> ITEMS_INFO. cast.framework.messages.ItemsInfo com informações do item da fila.
GET_QUEUE_IDS Não é preciso usar parâmetros. QUEUE_IDS (em inglês) cast.framework.messages.QueueIds.

Para NEXT/PREVIOUS, se a representação de fila existente no receptor da Web não tiver mais itens, o QueueBase.nextItems() ou QueueBase.prevItems() será invocado automaticamente para receber mais itens.

Para FETCH_ITEM, a função correspondente fetchItems na implementação de QueueBase é chamada para as filas de nuvem, que recuperam os dados relevantes a serem retornados para o receptor da Web para armazenar.

Sempre que mais itens são buscados, um novo tipo de mensagem QUEUE_CHANGE é acionado e enviado de volta ao remetente. Veja os vários tipos de mudanças de fila.

Para GET_ITEMS_INFO, a implementação de QueueBase não é acionada, e o receptor da Web retorna informações de mídia já conhecidas para a lista de IDs.

Embaralhamento de uma fila

Para definir os itens da fila em ordem aleatória, defina a sinalização shuffle de QueueData como true ao carregar os itens na fila.

Se você estiver usando uma implementação de QueueBase, use o método shuffle para retornar uma lista aleatória de itens.

Para embaralhar uma fila atual, use a sinalização shuffle do QUEUE_UPDATE MessageType, em vez do comando QUEUE_SHUFFLE. Consulte QueueUpdateRequestData se quiser mais informações.

Modo de repetição

Para definir que os itens na fila sejam repetidos, defina a propriedade repeatMode de QueueData como o RepeatMode desejado ao carregar os itens na fila.

Para alterar o RepeatMode de uma fila atual, use a propriedade repeatMode do QueueUpdateRequestData, que usa o QUEUE_UPDATE MessageType.