如何通过AndroidX Media3提取网络音频流的编码格式与比特率?
AndroidX Media3 获取音频编码格式与比特率问题解答
问题1:当前实现是否正确?返回-1是bug吗?
你的实现方向是对的,调用player.getAudioFormat()确实是Media3官方提供的获取当前播放音频格式的接口,但返回-1大概率不是bug,主要原因有两个:
- 媒体流本身未携带对应元数据:部分网络电台的音频流(尤其是低成本直播流)可能没有嵌入采样率、比特率这类元数据,播放器无法解析出有效值,就会返回-1。
- 元数据尚未完成解析:如果在播放器刚启动、还没完成媒体流加载/解析时调用
getAudioFormat(),此时相关字段还未被赋值,也会返回-1。
问题2:正确的实现方法
要稳定获取编码格式和比特率,需要结合播放器状态监听和轨道信息查询,具体步骤如下:
1. 监听音频格式变化事件
通过Player.Listener的onAudioFormatChanged回调获取格式信息,这个回调会在播放器成功解析到音频格式时触发,此时字段值是可靠的:
player.addListener(object : Player.Listener { override fun onAudioFormatChanged(audioFormat: AudioFormat) { // 获取编码格式 val mimeType = audioFormat.sampleMimeType // 处理未知值,Media3用C.RATE_UNKNOWN/C.BITRATE_UNKNOWN表示-1 val sampleRate = if (audioFormat.sampleRate != C.RATE_UNKNOWN) audioFormat.sampleRate else "未知" val bitrate = if (audioFormat.bitrate != C.BITRATE_UNKNOWN) "${audioFormat.bitrate / 1000} kbps" else "未知" // 更新UI显示 updateAudioInfoUi(mimeType, sampleRate, bitrate) } })
2. 针对HLS/自适应流的特殊处理
如果是HLS这类多码率自适应流,getAudioFormat()可能返回通用格式,具体轨道的比特率需要从当前选中的轨道中获取:
// 获取当前播放的音频轨道组 val currentTracks = player.currentTracks val audioTrackGroups = currentTracks.groups.filter { it.type == TrackType.AUDIO } if (audioTrackGroups.isNotEmpty()) { val selectedIndex = audioTrackGroups[0].selectedIndex if (selectedIndex != C.INDEX_UNSET) { val trackFormat = audioTrackGroups[0].getFormat(selectedIndex) val trackBitrate = if (trackFormat.bitrate != C.BITRATE_UNKNOWN) "${trackFormat.bitrate / 1000} kbps" else "未知" // 更新UI的比特率显示 } }
3. 结合媒体元数据补充信息
部分媒体流的比特率信息可能在MediaMetadata中,也可以通过回调获取:
override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) { val bitrate = mediaMetadata.extras?.getInt(MediaMetadata.EXTRA_BITRATE) bitrate?.let { val bitrateStr = "${it / 1000} kbps" // 更新UI } }
内容的提问来源于stack exchange,提问作者Mike Macpherson
相关产品推荐
相关产品推荐

