Cast 框架提供了支持创建 MediaQueueItem
实例列表的队列类,这些列表可以通过 MediaInfo
实例(例如视频或音频流)构建,以便在接收器上按顺序播放。您可以修改、重新排序、更新这个内容项队列,等等。
只要队列中至少有一个当前处于活跃状态(正在播放或暂停)的项,接收器 SDK 就会维护该队列并响应对该队列执行的操作。发件人可以加入会话并向队列中添加内容。接收器会一直针对队列项保持会话,直到最后一个项目完成播放、发送方停止播放并终止会话,或者发送方在接收器上加载新队列。默认情况下,接收器不会保留有关已终止队列的任何信息。当队列中的最后一项完成时,媒体会话结束,队列将消失。
创建和加载媒体队列项
媒体队列项在 Cast 框架中表示为 MediaQueueItem
实例。
创建媒体队列项时,如果您使用包含自适应内容的媒体播放器库,您可以设置预加载时间,以便播放器可以在媒体队列项前面的项播放完毕之前开始缓冲媒体队列项。将该项的 autoplay 属性设为 true 即可让接收方自动播放该内容。例如,您可以使用构建器模式来创建媒体队列项,如下所示:
val queueItem: MediaQueueItem = MediaQueueItem.Builder(mediaInfo) .setAutoplay(true) .setPreloadTime(20.0) .build()
MediaQueueItem queueItem = new MediaQueueItem.Builder(mediaInfo) .setAutoplay(true) .setPreloadTime(20) .build();
使用 RemoteMediaClient
的相应 queueLoad
方法在队列中加载媒体队列项的数组。
接收媒体队列状态更新
当接收器加载媒体队列项时,它会为相应项分配一个唯一 ID,该 ID 在会话时长(及队列的生命周期)内持续有效。您的应用可以根据当前已加载(可能未在播放)、正在加载或预加载哪项项来了解队列的状态。MediaStatus
类提供以下状态信息:
getPreloadedItemId()
方法 - 如果已预加载下一项,则返回预加载项 ID。getLoadingItemId()
方法 - 返回接收器上当前正在加载(但在队列中无效)的项 ID。getCurrentItemId()
方法 - 返回媒体状态发生变化时队列中处于活动状态的项的 ID(可能未在播放)。getQueueItems()
(已废弃,请改用MediaQueue
)方法 - 以不可修改的列表的形式返回MediaQueueItem
实例的列表。
您的应用也可以使用 MediaQueue
类获取内容列表。该类是媒体队列的稀疏数据模型。它会将项 ID 列表保留在队列中,并自动与接收器同步。MediaQueue
不会保留所有 MediaQueueItem
,因为如果队列很长,会占用过多内存。而是按需提取内容,并保留最近访问内容的 LruCache
。您可以使用以下方法访问媒体队列:
getItemIds()
方法 - 按顺序返回所有项 ID 的列表。getItemAtIndex()
方法 - 返回指定索引处的缓存项。如果该项未缓存,MediaQueue
将返回null
并安排提取该项。提取项时,系统会调用MediaQueue.Callback#itemsUpdatedAtIndexes()
,然后再次使用同一 ID 调用getItemAtIndex()
将返回该项。- 当用户将队列界面滚动到顶部或底部,并且您的应用想要从云端提取更多项时,会使用
fetchMoteItemsRelativeToIndex()
。
将这些方法与其他媒体状态方法结合使用,可告知应用队列状态和队列中的项。除了来自接收器的媒体状态更新之外,您的应用还可以通过实现 RemoteMediaClient.Callback
和 MediaQueue.Callback
来监听队列的变化。
此外,Cast SDK 还提供两个实用程序类来创建用于排队的界面。
MediaQueueRecyclerViewAdapter
,用于支持RecyclerView
的数据MediaQueueListAdapter
,用于支持ListAdapter
的数据。
例如,如需使用 MediaQueueRecyclerViewAdapter
创建 RecyclerView
,请使用以下代码:
class MyRecyclerViewAdapter(mediaQueue: MediaQueue?) : MediaQueueRecyclerViewAdapter<MyViewHolder?>(mediaQueue) { override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val item = getItem(position) // Update the view using `item`. ... } } class MyViewHolder : RecyclerView.ViewHolder { // Implement your own ViewHolder. ... } fun someMethod() { val adapter = MyRecyclerViewAdapter( mCastSession.remoteMediaClient.getMediaQueue()) val recyclerView = activity.findViewById(R.id.my_recycler_view_id) as RecyclerView recyclerView.adapter = adapter }
public class MyRecyclerViewAdapter extends MediaQueueRecyclerViewAdapter<MyViewHolder> { public MyRecyclerViewAdapter(MediaQueue mediaQueue) { super(mediaQueue); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { MediaQueueItem item = getItem(position); // Update the view using `item`. ... } } public class MyViewHolder implements RecyclerView.ViewHolder { // Implement your own ViewHolder. ... } public void someMethod() { RecyclerView.Adapter adapter = new MyRecyclerViewAdapter( mCastSession.getRemoteMediaClient().getMediaQueue()); RecyclerView recyclerView = (RecyclerView) getActivity().findViewById(R.id.my_recycler_view_id); recyclerView.setAdapter(adapter); }
修改队列
如需对队列中的项执行操作,请使用 RemoteMediaClient
类的队列方法。通过这些操作,您可以将项目数组加载到新队列中、向现有队列插入项、更新队列中项的属性、在队列中让项向前或向后跳转、设置队列本身的属性(例如,更改用于选择下一项的 repeatMode
算法)、从队列中移除项以及对队列中的项重新排序。