如何在Andoid exoplayer中播放原始NAL单元?

时间:2018-05-07 15:45:55

标签: java android c++ video h.264

我知道exoplayer支持RTSP,但是我需要c ++代码才能在很多操作系统上运行,所以我需要在传递给exoplayer之前用C ++解析RTP数据包到NAL单元

我找到了decode RTP packets using live555的方法并提取其NAL单位。根据{{​​3}}:

  

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

     

MediaSource,用于定义要播放的媒体,加载媒体以及可以从中读取加载的媒体。

     

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

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

ExoPlayer's documentation,我们可以看到已经有一些MediaSource可用。我虽然可能class reference for MediaSource可以工作但是没有完全描述它的作用,在构造函数中我必须提供UriSsManifest(什么)。

我可以看到这个库中存在SmoothStreaming MediaSource所以可能事情已经完成了一半

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

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

更新

我一直在研究这个图书馆是如何运作的。这一切都以NAL unit utility开头,其中包含MediaSourceExtractor等对象。似乎DataSourceMediaSource,您可以在其中提供自己的ExtractorDataSource

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

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

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

所以某种方式ExtractorDataSource读取,解析它并以通用格式发送给ExtractorMediaSource

我需要知道这种常见格式是如何解析我从自定义DataSource读取的NAL单元。

2 个答案:

答案 0 :(得分:1)

您无法使用ExoPlayer播放NAL单元或原始H.264流。
图片数据必须存在于supported container/format内。

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

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

作为第二个选项,对于Android,您可以使用MediaCodec解码从NAL单元中提取的H264。这是一个useful example source。只需使用:

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

通过Android自己的解码器研究其他source的功能,了解其工作原理。

其他起点:

答案 1 :(得分:0)

我做了非常相似的事情,您可以查看我的博客文章有关自定义ExoPlayer(https://medium.com/@mahmoud.mohamed.bahaa/diving-into-exoplayer-getting-more-control-over-the-framework-cac436d1472c)的某些方面