自定义 ExoPlayer MediaSource——从哪里开始?

Custom ExoPlayer MediaSource -- where to start?

我正在使用 ExoPlayer 创建自定义媒体播放器(我之前就同一主题提出过几个问题,因为我对 Android 开发还很陌生,看起来我 运行我写的每一行代码都撞墙了)。

作为此自定义播放器的一部分,我想下载、解析和处理我们的业务生成的 XML 文件来定义我们的内容。此 XML 文件为网络 ID(一个 4-6 秒的视频广告内容所有者)提供了一个 URL,为内容提供了一个 URL,以及一个广告标签 URL 用于播放前置和中置广告。

我的目标是将此 XML 文件作为视频源传递给 prepare(),调用 setPlayWhenReady(true),然后让所有内容按预期播放(网络 ID、内容和广告)

要做到这一点,我认为我需要创建一个自定义 MediaSource——但是我找不到任何关于这样做的好的文档或教程。 The ExoPlayer documentation on MediaSources在这个案例中几乎没有用,只描述了如何利用ConcatenatingMediaSource、MergingMediaSource和LoopingMediaSource来自定义媒体播放。

更新

继续我自己的研究,我想要的可能可以通过自定义提取器来完成。当我将内容传递给 ExtractorMediaSource 时,我收到错误 com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (MatroskaExtractor, FragmentedMp4Extractor, Mp4Extractor, Mp3Extractor, AdtsExtractor, Ac3Extractor, TsExtractor, FlvExtractor, OggExtractor, PsExtractor, WavExtractor, AmrExtractor) could read the stream.。这让我想知道让 Extractor 解析 XML、提取内容并将数据传回是否更好。我还不确定这两个组件之间有什么区别或者哪个更合适,并且缺少文档。

Therefore the parsing of this XML file should be the responsibility of the video player, not of the client's app.

因此,您实质上是在尝试创建一个新模式来为底层播放器分发视频(无论是什么,都要处理)。这似乎是客户端逻辑。但是,你想要一个答案,所以我会试着给你一个。

首先,ExoPlayer 中的 Extractor 不应该用于解析您的 XML,根据文档:

Extracts media data from a container format.

这将用于从视频容器中提取视频数据,例如MP4.

在您的场景中,您可能希望查看类似于 DashManifestParser 的内容,后者使用 ParsingLoadable.Parser,其职责是解析您的输入模型。 ParsingLoadable.Parser 然后被 MediaSource 用来获取播放所需的信息。

但是,我不建议这样做。在这种情况下,对您来说最好的选择是创建一个 Parser 来获取内容 Url 并将其传递给底层播放器。您的内容 Url 将 link 放入 MP4 容器,也许是 DRM 内容等,但播放器可以很好地处理所有这些内容,而无需增加所有其他复杂性。

至于制作广告,可以通过多种方式完成:

  • 有一个播放器实例,在内容和广告之间切换。很简单,但是您需要跟踪位置信息,并且在切换时也会有缓冲。
  • 有一个播放器实例,但使用 ConcatenatingMediaSource,为此您将解析 xml 为内容和每个广告创建一个 MediaSource,然后将它们添加到 ConcatenatingMediaSource.
  • 只有一个玩家实例,但使用 ExoPlayer 提供的 AdsLoader。这是最好的解决方案,但遗憾的是缺少文档。为此,您可以提供一个 link 来加载广告,并提供一个单独的 link 来加载内容。

所以。总结一下。

  • 创建一个解析器,可以从 XML 中获取您需要的信息,即内容 link 和广告 links.
  • 创建一个播放器,为内容创建媒体源,然后为广告创建媒体源,将它们添加到串联媒体源。

如果您想了解如何执行某些方面的操作,我建议您查看我们在底层使用 Exo-Player 的开源库。我们最近甚至开始使用 AdsLoaderhttps://github.com/novoda/no-player