You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Chromecast Sender更新元数据如何避免音频流重缓冲

问题场景
  • 已参照官方文档完成Chromecast Android Sender端媒体元数据投放功能,初始加载流程正常,可正确展示媒体标题、封面、正常播放流
  • 对接实时音频流场景时,需要不定期更新媒体元数据,要求更新过程不能触发音频流重新缓冲
  • 现有实现所有媒体相关操作都走load()流程,更新元数据时会导致流缓冲
现有问题代码
override fun loadMediaLoadRequestData(request: PlatformBridgeApis.MediaLoadRequestData?) 
    {
        if (request == null) return
        val remoteMediaClient: RemoteMediaClient = remoteMediaClient ?: return
        val mediaLoadRequest = getMediaLoadRequestData(request)
        remoteMediaClient.load(mediaLoadRequest)
    }

    fun getMediaLoadRequestData(request: PlatformBridgeApis.MediaLoadRequestData): MediaLoadRequestData {
        val mediaInfo = getMediaInfo(request.mediaInfo)

        return MediaLoadRequestData.Builder()
            .setMediaInfo(mediaInfo)
            .setAutoplay(request.shouldAutoplay)
            .setCurrentTime(request.currentTime)
            .build()
    }
    fun getMediaInfo(mediaInfo: PlatformBridgeApis.MediaInfo?): MediaInfo? {
        if (mediaInfo == null) return null

        val streamType = getStreamType(mediaInfo.streamType)
        val metadata = getMediaMetadata(mediaInfo.mediaMetadata)
        val mediaTracks = mediaInfo.mediaTracks.map { getMediaTrack(it) }
        val customData = JSONObject(mediaInfo.customDataAsJson ?: "{}")

        return MediaInfo.Builder(mediaInfo.contentId)
            .setStreamType(streamType)
            .setContentType(mediaInfo.contentType)
            .setMetadata(metadata)
            .setMediaTracks(mediaTracks)
            .setStreamDuration(mediaInfo.streamDuration)
            .setCustomData(customData)
            .build()
    }
问题根源

调用RemoteMediaClient.load()方法的语义是加载全新的媒体资源,只要触发该方法,接收器端就会重置当前播放状态、重新拉取媒体流,必然产生缓冲,无法满足同一条实时流更新元数据的需求。

实现方案
  1. 拆分「加载新流」和「更新现有流元数据」两个逻辑分支,同一条流的元数据更新不要走load()流程
  2. 元数据更新场景使用Cast SDK提供的专用API,直接更新当前播放媒体的元数据,不会触发流重载
  3. 在原有loadMediaLoadRequestData方法中增加判断:如果本次请求的内容ID和当前正在播放的内容ID一致,直接走元数据更新逻辑,否则走原有加载新流逻辑

修改后的完整代码如下:

override fun loadMediaLoadRequestData(request: PlatformBridgeApis.MediaLoadRequestData?) 
{
    if (request == null) return
    val remoteMediaClient: RemoteMediaClient = remoteMediaClient ?: return
    val targetContentId = request.mediaInfo?.contentId
    val currentPlayingContentId = remoteMediaClient.mediaInfo?.contentId

    // 同一条流的元数据更新,走无缓冲更新逻辑
    if (targetContentId != null && targetContentId == currentPlayingContentId) {
        val newMetadata = getMediaMetadata(request.mediaInfo?.mediaMetadata)
        val customData = JSONObject(request.mediaInfo?.customDataAsJson ?: "{}")
        // 调用SDK专用元数据更新接口,不会触发流重新加载/缓冲
        remoteMediaClient.setMediaMetadata(newMetadata, customData)
        return
    }

    // 不同流/首次加载,走原有load流程
    val mediaLoadRequest = getMediaLoadRequestData(request)
    remoteMediaClient.load(mediaLoadRequest)
}

// 以下原有工具方法无需修改
fun getMediaLoadRequestData(request: PlatformBridgeApis.MediaLoadRequestData): MediaLoadRequestData {
    val mediaInfo = getMediaInfo(request.mediaInfo)
    return MediaLoadRequestData.Builder()
        .setMediaInfo(mediaInfo)
        .setAutoplay(request.shouldAutoplay)
        .setCurrentTime(request.currentTime)
        .build()
}
fun getMediaInfo(mediaInfo: PlatformBridgeApis.MediaInfo?): MediaInfo? {
    if (mediaInfo == null) return null
    val streamType = getStreamType(mediaInfo.streamType)
    val metadata = getMediaMetadata(mediaInfo.mediaMetadata)
    val mediaTracks = mediaInfo.mediaTracks.map { getMediaTrack(it) }
    val customData = JSONObject(mediaInfo.customDataAsJson ?: "{}")

    return MediaInfo.Builder(mediaInfo.contentId)
        .setStreamType(streamType)
        .setContentType(mediaInfo.contentType)
        .setMetadata(metadata)
        .setMediaTracks(mediaTracks)
        .setStreamDuration(mediaInfo.streamDuration)
        .setCustomData(customData)
        .build()
}
注意事项
  • 官方提供的Default Media Receiver、Styled Media Receiver都原生支持该元数据更新逻辑,无适配成本;如果使用自定义接收器,需要确保收到元数据更新指令时仅刷新UI展示,不触发媒体源重新加载即可
  • 禁止在同流更新场景调用load()方法,即使传入的MediaInfo参数和当前完全一致,部分接收器实现仍会触发流重载,无法保证无缓冲效果
  • 如果需要同时更新媒体轨道、自定义数据、时长等其他非流地址字段,可以基于当前remoteMediaClient.mediaInfo构建新的MediaInfo实例,仅替换需要更新的字段,调用remoteMediaClient.updateMediaInfo()方法传入即可,同样不会触发流缓冲

内容的提问来源于stack exchange,提问作者bypass112

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:39:23