如何将字幕集成到Android ExoPlayer中

3

我正在使用Exoplayer播放不同类型的视频,我已经下载了这个演示并进行了操作

https://github.com/google/ExoPlayer

现在我需要为我的视频添加字幕,我正在使用ExoPlayer 2.9.5版本。

这是构建媒体源的方法。

private MediaSource buildMediaSource(Uri uri, @Nullable String overrideExtension) {
    @ContentType int type = Util.inferContentType(uri, overrideExtension);
    switch (type) {
      case C.TYPE_DASH:
        return new DashMediaSource.Factory(dataSourceFactory)
            .setManifestParser(
                new FilteringManifestParser<>(new DashManifestParser(), getOfflineStreamKeys(uri)))
            .createMediaSource(uri);
      case C.TYPE_SS:
        return new SsMediaSource.Factory(dataSourceFactory)
            .setManifestParser(
                new FilteringManifestParser<>(new SsManifestParser(), getOfflineStreamKeys(uri)))
            .createMediaSource(uri);
      case C.TYPE_HLS:
        return new HlsMediaSource.Factory(dataSourceFactory)
            .setPlaylistParserFactory(
                new DefaultHlsPlaylistParserFactory(getOfflineStreamKeys(uri)))
            .createMediaSource(uri);
      case C.TYPE_OTHER:
        return new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
      default: {
        throw new IllegalStateException("Unsupported type: " + type);
      }
    }
  }

我猜这个地方应该是需要修改的地方,以添加字幕到我的媒体文件,但我不知道如何操作?

此外,字幕将来自服务器,并且是.str格式。

有人能帮忙吗?

这是我的更新代码

private MediaSource buildMediaSourceWithSubtitle (Uri uri, @Nullable String overrideExtension, Uri subtitle) {

    Format subtitleFormat = Format.createTextSampleFormat(
            null, // An identifier for the track. May be null.
            MimeTypes.APPLICATION_SUBRIP, // The mime type. Must be set correctly.
            0, // Selection flags for the track.
            null); // The subtitle language. May be null.
    MediaSource subtitleSource =
            new SingleSampleMediaSource.Factory(dataSourceFactory)
        .createMediaSource(subtitle, subtitleFormat, C.TIME_UNSET);

    MediaSource mediaSource = null;

    @ContentType int type = Util.inferContentType(uri, overrideExtension);
    switch (type) {
      case C.TYPE_DASH:
        mediaSource = new DashMediaSource.Factory(dataSourceFactory)
                .setManifestParser(
                        new FilteringManifestParser<>(new DashManifestParser(), getOfflineStreamKeys(uri)))
                .createMediaSource(uri);

        return new MergingMediaSource(mediaSource, subtitleSource);

      case C.TYPE_SS:
        mediaSource = new SsMediaSource.Factory(dataSourceFactory)
                .setManifestParser(
                        new FilteringManifestParser<>(new SsManifestParser(), getOfflineStreamKeys(uri)))
                .createMediaSource(uri);
        return new MergingMediaSource(mediaSource, subtitleSource);

      case C.TYPE_HLS:
        mediaSource = new HlsMediaSource.Factory(dataSourceFactory)
                .setPlaylistParserFactory(
                        new DefaultHlsPlaylistParserFactory(getOfflineStreamKeys(uri)))
                .createMediaSource(uri);
        return new MergingMediaSource(mediaSource, subtitleSource);

      case C.TYPE_OTHER:
        mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
        return new MergingMediaSource(mediaSource, subtitleSource);
      default: {
        throw new IllegalStateException("Unsupported type: " + type);
      }
    }
  }

enter image description here


所以你没有找到这个链接:https://google.github.io/ExoPlayer/guide.html#side-loading-a-subtitle-file - Morrison Chang
你能播放 MKV 视频文件吗?如果可以的话,能否分享您的代码? - sanoj lawrence
3个回答

1

这实际上取决于你是侧载字幕还是它们已经嵌入到了你的流中。如果它们被嵌入到HLS、Dash或其他媒体源中,会检测到这些轨道,你需要选择文本轨道。请参见SimpleExoPlayer example

如果你正在侧载字幕,你需要使用SingleSampleMediaSourceMergingMediaSource。首先获取你的视频/音频源,然后从srt创建一个SingleSampleMediaSource并使用MergingMediaSourceExample将两者合并。完成后,像上面那样选择文本轨道。


1
请检查我的编辑,我已经按照您提供的示例进行了操作,但它没有起作用。 - Amira Elsayed Ismail
请查看截图 - Amira Elsayed Ismail
这是我的文件链接:https://github.com/amiraelsayed/cv/blob/master/subtitle.srt,它只是一个测试文件。 - Amira Elsayed Ismail

1
     public MediaSource getTextSource(Uri subTitle) {     //subTitle = Uri.parse(file.getAbsolutePath().toString());  file -- the local .srt file
    //todo C.SELECTION_FLAG_AUTOSELECT language MimeTypes
    Format textFormat = new Format.Builder()
            .setSampleMimeType(MimeTypes.APPLICATION_SUBRIP)
            .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
            .build();

    MediaItem.SubtitleConfiguration  subtitle = new MediaItem.SubtitleConfiguration.Builder(subTitle)
            .setMimeType(checkNotNull(textFormat.sampleMimeType))
            .setLanguage( textFormat.language)
            .setSelectionFlags(textFormat.selectionFlags).build();

    DefaultHttpDataSource.Factory  factory = new DefaultHttpDataSource.Factory()
            .setAllowCrossProtocolRedirects(true)
            .setConnectTimeoutMs(50000)
            .setReadTimeoutMs(50000)
            .setTransferListener( new DefaultBandwidthMeter.Builder(this).build());

    MediaSource textMediaSource = new SingleSampleMediaSource.Factory(new DefaultDataSource.Factory(this,
            factory))
            .createMediaSource(subtitle, C.TIME_UNSET);
    return textMediaSource;
}

然后在initplayer()中

concatenatingMediaSource = new ConcatenatingMediaSource();
 MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(videoUri));
MediaSource subtitleSource = getTextSource(subtitleUri);
MergingMediaSource mergingMediaSource = new MergingMediaSource(mediaSource, subtitleSource);
concatenatingMediaSource.addMediaSource(mergingMediaSource);
player.setMediaSource(concatenatingMediaSource);

0
使用以下代码在 Exoplayer 上启用字幕:
private void playWithCaption() {

        MediaItem.SubtitleConfiguration subtitle =
                new MediaItem.SubtitleConfiguration.Builder(subtitleUri)
                        .setMimeType(MimeTypes.APPLICATION_SUBRIP) // The correct MIME type (required).
                        .setLanguage("en") // MUST, The subtitle language (optional).
                        .setSelectionFlags(C.SELECTION_FLAG_DEFAULT) //MUST,  Selection flags for the track (optional).
                        .build();
        MediaItem mediaItem =
                new MediaItem.Builder()
                        .setUri(videoUri)
                        .setSubtitleConfigurations(ImmutableList.of(subtitle))
                        .build();

        player.setMediaItem(mediaItem);

        player.prepare();;


        player.setPlayWhenReady(true);

    }

请使用以下依赖项。
implementation "com.google.android.exoplayer:exoplayer:2.17.1"
implementation "com.google.android.exoplayer:exoplayer-core:2.17.1"
implementation "com.google.android.exoplayer:exoplayer-ui:2.17.1"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接