ExoPlayer 在 HLS 收到空播放列表后停止播放

问题描述 投票:0回答:1

我在 Android 应用程序中使用 ExoPlayer 通过 HLS 播放视频。有时,服务器在播放期间返回空播放列表(只有标题,没有曲目)。这种情况很少发生,随后的重新启动将返回更新的播放列表。我无法改变这种行为。

问题是ExoPlayer在收到空播放列表后停止播放视频并显示最后一帧的静态图像。其他播放器(例如iOS中的AvPlayer)没有这个问题,视频继续播放。

我尝试稍微调查一下这个问题。据我所知,在收到空播放列表之前,播放器首先请求 m3u8 文件,然后请求 ts 文件。并且这种情况会定期重复。但是,当播放器收到空播放列表时,对 ts 文件的请求就会消失,只发送播放列表更新的请求。 当我使用调试器进行查看时,我发现在收到空播放列表后,

onLoadCompleted
类中的
DefaultHlsPlaylistTracker
方法停止被调用。这似乎指出了问题的根源,但我不太明白。

如何让 ExoPlayer 忽略空播放列表?

更新:onPlaylistError 也会引发错误 HlsPlaylistTracker.PlaylistStuckException。但没有触发任何玩家回调。

android android-mediaplayer http-live-streaming exoplayer exoplayer2.x
1个回答
0
投票

您可以尝试实现自定义

HlsPlaylistTracker
,忽略空播放列表并重试获取,直到收到有效的播放列表。这意味着扩展
DefaultHlsPlaylistTracker
,并覆盖其播放列表解析行为。

首先,创建一个自定义

HlsPlaylistTracker

public class CustomHlsPlaylistTracker extends DefaultHlsPlaylistTracker {

    public CustomHlsPlaylistTracker(
        DataSource.Factory dataSourceFactory,
        LoadErrorHandlingPolicy loadErrorHandlingPolicy,
        HlsPlaylistParserFactory playlistParserFactory) {
        super(dataSourceFactory, loadErrorHandlingPolicy, playlistParserFactory);
    }

    @Override
    protected void onPlaylistUpdated(HlsUrl url, HlsMediaPlaylist newPlaylist) {
        if (newPlaylist.segments.isEmpty()) {
            // Detected an empty playlist, do not propagate this update.
            Log.w("CustomHlsPlaylistTracker", "Empty playlist detected, ignoring and retrying.");
            // Force a refresh
            refreshPlaylist(url);
        } else {
            // Propagate the update if the playlist is not empty.
            super.onPlaylistUpdated(url, newPlaylist);
        }
    }
}

然后,您需要在构建

ExoPlayer
实例时设置此自定义跟踪器:

DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, "yourApplicationName"));
LoadErrorHandlingPolicy loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy();
HlsPlaylistParserFactory playlistParserFactory = new DefaultHlsPlaylistParserFactory();

CustomHlsPlaylistTracker customHlsPlaylistTracker = new CustomHlsPlaylistTracker(dataSourceFactory, loadErrorHandlingPolicy, playlistParserFactory);

// Use the custom HlsPlaylistTracker when building the HlsMediaSource.
HlsMediaSource.Factory mediaSourceFactory = new HlsMediaSource.Factory(dataSourceFactory)
    .setPlaylistTracker(customHlsPlaylistTracker);
MediaSource mediaSource = mediaSourceFactory.createMediaSource(MediaItem.fromUri(hlsVideoUri));

player.setMediaSource(mediaSource);
player.prepare();
© www.soinside.com 2019 - 2024. All rights reserved.