i am working on a project where i should play .srt files along with video in android. I was working through the samples of Exoplayer but cant able to play .srt files with vi
I just edit exoplayer example in there Player activity such like... and its working for me...
private void initializePlayer() {
Intent intent = getIntent();
if (player == null) {
boolean preferExtensionDecoders = intent.getBooleanExtra(PREFER_EXTENSION_DECODERS, false);
UUID drmSchemeUuid = intent.hasExtra(DRM_SCHEME_UUID_EXTRA)
? UUID.fromString(intent.getStringExtra(DRM_SCHEME_UUID_EXTRA)) : null;
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager = null;
if (drmSchemeUuid != null) {
String drmLicenseUrl = intent.getStringExtra(DRM_LICENSE_URL);
String[] keyRequestPropertiesArray = intent.getStringArrayExtra(DRM_KEY_REQUEST_PROPERTIES);
Map<String, String> keyRequestProperties;
if (keyRequestPropertiesArray == null || keyRequestPropertiesArray.length < 2) {
keyRequestProperties = null;
} else {
keyRequestProperties = new HashMap<>();
for (int i = 0; i < keyRequestPropertiesArray.length - 1; i += 2) {
keyRequestProperties.put(keyRequestPropertiesArray[i],
keyRequestPropertiesArray[i + 1]);
}
}
try {
drmSessionManager = buildDrmSessionManager(drmSchemeUuid, drmLicenseUrl,
keyRequestProperties);
} catch (UnsupportedDrmException e) {
int errorStringId = Util.SDK_INT < 18 ? R.string.error_drm_not_supported
: (e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown);
showToast(errorStringId);
return;
}
}
@SimpleExoPlayer.ExtensionRendererMode int extensionRendererMode =
((AppController) getApplication()).useExtensionRenderers()
? (preferExtensionDecoders ? SimpleExoPlayer.EXTENSION_RENDERER_MODE_PREFER
: SimpleExoPlayer.EXTENSION_RENDERER_MODE_ON)
: SimpleExoPlayer.EXTENSION_RENDERER_MODE_OFF;
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveVideoTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelectionHelper = new TrackSelectionHelper(trackSelector, videoTrackSelectionFactory);
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, new DefaultLoadControl(),
drmSessionManager, extensionRendererMode);
player.addListener(this);
eventLogger = new EventLogger(trackSelector);
player.addListener(eventLogger);
player.setAudioDebugListener(eventLogger);
player.setVideoDebugListener(eventLogger);
player.setMetadataOutput(eventLogger);
simpleExoPlayerView.setPlayer(player);
player.setPlayWhenReady(shouldAutoPlay);
debugViewHelper = new DebugTextViewHelper(player, debugTextView);
debugViewHelper.start();
playerNeedsSource = true;
}
if (playerNeedsSource) {
String action = intent.getAction();
Log.d("URL action: ", action);
Uri[] uris;
String[] extensions;
if (ACTION_VIEW.equals(action)) {
uris = new Uri[] {intent.getData()};
extensions = new String[] {intent.getStringExtra(EXTENSION_EXTRA)};
} else if (ACTION_VIEW_LIST.equals(action)) {
String[] uriStrings = intent.getStringArrayExtra(URI_LIST_EXTRA);
uris = new Uri[uriStrings.length];
for (int i = 0; i < uriStrings.length; i++) {
uris[i] = Uri.parse(uriStrings[i]);
Log.d("URL action2: ", String.valueOf(uris[i])+" ");
}
extensions = intent.getStringArrayExtra(EXTENSION_LIST_EXTRA);
if (extensions == null) {
extensions = new String[uriStrings.length];
}
} else {
showToast(getString(R.string.unexpected_intent_action, action));
return;
}
if (Util.maybeRequestReadExternalStoragePermission(this, uris)) {
// The player will be reinitialized if the permission is granted.
return;
}
MediaSource[] mediaSources = new MediaSource[uris.length];
for (int i = 0; i < uris.length; i++) {
mediaSources[i] = buildMediaSource(uris[i], extensions[i]);
Log.d("URL action extensions: ", String.valueOf( extensions[i]));
}
MediaSource mediaSource = mediaSources.length == 1 ? mediaSources[0]
: new ConcatenatingMediaSource(mediaSources);
boolean haveResumePosition = resumeWindow != C.INDEX_UNSET;
if (haveResumePosition) {
player.seekTo(resumeWindow, resumePosition);
}
// edit for subtitle
// player.prepare(mediaSource, !haveResumePosition, false);
// playerNeedsSource = false;
// player.seekTo(0);
//updateButtonVisibilities();
/* MediaSource mediaSource = new HlsMediaSource(Uri.parse("https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8"),
mediaDataSourceFactory, mainHandler, null);*/
Format textFormat = Format.createTextSampleFormat(null, MimeTypes.APPLICATION_SUBRIP,
null, Format.NO_VALUE, Format.NO_VALUE, "en", null);
Uri uri = Uri.parse("http://www.storiesinflight.com/js_videosub/jellies.srt");
MediaSource subtitleSource = new SingleSampleMediaSource(uri, mediaDataSourceFactory, textFormat, C.TIME_UNSET);
// Plays the video with the sideloaded subtitle.
MergingMediaSource mergedSource =
new MergingMediaSource(mediaSource, subtitleSource);
player.prepare(mergedSource,!haveResumePosition, false);
playerNeedsSource = false;
//player.seekTo(0);
}
}
I have given a lots of efforts for this and finally concluded to the solution...
Sharing here for the reference
Srt file format ref link - http://www.storiesinflight.com/js_videosub/jellies.srt
Solution which finds a way for me - https://github.com/google/ExoPlayer/issues/3869#issuecomment-367067013
Adding Exoplayer code here
// initialize exoplayer
private void initializeExoPlayer() {
if (player == null) {
video_view = (PlayerView) findViewById(R.id.video_view);
// 1. Create a default TrackSelector
LoadControl loadControl = new DefaultLoadControl(
new DefaultAllocator(true, 16),
VideoPlayerConfig.MIN_BUFFER_DURATION,
VideoPlayerConfig.MAX_BUFFER_DURATION,
VideoPlayerConfig.MIN_PLAYBACK_START_BUFFER,
VideoPlayerConfig.MIN_PLAYBACK_RESUME_BUFFER, -1, true);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector =
new DefaultTrackSelector(videoTrackSelectionFactory);
// 2. Create the player
player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(mContext), trackSelector, loadControl);
video_view.setPlayer(player);
}
}
public void buildMediaSource(String videoUrl, final String questionVideoThumbnail) {
Uri mUri = Uri.parse(videoUrl);
Uri srtUri = Uri.parse("http://www.storiesinflight.com/js_videosub/jellies.srt");
// Measures bandwidth during playback. Can be null if not required.
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
// Produces DataSource instances through which media data is loaded.
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(mContext,
Util.getUserAgent(mContext, getString(R.string.app_name)), bandwidthMeter);
// This is the MediaSource representing the media to be played.
MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(mUri);
// Prepare the player with the source.
Format textFormat = Format.createTextSampleFormat(null, MimeTypes.APPLICATION_SUBRIP,
null, Format.NO_VALUE, Format.NO_VALUE, "en", null, Format.OFFSET_SAMPLE_RELATIVE);
MediaSource textMediaSource = new SingleSampleMediaSource.Factory(dataSourceFactory)
.createMediaSource(srtUri, textFormat, C.TIME_UNSET);
MergingMediaSource mediaSource = new MergingMediaSource(videoSource, textMediaSource);
player.prepare(mediaSource);
player.setPlayWhenReady(true);
player.addListener(this);
}
PopupMenu popup = new PopupMenu(getContext(), v);
popup.getMenuInflater().inflate(R.menu.subtile_menu, popup.getMenu());
popup.setOnMenuItemClickListener(item -> {
if (item.getItemId()==R.id.remove_subtitle){
//player.prepare(videoSource);
player.prepare(videoSource, false, false);
}else if (item.getItemId()==R.id.english){
if (caption){
Format textFormat = Format.createTextSampleFormat(null, MimeTypes.APPLICATION_SUBRIP,
null, Format.NO_VALUE, Format.NO_VALUE, "en", null, Format.OFFSET_SAMPLE_RELATIVE);
MediaSource textMediaSource = new SingleSampleMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(sub_url), textFormat, C.TIME_UNSET);
MergingMediaSource mediaSource = new MergingMediaSource(videoSource, textMediaSource);
player.prepare(mediaSource, false, false);
}else {
Toast.makeText(getContext(), "Subtitle not available", Toast.LENGTH_SHORT).show();
}
}
return true;
});
popup.show();
SubtitleView subtitleView=(SubtitleView)findViewById(com.google.android.exoplayer2.R.id.exo_subtitles);
player.setTextOutput(new ComponentListener());
public class ComponentListener implements TextRenderer.Output{
@Override
public void onCues(List<Cue> cues) {
if (subtitleView != null) {
subtitleView.onCues(cues);
}
}
}
To show/hide the subtitleView:
subtitleView.setVisiblity(Visible/Gone);
I know it's too late to answer this question, but if someone else falls for it, try this :
public class MainActivity extends AppCompatActivity {
SimpleExoPlayerView exoPlayerView;
SimpleExoPlayer exoPlayer;
String videoURL = "http://blueappsoftware.in/layout_design_android_blog.mp4";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
exoPlayerView = (SimpleExoPlayerView) findViewById(R.id.exo_player_view);
try {
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelector trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory(bandwidthMeter));
exoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
Uri videoURI = Uri.parse(videoURL);
Uri subtitleUri=Uri.parse("https://firebasestorage.googleapis.com/v0/b/findandfix-2f4a9.appspot.com/o/Despacito%20Remix%20Luis%20Fonsi%20ft.Daddy%20Yankee%20Justin%20Bieber%20Lyrics%20%5BSpanish%5D.srt?alt=media&token=63344d04-af1c-4e2c-9d15-381bf7159308");
DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory("exoplayer_video");
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource mediaSource = new ExtractorMediaSource(videoURI, dataSourceFactory, extractorsFactory, null, null);
// Build the subtitle MediaSource.
Format subtitleFormat = Format.createTextSampleFormat(
null, // An identifier for the track. May be null.
MimeTypes.APPLICATION_SUBRIP, // The mime type. Must be set correctly.
null,
Format.NO_VALUE,
Format.NO_VALUE,
"en",
null); // The subtitle language. May be null.
MediaSource subtitleSource =new SingleSampleMediaSource(subtitleUri, dataSourceFactory, subtitleFormat, C.TIME_UNSET);
MergingMediaSource mergedSource =
new MergingMediaSource(mediaSource, subtitleSource);
exoPlayerView.setPlayer(exoPlayer);
exoPlayer.prepare(mergedSource);
exoPlayer.setPlayWhenReady(true);
}catch (Exception e){
Log.e("MainAcvtivity"," exoplayer error "+ e.toString());
}
}
}
Aside from the merged media source I created a Listener for the Text Rendered as an Interface as in the Demo
private final class ComponentListener implements TextRenderer.Output{
@Override
public void onCues(List<Cue> cues) {
if (subtitleView != null) {
subtitleView.onCues(cues);
}
}
}
player.setTextOutput(componentListener);
I created an object and set the TextOutput as this