如何使用 Android MediaPlayer 通过 http 流使 AAC 可搜索?

Posted

技术标签:

【中文标题】如何使用 Android MediaPlayer 通过 http 流使 AAC 可搜索?【英文标题】:How to make AAC seekable over http stream using Android MediaPlayer? 【发布时间】:2017-10-29 02:24:35 【问题描述】:

我有一个使用 MediaPlayer 的应用程序,当我流式传输渐进式下载 MP3 时它运行良好。我曾尝试使用同一个应用程序来流式传输进度下载 AAC 文件。它可以很好地播放文件。当我尝试使用带有 AAC 的 MediaPlayer.seekTo() 在流中跳过时,什么不起作用。这在 mp3 中也可以正常工作。对于 AAC 流,它只是从零开始重新播放。

我的感觉是与编码有关。该 AAC 文件未正确配置为流式传输。

这是 MediaInfo 工具的输出:

Size: 2.3 MB
Format: QuickTime/MPEG-4/Motion JPEG 2000 format
Stream count: 2
Duration: 00:05:02
Bit rate: 64 kb/s
Meta info:
    album_artist: Red Hot Chili Peppers
    album: The Getaway
    minor_version: 512
    encoder: Lavf57.41.100
    title: Dark Necessities
    major_brand: M4V 
    track: 2
    disc: 1
    compatible_brands: isomiso2avc1
    artist: Red Hot Chili Peppers
    copyright: 2016 Warner Bros. Records Inc.
    genre: Alternative

Stream 0
Type: video
Codec: h264
Codec profile: High 10
FourCC: avc1
Duration: 00:00:00
Width: 350
Height: 350
Sample aspect ratio: 1:1
Display aspect ratio: 1:1
Pixel format: yuv420p10le
Frame rate: 90000 fps
Meta info:
    handler_name: VideoHandler
    language: und

Stream 1
Type: audio
Codec: aac
FourCC: mp4a
Duration: 00:05:02
Bit rate: 64 kb/s
Sample rate: 44100 Hz
Sample format: s16
Channel: 2
Meta info:
    handler_name: SoundHandler
    language: und

您会注意到它实际上是一个带有 AAC 音频的视频文件,并且没有包含真实视频。如果是这种情况,那么我认为它需要更多元数据来知道当我请求可能加载或可能不加载的流的一部分时在哪里播放。此外,视频需要关键帧才能知道从哪里播放,所以我相信流/文件中不包含关键帧或“提示”框。

我没有找到任何关于丢失的真实细节或这是否可能的任何运气。我已经在其他版本上对此进行了测试,似乎在 5.0.2 之前它有效。在 5.0.2 之后它不起作用。我还没有找到有关该版本更改内容的任何详细信息。

因此,这可能是流编码问题,不允许我们通过渐进式下载 http(s) 流传输此文件。或者,它可能是在 5.0.2 时间范围内的某个时间创建的 android 媒体播放器中的错​​误。或者两者兼而有之。

为什么这不起作用?

【问题讨论】:

是否可以将输出作为原始 AAC(带有 ADTS 标头)而不是 M4A / MP4 中包含的音频流式传输? MP3 正在工作,因为您获得了 MP3 帧(每个帧都是几毫秒的声音),因此您只需跳过帧进行搜索。 AAC 也是框架(如果你不放在容器中)。我对 Android SDK 不太熟悉,但我确信您可以将帧字节发送到 SDK 解码器。我会调查一些选项。 我收到了关于 Android 播放器支持 ADTS 的混合消息,所以我不确定它是否有效。我期待听到您的发现。 你有样品流链接供检查吗? 这是复制的书面材料,所以我觉得我不应该在公共论坛上发布它。我可以私下提供访问权限。 在十六进制编辑器中打开文件... Word 搜索以下字符串:是否列出了 2 traks?其中一个在附近有soun?在soun 单词之后是否列出了任何stcostssstsz stts 原子(确保它们都在soun 区域内而不是vide 区域内)?如果它们存在,那么对于 MPEG 解码器应该足够了,所以不知道......你的文件扩展名是否以 .mp4.m4a .m4v.aac 结尾? 【参考方案1】:

试试Exoplayer,就是这么简单

ExoPlayer 与 Android 的内置 MediaPlayer 相比具有许多优势:

支持基于 HTTP 的动态自适应流 (DASH) 和 SmoothStreaming,MediaPlayer 都不支持这两者(它还支持 HTTP 实时流 (HLS)、MP4、MP3、WebM、M4A、MPEG-TS 和 AAC)。 支持高级 HLS 功能,例如正确处理 #EXT-X-DISCONTINUITY 标记。 能够自定义和扩展播放器以适合您的用例。 ExoPlayer 是专门为此设计的,它允许用自定义实现替换许多组件。 随您的应用程序一起轻松更新播放器。因为ExoPlayer 是一个包含在应用程序 apk 中的库,所以您可以控制使用的版本,并且可以在定期应用程序更新过程中轻松更新到较新的版本。

【讨论】:

那是另一种选择,但我对 Android SDK 中 AAC 流支持的答案非常感兴趣。我知道我可以撕掉我现有的代码并尝试用一些东西替换它,但是用你知道的魔鬼换你不知道的魔鬼并不能回答我关于流媒体的问题。 是的,它是流媒体的可选和替代解决方案。我很抱歉你的意图。

以上是关于如何使用 Android MediaPlayer 通过 http 流使 AAC 可搜索?的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中使用 MediaPlayer 播放音频文件

如何使用 Android 动画播放“滴答滴答”声音(可能使用“Android MediaPlayer / SoundPool”)?

如何仅使用 mediaplayer android 通过耳机播放音频

如何在android中静音MediaPlayer

Android -- MediaPlayer内部实现简析

Android 如何更改默认 VideoView / MediaPlayer 全屏?