Queueing

Overview

The Web Receiver SDK supports queueing with the default queue provided by the SDK using QueueData and QueueManager or using a custom queue by implementing cast.framework.QueueBase and using QueueManager for updates.

The Queueing API allows applications to better integrate with Cast by providing the following features:

  • Support of Google's and partner's cloud queue implementation so externally stored and created queue can be directly loaded into Cast devices.
  • Mechanisms that allows pagination of items in the queue rather than loading everything at once.
  • Support for new messaging such as going to the next item, the previous item, fetching a window of items, as well as getting media information related to a set of queue items.
  • The QueueManager to manage insertion, removal, and update of queue items.

Default queue

The Web Receiver SDK provides limited queue support out of the box in the form of a default queue.

To use the default queue, provide the queueData in the LoadRequestData of your sender-side loads or send a local load request using PlayerManager#load . Also see Loading media .

On the receiver-side, the queue can be modified using the QueueManager once the initial media has been loaded.

Custom queue

If the default queue does not provide the queueing functionality required for your app, the ability to create a custom queue is available, allowing for more capabilities and flexibility.

Application developers can create a Web Receiver side queue by implementing cast.framework.QueueBase .

Here is a basic example of a simple queue where the initialize call is overridden and then a list of queue items along with queue descriptions are provided to the Cast device.

Also see Loading media .

  // 
  
 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 this example, the list of items in the initialize call is provided in the provider's QueueBase constructor call. However, for a cloud queue implementation, the custom Web Receiver logic can fetch the items externally and then return them as part of the initialize call.

To demonstrate a more comprehensive use of the queueing API, here is a Demo queue that implements most of the QueueBase class.

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

In the example above, YourServer is your cloud queue server and has logic about how to fetch certain media items.

To use QueueBase -implemented queueing, one would set the queue option in the CastReceiverContext :

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

Managing a queue

The QueueManager gives developers flexibility in developing their queueing solutions by providing methods to access the currently stored list of queue items as well as the current playing item. It also provides operations such as insertion, removal, and update of queueing items. The following snippet shows how to access an instance of QueueManager :

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

Default queue management

Once the initial queue has been loaded, the QueueManager can be used to perform actions such as retrieving the current item, retrieving all items in the queue, and updating the items in the queue using insertItems , removeItems , and updateItems .

Custom queue management

Here is an example of a custom queue implementation that uses the insertion and removal methods based on some event. The example also demonstrates a usage of updateItems where the developers can modify the queue items in the existing queue, such as removing ad breaks.

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

Incoming and outgoing messages

To fully support receiver-side queue fetching as the source of truth, the following additional queueing messages are introduced and handled by the CAF Receiver SDK:

Incoming Message Parameters Outgoing Response Message Return
NEXT No parameter needed. MEDIA_STATUS Receiver will (fetch through nextItems() if necessary) and start playing the next item.
PREVIOUS No parameter needed. MEDIA_STATUS The Web Receiver will (fetch through prevItems() if necessary) and start playing the previous item.
FETCH_ITEMS FetchItemsRequestData QUEUE_CHANGE A cast.framework.messages.QueueChange. As an example, for an insert case, the items field in the JSON will contain the list of new items fetched.
GET_ITEMS_INFO GetItemsInfoRequestData containing itemIds: Array<number> ITEMS_INFO cast.framework.messages.ItemsInfo with queue item information.
GET_QUEUE_IDS No parameter needed. QUEUE_IDS cast.framework.messages.QueueIds.

For NEXT / PREVIOUS , if the existing queue representation on the Web Receiver does not have more items, the QueueBase.nextItems() or QueueBase.prevItems() is automatically invoked to receive more items.

For FETCH_ITEM , the corresponding function fetchItems in the QueueBase implementation is called for cloud queues, which retrieves the relevant data to be returned to the Web Receiver to store.

Whenever more items are fetched, a new message type QUEUE_CHANGE is triggered and sent back to the sender. See the various types of queue changes .

For GET_ITEMS_INFO , QueueBase 's implementation is not triggered and the Web Receiver returns media information already known to the list of ids.

Shuffling a queue

To set the items in your queue to be shuffled, set the shuffle flag of QueueData to true when loading your items into the queue.

If you are using an implementation of QueueBase , use the shuffle method to return a shuffled list of items.

To shuffle an existing queue, use the shuffle flag of the QUEUE_UPDATE MessageType , rather than the QUEUE_SHUFFLE command. See QueueUpdateRequestData for more information.

Repeat mode

To set the items in your queue to be repeated, set the repeatMode property of QueueData to the desired RepeatMode when loading your items into the queue.

To change the RepeatMode of an existing queue, use the repeatMode property of the QueueUpdateRequestData , which uses the QUEUE_UPDATE MessageType .

Create a Mobile Website
View Site in Mobile | Classic
Share by: