Kolejkowanie

Omówienie

Web odbiornik SDK obsługuje kolejkę za pomocą kolejki domyślnej dostarczanej przez pakiet SDK za pomocą QueueData i QueueManager lub kolejki niestandardowej przez wdrożenie aktualizacji cast.framework.QueueBase i QueueManager.

Interfejs Queueing API umożliwia lepszą integrację aplikacji z Cast przez udostępnienie tych funkcji:

  • Obsługa implementacji kolejki Google w chmurze Google i partnera umożliwiającą ładowanie i tworzenie utworzonej kolejki zewnętrznej bezpośrednio na urządzeniach przesyłających.
  • Mechanizmy umożliwiające dzielenie elementów na strony w kolejce, zamiast wczytywać wszystko od razu.
  • Obsługa nowych wiadomości, takich jak przejście do następnego elementu, poprzedniego elementu, pobieranie okna elementów i pobieranie informacji multimedialnych związanych z zestawem elementów w kolejce.
  • QueueManager służy do zarządzania wstawianiem, usuwaniem i aktualizowaniem elementów w kolejce.

Domyślna kolejka

Pakiet SDK Web odbiornika udostępnia domyślnie ograniczoną kolejkę, która jest obsługiwana jako domyślna.

Aby użyć domyślnej kolejki, podaj obiekt queueData w LoadRequestData wczytywanych po stronie nadawcy lub wyślij żądanie wczytania lokalnego za pomocą PlayerManager#load. Przeczytaj też sekcję Wczytywanie multimediów.

Po stronie odbiorcy kolejkę można zmodyfikować za pomocą QueueManager po wczytaniu początkowego elementu multimedialnego.

Kolejka niestandardowa

Jeśli domyślna kolejka nie udostępnia funkcji kolejki wymaganej w Twojej aplikacji, możesz utworzyć kolejkę niestandardową, co zapewnia większe możliwości i elastyczność.

Deweloperzy aplikacji mogą utworzyć kolejkę po stronie odbiorcy przez wdrożenie cast.framework.QueueBase.

Oto prosty przykład prostej kolejki, w której wywołanie initialize zostało zastąpione, a na urządzeniu przesyłającym znajduje się lista elementów kolejki wraz z opisami kolejek.

Przeczytaj też sekcję Wczytywanie multimediów.

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

W tym przykładzie lista elementów w wywołaniu initialize jest podana w wywołaniu operatora QueueBase dostawcy. Jednak w przypadku implementacji kolejki w chmurze niestandardowa logika internetowa odbiorcy może pobierać elementy poza organizację, a następnie zwracać je w ramach inicjowania wywołania.

Aby zaprezentować bardziej kompleksowe wykorzystanie interfejsu API kolejki, skorzystaj z tej wersji demonstracyjnej, która implementuje większość klasy 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);
 }
};

W powyższym przykładzie YourServer jest serwerem kolejki w chmurze i zawiera logikę pobierania określonych elementów multimedialnych.

Aby użyć kolejki QueueBase, trzeba było ustawić opcję kolejki w CastReceiverContext:

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

Zarządzanie kolejką

QueueManager zapewnia deweloperom elastyczność w tworzeniu rozwiązań do kolejek, zapewniając metody dostępu do obecnie zapisanej listy elementów kolejki oraz aktualnie odtwarzanego elementu. Zapewnia ona też operacje, takie jak wstawianie, usuwanie i aktualizowanie elementów w kolejce. Ten fragment kodu zawiera informacje o tym, jak uzyskać dostęp do instancji QueueManager:

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

Domyślne funkcje zarządzania kolejkami

Po załadowaniu początkowej kolejki QueueManager można używać do takich działań jak pobieranie bieżącego elementu, pobieranie wszystkich elementów z kolejki oraz aktualizowanie ich w kolejkach za pomocą insertItems, removeItems i updateItems.

Zarządzanie niestandardowymi kolejkami

Oto przykład implementacji niestandardowej kolejki, która korzysta z metod wstawiania i usuwania na podstawie określonego zdarzenia. Ten przykład pokazuje też użycie elementu updateItems, w którym deweloperzy mogą modyfikować elementy kolejki w dotychczasowej kolejce, na przykład usuwając przerwy na reklamy.

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

Wiadomości przychodzące i wychodzące

Aby w pełni obsługiwać pobieranie kolejki po stronie odbiorcy jako źródło danych, wprowadziliśmy i obsługujemy następujące dodatkowe wiadomości w kolejce:

Wiadomość przychodząca Parametry Wiadomość wychodząca – odpowiedź Powrót
DALEJ Parametr nie jest wymagany. MEDIA_STATUS Odbiorca (w razie potrzeby pobierze element nextItems()) i rozpocznie odtwarzanie następnego elementu.
WSTECZ Parametr nie jest wymagany. MEDIA_STATUS Web odbiornik (w razie potrzeby pobierze parametr prevItems()) i zacznie odtwarzanie poprzedniego elementu.
PODLITYCZNE_ELEMENTY Pobierz dane żądań QUEUE_CHANGE A cast.framework.messages.QueueChange. Na przykład w przypadku przypadku wstawienia pole w pliku JSON będzie zawierać listę nowo pobranych elementów.
UZYSKAJ_INFORMACJE GetItemsInfoRequestData zawierające identyfikatory elementów: Array<number> ITEMS_INFO (INFORMACJE O ELEMENTACH) cast.framework.messages.ItemsInfo z informacjami o elementach kolejki.
IDENTYFIKATOR_POBIERZ Parametr nie jest wymagany. IDENTYFIKATORY_KOLEJKI cast.framework.messages.QueueIds.

Jeśli w NEXT/PREVIOUS obecna reprezentacja kolejki na odbiorniku WWW nie zawiera większej liczby elementów, automatycznie wywoływane jest narzędzie QueueBase.nextItems() lub QueueBase.prevItems(), aby pobrać więcej elementów.

W przypadku FETCH_ITEM odpowiednia funkcja fetchItems w implementacji QueueBase jest wywoływana dla kolejek w chmurze, która pobiera odpowiednie dane do zwrócenia do odbiornika internetowego.

Po każdym pobraniu kolejnych elementów uruchamiany jest nowy typ wiadomości QUEUE_CHANGE, który jest zwracany do nadawcy. Zobacz różne zmiany w kolejce.

W przypadku GET_ITEMS_INFO implementacja QueueBase nie jest wywoływana, a odbiornik odbiera informacje o multimediach znane już z listy identyfikatorów.

Losowe odtwarzanie kolejki

Aby ustawić kolejność elementów w kolejce, ustaw flagę shuffle na wartość QueueData na true podczas wczytywania elementów w kolejce.

Jeśli używasz implementacji obiektu QueueBase, użyj metody shuffle, aby zwrócić losową listę elementów.

Aby losowo odtwarzać istniejącą kolejkę, użyj flagi shuffle w elemencie QUEUE_UPDATEMessageType zamiast polecenia QUEUE_SHUFFLE. Więcej informacji znajdziesz na stronie QueueUpdateRequestData.

Tryb powtarzania

Aby ustawić powtarzanie elementów w kolejce, ustaw właściwość repeatMode właściwości QueueData na podczas wczytywania elementów w kolejce.

Aby zmienić RepeatMode istniejącej kolejki, użyj właściwości repeatMode z QueueUpdateRequestData, która korzysta z QUEUE_UPDATEMessageType.