You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

ExoPlayer播放中替换/添加字幕的实现方法咨询

Dynamic Subtitle Updates in ExoPlayer (Playing Video)

Great question! Let's walk through how to handle adding or replacing subtitles for a video that's already playing in ExoPlayer—since the pre-player setup with MergingMediaSource doesn't cover this dynamic use case. First, let's clear up one key point: DynamicConcatenatingMediaSource isn't the right tool here. It's designed for stitching together a sequence of media items (like a playlist), not modifying the subtitle tracks of a single, currently playing video. Instead, we have two main approaches depending on your scenario:

1. Switching Built-In Subtitles (No MediaSource Rebuild Needed)

If your video already has embedded subtitle tracks, you don't need to touch the media source at all. ExoPlayer lets you switch between available tracks dynamically using TrackSelectionParameters:

// Get current track selection parameters
TrackSelectionParameters currentParams = player.getTrackSelectionParameters();

// Fetch all available subtitle track groups
TrackGroups subtitleTrackGroups = player.getCurrentTracks().getGroups(C.TRACK_TYPE_TEXT);

// Example: Select the second subtitle track (index 1) from the first group
TrackSelectionOverride subtitleOverride = TrackSelectionOverride.create(subtitleTrackGroups.get(0), 1);

// Build updated parameters
TrackSelectionParameters newParams = currentParams.buildUpon()
    .setTrackTypeDisabled(C.TRACK_TYPE_TEXT, false) // Ensure subtitles aren't disabled
    .setOverrideForType(subtitleOverride)
    .build();

// Apply the new selection (seamless switch during playback)
player.setTrackSelectionParameters(newParams);

This will instantly switch to the selected subtitle track without interrupting playback.

2. Adding/Replacing Custom User-Provided Subtitles

For adding a new subtitle file (from internal storage) or replacing existing ones, you'll need to rebuild your media source and update the player dynamically. Here's how to do it seamlessly:

Step 1: Create the Custom Subtitle MediaSource

First, build a SingleSampleMediaSource for the user's subtitle file:

// Assume you have a DataSourceFactory set up (e.g., DefaultDataSourceFactory)
SingleSampleMediaSource customSubtitleSource = new SingleSampleMediaSource.Factory(dataSourceFactory)
    .createMediaSource(
        MediaItem.fromUri(Uri.fromFile(userSubtitleFile)), // Path to user's subtitle file
        Format.createTextSampleFormat(
            null, // Let ExoPlayer auto-generate an ID
            MimeTypes.TEXT_VTT, // Adjust based on subtitle type: MimeTypes.APPLICATION_SUBRIP for SRT
            Format.NO_VALUE,
            null
        )
    );

Step 2: Rebuild the MergingMediaSource

Take your original video media source and merge it with the new subtitle source:

// Assume originalVideoSource is the MediaSource for your playing video
MergingMediaSource updatedMediaSource = new MergingMediaSource(originalVideoSource, customSubtitleSource);

Step 3: Update the Player Seamlessly

Tell the player to switch to the new media source while keeping playback state and position:

// Parameters: newMediaSource, keepPlaying, resetPosition
player.prepare(updatedMediaSource, true, false);
  • keepPlaying = true: The player resumes playback immediately after updating.
  • resetPosition = false: The player stays at the current playback position.

Alternative: Using MediaItem with Subtitle Configurations

If you're using MediaItem to load your video (instead of raw MediaSource), you can update the MediaItem directly with new subtitle configurations:

// Create a subtitle configuration for the user's file
MediaItem.SubtitleConfiguration subtitleConfig = new MediaItem.SubtitleConfiguration.Builder(Uri.fromFile(userSubtitleFile))
    .setMimeType(MimeTypes.TEXT_VTT)
    .setLanguage("en") // Set appropriate language code
    .setSelectionFlags(C.SELECTION_FLAG_DEFAULT) // Mark as default if needed
    .build();

// Update the existing MediaItem with the new subtitle
MediaItem updatedMediaItem = originalMediaItem.buildUpon()
    .addSubtitleConfiguration(subtitleConfig)
    // Use .clearSubtitleConfigurations() first if you want to replace all existing subtitles
    .build();

// Apply the updated MediaItem without resetting position
player.setMediaItem(updatedMediaItem, false);
player.prepare(false);

Key Notes

  • If you want to replace all existing subtitles (including built-in ones), use .clearSubtitleConfigurations() when updating the MediaItem, or exclude built-in tracks by only merging your custom subtitle source with the video.
  • Always ensure your DataSourceFactory has the necessary permissions to access the user's internal storage file.

内容的提问来源于stack exchange,提问作者Siju

火山引擎 最新活动