在 VideoView 中播放 'unsupported' 编解码器
Play 'unsupported' codec in VideoView
我有一个包含 audio/video 流的流。视频编码为 H.264 AVC,音频编码为 G.711 µ-law (PCMU)。 (我无法控制输出格式。)
当我尝试将视频显示到 VideoView
帧中时,设备提示无法播放视频。我想那是因为 Android 不支持上述音频编码。
有没有办法以某种方式在 VideoView
中显示选定的流?
- 我可以只使用 Java 代码片段来 'compute' 编解码器吗?我看过 class
android.net.rtp.AudioCodec
,其中包含一个字段 PCMU
,我可以想象 class 会有用。
- 或者我是否必须在我的应用程序中插入一个库或一些本机代码 (FFmpeg) 并使用它?如果是,如何?
如何解决?
如果您想在显示流之前对其进行操作,不幸的是,您将在 Android 设备上进入棘手的领域 - 如果您确实有可能在服务端进行转换,则很可能更容易(而且你通常也应该在服务器端有更多 'horsepower')。
假设您确实需要在服务器端进行转换,那么您可以使用的技术是将视频从服务器流式传输到您的应用程序,根据需要进行转换,然后从本地主机服务器 'stream'在您的应用中添加到 VideoView。大致步骤是:
- 像往常一样从服务器流式传输加密文件,'chunk by chunk'
- 在您的 Android 设备上,从流中读取并在收到时转换每个块
- 在您的 Android 设备上使用本地主机 http 服务器,现在 'serve' 将转换后的块传送到 MediaPlayer(媒体播放器应设置为使用 URL 指向您的本地主机 http 服务器)
我相信,这种方法的一个例子是 LibMedia: sure: http://libeasy.alwaysdata.net(注意,这不是免费图书馆,AFAIK)。
对于实际的转换,您可以按照您的建议使用 ffmpeg - 有许多用于 Android 项目的 ffmpeg 包装器,您可以使用或查看它们来设计自己的。一些例子:
如果您打算编写自己的包装器,请查看第二个 link 中有关 libffmpeginvoke 的注释。
需要注意的一件事是压缩技术,特别是视频压缩,通常使用一种方法,其中一个数据包或帧相对于它之前的帧(有时甚至是它之后的帧)被压缩。例如,第一帧可能是 'key frame',接下来的五帧可能只包含解释它们与关键帧有何不同的数据,而第七帧可能是另一个关键帧,依此类推。这意味着如果您要将块从一种格式转换为另一种格式,您通常需要一个 'chunk',它具有所有必需的关键帧。
我认为您在从 PCM 音频转换为 AAC 音频时不会遇到这个问题,但无论如何了解这个概念还是很有用的。
我有一个包含 audio/video 流的流。视频编码为 H.264 AVC,音频编码为 G.711 µ-law (PCMU)。 (我无法控制输出格式。)
当我尝试将视频显示到 VideoView
帧中时,设备提示无法播放视频。我想那是因为 Android 不支持上述音频编码。
有没有办法以某种方式在 VideoView
中显示选定的流?
- 我可以只使用 Java 代码片段来 'compute' 编解码器吗?我看过 class
android.net.rtp.AudioCodec
,其中包含一个字段PCMU
,我可以想象 class 会有用。 - 或者我是否必须在我的应用程序中插入一个库或一些本机代码 (FFmpeg) 并使用它?如果是,如何?
如何解决?
如果您想在显示流之前对其进行操作,不幸的是,您将在 Android 设备上进入棘手的领域 - 如果您确实有可能在服务端进行转换,则很可能更容易(而且你通常也应该在服务器端有更多 'horsepower')。
假设您确实需要在服务器端进行转换,那么您可以使用的技术是将视频从服务器流式传输到您的应用程序,根据需要进行转换,然后从本地主机服务器 'stream'在您的应用中添加到 VideoView。大致步骤是:
- 像往常一样从服务器流式传输加密文件,'chunk by chunk'
- 在您的 Android 设备上,从流中读取并在收到时转换每个块
- 在您的 Android 设备上使用本地主机 http 服务器,现在 'serve' 将转换后的块传送到 MediaPlayer(媒体播放器应设置为使用 URL 指向您的本地主机 http 服务器)
我相信,这种方法的一个例子是 LibMedia: sure: http://libeasy.alwaysdata.net(注意,这不是免费图书馆,AFAIK)。
对于实际的转换,您可以按照您的建议使用 ffmpeg - 有许多用于 Android 项目的 ffmpeg 包装器,您可以使用或查看它们来设计自己的。一些例子:
如果您打算编写自己的包装器,请查看第二个 link 中有关 libffmpeginvoke 的注释。
需要注意的一件事是压缩技术,特别是视频压缩,通常使用一种方法,其中一个数据包或帧相对于它之前的帧(有时甚至是它之后的帧)被压缩。例如,第一帧可能是 'key frame',接下来的五帧可能只包含解释它们与关键帧有何不同的数据,而第七帧可能是另一个关键帧,依此类推。这意味着如果您要将块从一种格式转换为另一种格式,您通常需要一个 'chunk',它具有所有必需的关键帧。
我认为您在从 PCM 音频转换为 AAC 音频时不会遇到这个问题,但无论如何了解这个概念还是很有用的。