首页 > 解决方案 > 如何在 Android exoplayer 中播放原始 NAL 单元?

问题描述

我知道 exoplayer 支持 RTSP,但我需要适用于许多操作系统的播放器的 C++ 代码,所以我需要在传递给 exoplayer 之前将 C++ 中的 RTP 数据包解析为 NAL 单元

我找到了一种使用 live555 解码 RTP 数据包并提取其 NAL 单元的方法。根据ExoPlayer 的文档

所有 ExoPlayer 实现的通用组件是:

一个 MediaSource,它定义要播放的媒体、加载媒体以及可以从中读取加载的媒体。

MediaSource 在播放开始时通过 ExoPlayer.prepare 注入。...

所以我需要一个MediaSource可以从我的 C++ 代码中提取 NAL 单元的自定义。

MediaSource 的类引用中,我们可以看到已经有一些MediaSources 可用。我虽然也许SmoothStreaming MediaSource可以工作,但没有描述它究竟做了什么,在它的构造函数中我必须提供一个Uri或一个SsManifest(什么)。

我可以看到这个库中有一个NAL 单元实用程序,所以也许事情已经完成了一半

那么如何构建或使用已经可用的 MediaSource 来读取 NAL 单元以供 ExoPlayer 播放呢?

另外,您如何将 NAL 单元从 C++ 传递到 Java?在代码中,我发现它只是将它们存储在 C++ 缓冲区中。我应该以某种方式在 Java 中读取这个缓冲区吗?

更新:

我一直在研究这个库是如何工作的。这一切都从一个MediaSource开始,它具有像ExtractorDataSource这样的对象。似乎ExtractorMediaSourceMediaSource您可以提供自己的ExtractorDataSource.

据我了解,DataSource是一个从任何可能的地方获取原始字节的类,无论是文件读取还是网络数据包。根据Extractor库中可用的类,例如Mp4Extractorand Mp3Extractor,anExtractor是可以解释从中读取的数据的东西DataSource。接口中的两个主要方法Extractor是:

void init(ExtractorOutput output)
int read(ExtractorInput input, PositionHolder seekPosition)

我不知道什么是什么ExtractorInputExtractorInput但它们看起来很重要。

那么以某种方式Extractor读取,解析它并以通用格式DataSource发送到渲染器?

我需要知道这种通用格式是怎样的,这样我就可以解析从自定义读取的 NAL 单元DataSource

标签: javaandroidc++videoh.264

解决方案


您不能使用 ExoPlayer 播放 NAL 单元或原始 H.264 流。
图片数据必须存在于受支持的容器/格式中。

不清楚你神秘的 C++ 代码在做什么,是NDK设置吗?它在Android解码中的作用是什么?您是说您无法将[从 C++ 函数]数据数组作为函数参数传递给某个 Android 函数吗?是这样的Java 到 C++设置吗?目前还不清楚你真正的问题是什么......

如果您坚持使用 Exoplayer,我可以告诉您 FLV 是(在容器列表中)可能是最佳选择的一个,因为它可以实时构建(重新混合)。您首先创建一个包含数据的 FLV 标头,SPS然后PPS是关键帧(从第一个 NAL 中提取的 H264 数据)。您必须熟悉 FLV 字节结构,但每个帧头大约为 13 个字节,后跟 NAL 数据,每帧重复直到结束。这将是实时转码。

作为第二个选项,对于 Android,您可以只使用MediaCodec从 NAL 单元中提取的 H264 进行解码。这是一个有用的示例源。只需用作:

MediaCodec.createDecoderByType("video/avc"); //then later give NAL units

研究这个其他来源的功能,以了解它如何通过 Android 自己的解码器工作。

其他起点:


推荐阅读