在 ExoPlayer 中,每个媒体片段都由一个 MediaItem 表示。不过,在内部,播放器需要 MediaSource 实例才能播放内容。播放器使用 MediaSource.Factory 根据媒体文件创建这些对象。
默认情况下,播放器使用 DefaultMediaSourceFactory,它可以创建以下内容 MediaSource 实现的实例:
DashMediaSource(适用于 DASH)。SsMediaSource(对于 SmoothStreaming)。HlsMediaSource(对于 HLS)。ProgressiveMediaSource,用于常规媒体文件。RtspMediaSource表示 RTSP。
DefaultMediaSourceFactory 还可以根据相应媒体文件的属性创建更复杂的媒体来源。媒体内容页面对此进行了更详细的介绍。
对于需要播放器的默认配置不支持的媒体来源设置的应用,有多种自定义选项。
自定义媒体源创建
构建播放器时,可以注入 MediaSource.Factory。例如,如果应用想要插入广告并使用 CacheDataSource.Factory 支持缓存,则可以配置 DefaultMediaSourceFactory 的实例来满足这些要求,并在播放器构建期间注入:
Kotlin
val mediaSourceFactory: MediaSource.Factory = DefaultMediaSourceFactory(context) .setDataSourceFactory(cacheDataSourceFactory) .setLocalAdInsertionComponents(adsLoaderProvider, playerView) val player = ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build()
Java
MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(context) .setDataSourceFactory(cacheDataSourceFactory) .setLocalAdInsertionComponents(adsLoaderProvider, /* adViewProvider= */ playerView); ExoPlayer player = new ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build();
DefaultMediaSourceFactory JavaDoc 更详细地介绍了可用选项。
还可以注入自定义 MediaSource.Factory 实现,例如支持创建自定义媒体来源类型。系统会调用工厂的 createMediaSource(MediaItem),为添加到播放列表中的每个媒体文件创建媒体来源。
基于媒体来源的播放列表 API
ExoPlayer 接口定义了其他播放列表方法,这些方法接受媒体来源,而不是媒体文件。这样就可以绕过播放器的内部 MediaSource.Factory,直接将媒体来源实例传递给播放器:
Kotlin
// Set a list of media sources as initial playlist. exoPlayer.setMediaSources(listOfMediaSources) // Add a single media source. exoPlayer.addMediaSource(anotherMediaSource) // Can be combined with the media item API. exoPlayer.addMediaItem(/* index= */ 3, MediaItem.fromUri(videoUri)) exoPlayer.prepare() exoPlayer.play()
Java
// Set a list of media sources as initial playlist. exoPlayer.setMediaSources(listOfMediaSources); // Add a single media source. exoPlayer.addMediaSource(anotherMediaSource); // Can be combined with the media item API. exoPlayer.addMediaItem(/* index= */ 3, MediaItem.fromUri(videoUri)); exoPlayer.prepare(); exoPlayer.play();
高级媒体来源组合
ExoPlayer 提供了多个 MediaSource 实现,用于修改和组合其他 MediaSource 实例。如果必须组合多项自定义设置,并且所有较简单的设置路径都不够用,则这些设置最有用。
ClippingMediaSource:允许将媒体剪辑到指定的时间戳范围。如果这是唯一的修改,最好改用MediaItem.ClippingConfiguration。FilteringMediaSource:将可用轨道过滤为指定类型,例如,仅公开同时包含音频和视频的文件中的视频轨道。如果这是唯一的修改,最好改用轨道选择参数。MergingMediaSource:合并多个媒体源以并行播放。在几乎所有情况下,建议在调用构造函数时将adjustPeriodTimeOffsets和clipDurations设置为 true,以确保所有来源同时开始和结束。如果进行此修改是为了添加旁加载字幕,最好改用MediaItem.SubtitleConfiguration。ConcatenatingMediaSource2:合并多个媒体源以连续播放。用户可见的媒体结构会公开单个Timeline.Window,这意味着它看起来像单个内容。如果进行此修改是为了播放多个不应看起来像单个内容的项,则最好改用 playlist API 方法(例如Player.addMediaItem)。SilenceMediaSource:生成指定时长的静音,这对于填补间隙非常有用。AdsMediaSource:通过客户端广告插播功能扩展媒体来源。如需了解详情,请参阅广告植入指南。ServerSideAdInsertionMediaSource:通过服务器端广告插播功能扩展媒体来源。如需了解详情,请参阅广告植入指南。