ExoPlayer播放中替换/添加字幕的实现方法咨询
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 theMediaItem, or exclude built-in tracks by only merging your custom subtitle source with the video. - Always ensure your
DataSourceFactoryhas the necessary permissions to access the user's internal storage file.
内容的提问来源于stack exchange,提问作者Siju




