Exoplayer - MKV 视频无法播放

Exoplayer - MKV Video is not playing

我已将 Exoplayer 集成到我的一个 Android 应用程序中,我可以用它播放所有类型的视频,但无法播放 .mkv 视频。对于我拥有的所有 URL,我得到 2 个不同的异常。

这是我使用的代码片段:

    private void initializePlayer() {

    TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
    mPlayerView.setPlayer(player);

    player.setPlayWhenReady(shouldAutoPlay);
    player.addAnalyticsListener(this);

    MediaSource mediaSource = buildMediaSource(Uri.parse(getIntent().getStringExtra(KEY_URL)));

    boolean haveStartPosition = currentWindow != C.INDEX_UNSET;
    if (haveStartPosition) {
        player.seekTo(currentWindow, playbackPosition);
    }

    player.seekTo(getResumePosition());
    Logger.d(TAG, "mResumePosition >> " + getResumePosition());
    player.prepare(mediaSource, !haveStartPosition, false);
    
}


    private MediaSource buildMediaSource(Uri uri) {

    String userAgent = Util.getUserAgent(this, getString(R.string.app_name));

    if (uri.getLastPathSegment().contains("mp3") || uri.getLastPathSegment().contains("mp4")) {
        return new ExtractorMediaSource.Factory(new DefaultHttpDataSourceFactory(userAgent))
                .createMediaSource(uri);
    } else if (uri.getLastPathSegment().contains("m3u8")) {
        return new HlsMediaSource.Factory(new DefaultHttpDataSourceFactory(userAgent))
                .createMediaSource(uri);
    } else if (uri.getLastPathSegment().contains("mpd")) {
        DashMediaSource mediaSource = new DashMediaSource.Factory(
                new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
                buildDataSourceFactory(true))
                .setManifestParser(
                        new FilteringManifestParser<>(
                                new DashManifestParser(), null))
                .createMediaSource(uri);
        return mediaSource;
    } else {
        DashChunkSource.Factory dashChunkSourceFactory = new DefaultDashChunkSource.Factory(
                new DefaultHttpDataSourceFactory("ua", new DefaultBandwidthMeter()));
        DataSource.Factory manifestDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent);
        return new DashMediaSource.Factory(dashChunkSourceFactory, manifestDataSourceFactory).
                createMediaSource(uri);
    }
}

视频 URL:http://tivixtv.net:80/movie/Qquzu5/MBGaYNMY4Q/75988.mkv

我得到异常:

2020-08-07 19:17:54.867 5721-6862/com.zeenews.tv E/ExoPlayerImplInternal: Source error
  com.google.android.exoplayer2.ParserException: org.xmlpull.v1.XmlPullParserException: Unexpected token (position:TEXT Eߣ������������#B��...@1:98 in java.io.InputStreamReader@5dd061d) 
    at com.google.android.exoplayer2.source.dash.manifest.DashManifestParser.parse(DashManifestParser.java:96)
    at com.google.android.exoplayer2.source.dash.manifest.DashManifestParser.parse(DashManifestParser.java:61)
    at com.google.android.exoplayer2.upstream.ParsingLoadable.load(ParsingLoadable.java:172)
    at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:415)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: org.xmlpull.v1.XmlPullParserException: Unexpected token (position:TEXT Eߣ������������#B��...@1:98 in java.io.InputStreamReader@5dd061d) 
    at org.kxml2.io.KXmlParser.next(KXmlParser.java:432)
    at org.kxml2.io.KXmlParser.next(KXmlParser.java:313)
    at com.google.android.exoplayer2.source.dash.manifest.DashManifestParser.parse(DashManifestParser.java:89)
    at com.google.android.exoplayer2.source.dash.manifest.DashManifestParser.parse(DashManifestParser.java:61) 
    at com.google.android.exoplayer2.upstream.ParsingLoadable.load(ParsingLoadable.java:172) 
    at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:415) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
    at java.lang.Thread.run(Thread.java:764) 

视频 URL:http://tivixtv.net:80/movie/Qquzu5/MBGaYNMY4Q/88512.mkv

我得到异常:

2020-08-07 19:51:54.515 7989-8627/com.zeenews.tv E/ExoPlayerImplInternal: Source error
  com.google.android.exoplayer2.ParserException: org.xmlpull.v1.XmlPullParserException: unterminated entity ref (position:TEXT @2:2937 in java.io.InputStreamReader@265ea06) 
    at com.google.android.exoplayer2.source.dash.manifest.DashManifestParser.parse(DashManifestParser.java:96)
    at com.google.android.exoplayer2.source.dash.manifest.DashManifestParser.parse(DashManifestParser.java:61)
    at com.google.android.exoplayer2.upstream.ParsingLoadable.load(ParsingLoadable.java:172)
    at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:415)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: org.xmlpull.v1.XmlPullParserException: unterminated entity ref (position:TEXT @2:2937 in java.io.InputStreamReader@265ea06) 
    at org.kxml2.io.KXmlParser.readEntity(KXmlParser.java:1220)
    at org.kxml2.io.KXmlParser.readValue(KXmlParser.java:1402)
    at org.kxml2.io.KXmlParser.next(KXmlParser.java:393)
    at org.kxml2.io.KxmlParser.next(KXmlParser.java:313)
    at com.google.android.exoplayer2.source.dash.manifest.DashManifestParser.parse(DashManifestParser.java:89)
    at com.google.android.exoplayer2.source.dash.manifest.DashManifestParser.parse(DashManifestParser.java:61) 
    at com.google.android.exoplayer2.upstream.ParsingLoadable.load(ParsingLoadable.java:172) 
    at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:415) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
    at java.lang.Thread.run(Thread.java:764) 

如果有人能帮助我,我将不胜感激。

我从 GitHub post:

那里得到了这个答案

https://github.com/google/ExoPlayer/issues/7725

我的代码试图使用 DashMediaSource 来播放 Matroska 文件,而它应该使用 ProgressiveMediaSource(或等效地,ExtractorMediaSource ,尽管 class 已被弃用)。

这是播放 .mkv 文件的更新 buildMediaSource() 代码:

    private MediaSource buildMediaSource(Uri uri) {

    String userAgent = Util.getUserAgent(this, getString(R.string.app_name));

    if (uri.getLastPathSegment().contains("mp3") || uri.getLastPathSegment().contains("mp4") || uri.getLastPathSegment().contains("mkv")) {
        return new ExtractorMediaSource.Factory(new DefaultHttpDataSourceFactory(userAgent))
                .createMediaSource(uri);
    } else if (uri.getLastPathSegment().contains("m3u8")) {
        return new HlsMediaSource.Factory(new DefaultHttpDataSourceFactory(userAgent))
                .createMediaSource(uri);
    } else if (uri.getLastPathSegment().contains("mpd")) {
        DashMediaSource mediaSource = new DashMediaSource.Factory(
                new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
                buildDataSourceFactory(true))
                .setManifestParser(
                        new FilteringManifestParser<>(
                                new DashManifestParser(), null))
                .createMediaSource(uri);
        return mediaSource;
    } else {
        DashChunkSource.Factory dashChunkSourceFactory = new DefaultDashChunkSource.Factory(
                new DefaultHttpDataSourceFactory("ua", new DefaultBandwidthMeter()));
        DataSource.Factory manifestDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent);
        return new DashMediaSource.Factory(dashChunkSourceFactory, manifestDataSourceFactory).
                createMediaSource(uri);
    }
}