I have more than one video to play one by one. After Creating MediaSource of each video, All these are going to ConcatenatingMediaSource(mediaSources[]). Normally it play one by one. But when video is fast forward using seekTo(), 1st video is ok but other videos do not follow seekTo().
Suppose 1st video is 10s, 2nd 12s, 3rd 10s.
If I call seekTo((long)12*1000) it should play 2nd video with 2s forward. But it plays from the beginning of 2nd video.
Setting VideoSources
DefaultDataSourceFactory defaultDataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(),Util.getUserAgent(getApplicationContext(), "ExoPlayer"));
MediaSource mediaSource = new ExtractorMediaSource.Factory(defaultDataSourceFactory).createMediaSource(videoItem.getVideoUri());
videoItemArrayList.get(k).setVideoSource(mediaSource);
Concatenate Sources
MediaSource[] mediaSources = new MediaSource[videoItemArrayList.size()];
int j=0;
for(VideoItem item : videoItemArrayList){
mediaSources[j] = item.getVideoSource();
++j;
}
concatenatedSource = new ConcatenatingMediaSource(mediaSources);
Setup exoplayer
exoPlayer.prepare(concatenatedSource);
exoPlayer.seekTo(0);
exoPlayer.setPlayWhenReady(true);
exoPlayer.getPlaybackState();
Using exoplayer.seekTo(period) internally calls currentWindowIndex() internally of the source. While you are playing the first video in the concatenated mediasource you end up receiving windowIndex as 0. Use seekTo(windowIndex, time) to solve the issue.
Related
I want to show video by http data source. but when I set data source, exoplayer immediately start to buffer video, How can start buffering on user play click.
val dataSourceFactory = DefaultDataSourceFactory(context,Util.getUserAgent(context!!,"user_agent"))
player = SimpleExoPlayer.Builder(context!!).build()
playerView!!.player = player
val contentUrl = "my video url.mp4"
videoSource = ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(contentUrl))
player.prepare(videoSource)
P.S:
I try to change DefaultLoadControl to change buffering behavior but I cant find a workaround.
Thanks.
I am using FragmentStatePagerAdapter with Exoplayer. My main goal is to load the next page, however don't play the video in that page. Right now in my VideoFragment for the viewpager, I am playing the video inside
onCreateView
player = new SimpleExoPlayer.Builder(mContext).build();
player.setPlayWhenReady(true);
player.setRepeatMode(Player.REPEAT_MODE_ONE);
playerView.setPlayer(player);
addListenerToPlayer();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(mContext,
Util.getUserAgent(mContext, "yourApplicationName"));
Uri uri = Uri.parse(mUrl);
MediaSource videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
player.prepare(videoSource);
How do I setup my exoplayer and adapter so that it only plays the current screen?
Replace player.setPlayWhenReady(true); with player.setPlayWhenReady(false); in your initial configuration as this instructs the player instance to play the media as soon as it's ready to be played.
According to the docs on Player.STATE_READY:
The player is able to immediately play from its current position. The
player will be playing if getPlayWhenReady() is true, and paused
otherwise.
Moreover, you should setup either PageChangeListener or PageChangeCallback (depending on which version of ViewPager you're using) to monitor which page in the ViewPager is currently selected and which are not. For the selected page, you can set its corresponding exoplayer instance to play the video with player.setPlayWhenReady(true). It is also a good idea to pause the player in each of your fragment's onPause(...) lifecycle method.
How to play multiple URLs sequentially in android? I have a small streaming url 10s/each of one complete song. I need to play it one after another. Is there any way doing it so the music don't get lagged?
https://exoplayer.dev/media-sources.html read Advanced composition
MediaSource firstSource =
new ProgressiveMediaSource.Factory(...).createMediaSource(firstVideoUri);
MediaSource secondSource =
new ProgressiveMediaSource.Factory(...).createMediaSource(secondVideoUri);
// Plays the first video twice, then the second video.
ConcatenatingMediaSource concatenatedSource =
new ConcatenatingMediaSource(firstSource, firstSource, secondSource);
It looks like you are using the m3u8 playlist to play with MediaPlayer. However, you wouldn't able to do it. You can use ExoPlayer to play m3u8 list. Check this link
https://github.com/google/ExoPlayer
simpleExoPlayerView.setShowMultiWindowTimeBar(true);
I am using the following code to play a stream (which has both a video and an audio). But what if I want a video stream and a separate audio stream for the video stream at the same time synchronously? For example, suppose there are
https://someserver.com/video1/video.mp4
https://someserver.com/video1/audio.mp3
Both video.mp4 and audio.mp3 belong to video1 and have the same length, 1:23:34. Can I play video.mp4 and audio.mp3 synchronously as if they were one stream, with one ExoPlayer? The user must be able to pause/play/seek, and the same action should be applied to both streams.
If not, and I have to use two ExoPlayers, one for video and one for audio, how can I synchronise the audio and the video?
var uri = Uri.parse(url);
var df = DefaultHttpDataSourceFactory(url);
var ms = ExtractorMediaSource(uri, df, DefaultExtractorsFactory(), null, null);
exoPlayer.playWhenReady=true;
exoPlayer.prepare(ms);
You can! This is done in ExoPlayer by creating a MergingMediaSource. The example in the link merges a video source with a subtitle source but it's even easier for audio and video:
MediaSource videoSource = new ProgressiveMediaSource.Factory(...)
.createMediaSource(videoUri);
MediaSource audioSource = new ProgressiveMediaSource.Factory(...)
.createMediaSource(audioUri);
MergingMediaSource mergedSource = new MergingMediaSource(videoSource, audioSource);
I have a list of HLS urls that I need to play consecutively with exoplayer 2. This is not a problem:
val mediaSources = arrayOfNulls<MediaSource>(videoModel.Clips.size)
for (i in videoModel.Clips.indices) {
mediaSources[i] = buildVideoSource(videoModel.Clips.get(i).StreamUrl)
}
val videoSource = if (mediaSources.size == 1) mediaSources[0] else ConcatenatingMediaSource(*mediaSources)
The problem here is that I need to mute these videos, and play a mp3 audio track instead as background tune. How should I go about this? I thought I could just use a MergingMediaSource like this:
val audioSource = buildAudioSource()
val mergedSource = MergingMediaSource(videoSource, audioSource)
player!!.prepare(videoSource)
But that throws the following error: The merge failed because the sources have different period counts.
Source error:
com.google.android.exoplayer2.source.MergingMediaSource$IllegalMergeException
at com.google.android.exoplayer2.source.MergingMediaSource.checkTimelineMerges(MergingMediaSource.java:169)
at com.google.android.exoplayer2.source.MergingMediaSource.handleSourceInfoRefreshed(MergingMediaSource.java:144)
at com.google.android.exoplayer2.source.MergingMediaSource.access$000(MergingMediaSource.java:34)
at com.google.android.exoplayer2.source.MergingMediaSource$1.onSourceInfoRefreshed(MergingMediaSource.java:102)
at com.google.android.exoplayer2.source.ConcatenatingMediaSource.handleSourceInfoRefreshed(ConcatenatingMediaSource.java:142)
at com.google.android.exoplayer2.source.ConcatenatingMediaSource.access$000(ConcatenatingMediaSource.java:34)
at com.google.android.exoplayer2.source.ConcatenatingMediaSource$1.onSourceInfoRefreshed(ConcatenatingMediaSource.java:81)
at com.google.android.exoplayer2.source.hls.HlsMediaSource.onPrimaryPlaylistRefreshed(HlsMediaSource.java:142)
at com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker.onPlaylistUpdated(HlsPlaylistTracker.java:385)
at com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker.access$1200(HlsPlaylistTracker.java:41)
at com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker$MediaPlaylistBundle.processLoadedPlaylist(HlsPlaylistTracker.java:590)
at com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker$MediaPlaylistBundle.onLoadCompleted(HlsPlaylistTracker.java:539)
at com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker$MediaPlaylistBundle.onLoadCompleted(HlsPlaylistTracker.java:472)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.handleMessage(Loader.java:383)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
I have 2 questions:
How can I mute incoming HLS stream? I'd preferably not load the audio at all to save data usage.
How can I play a seperate audiotrack under a ConcatenatingMediaSource?
u can disable audio , in exo player Demo application, you can select audio button and choose disable.
you can see the demo code to see how disable the audio