How to re-add a mediasource after the exoplayer has been prepared? - android

I'm creating a playlist video player in exoplayer in android studio. I'm adding the first video extracted from a server and it is being played by the exoplayer perfectly. But when I add the second part, the exoplayer does not play that video. I want to add the second video after the exoplayer has been prepared. I want to know how to do that. Please Help me.
My MainActivity.java:
public class MainActivity extends AppCompatActivity
{
SimpleExoPlayer video_player;
PlayerView player_screen;
DefaultTrackSelector track_selector;
DefaultBandwidthMeter band_width_meter = new DefaultBandwidthMeter();
ArrayList<MediaSource> mediaSources_contents = new ArrayList<>();
ConcatenatingMediaSource concatenating_mediaSource_contents;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
player_screen = (PlayerView) findViewById(R.id.player_screen);
player_screen.requestFocus();
TrackSelection.Factory video_track_selection_factory = new AdaptiveTrackSelection.Factory(band_width_meter);
track_selector = new DefaultTrackSelector(video_track_selection_factory);
video_player = ExoPlayerFactory.newSimpleInstance(this, track_selector);
player_screen.setPlayer(video_player);
video_player.setPlayWhenReady(true);
Uri url1 = Uri.parse("THE - URL - OF - FIRST - VIDEO");
DataSource.Factory data_source_factory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "Application Name"), band_width_meter);
MediaSource source1 = new ExtractorMediaSource.Factory(data_source_factory).createMediaSource(url1);
mediaSources_contents.add(source1);
concatenating_mediaSource_contents = new ConcatenatingMediaSource(mediaSources_contents.toArray(new MediaSource[mediaSources_contents.size()]));
video_player.prepare(concatenating_mediaSource_contents);
// The lines below this point adds the second video to the media source. But it is not being played by the exoplayer.
Uri url2 = Uri.parse("THE - URL - OF - SECOND - VIDEO");
MediaSource source2 = new ExtractorMediaSource.Factory(data_source_factory).createMediaSource(url2);
mediaSources_contents.add(source2);
}
}

At Prepared Time
Initialize ConcatenatingMediaSource
ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource();
MediaSource firstSource = new ProgressiveMediaSource.Factory(new FileDataSourceFactory()).createMediaSource(Uri.parse(uri.get(0)));
MediaSource secondSource= new ProgressiveMediaSource.Factory(new FileDataSourceFactory()).createMediaSource(Uri.parse(uri.get(1)));
mediaSource.addMediaSources(firstSource);
mediaSource.addMediaSources(secondSource);
player.prepare(mediaSource, true, false);
After Prepare Add mediasource
MediaSource thirdSource= new ProgressiveMediaSource.Factory(new FileDataSourceFactory()).createMediaSource(Uri.parse(uri.get(3)));
mediaSource.addMediaSources(thirdSource);// mediaSource is refrance of ConcatenatingMediaSource

Try add this concatenating_mediaSource_contents.addMediaSource(source2); instead mediaSources_contents.add(source2);and for first media source also (not necessary, for better readability)

Related

Exoplayer can't play only audio for HLS

I have link only audio https://storage.googleapis.com/as-piepme/1465/livestream/1465.fef238cdc9d9eb0b958d4eb23080e28b/index.m3u8 but Exoplayer can't play above link,
it return "source error". But both IOS and Chrome run fine. My code:
SimpleExoPlayer player = new SimpleExoPlayer.Builder(context).build();
player.setMediaItem(MediaItem.fromUri(Uri.parse(linkPlay)));
player.prepare();
player.setPlayWhenReady(true);
Update my solution:
MediaItem mediaItem = new MediaItem.Builder()
.setUri(Uri.parse("https://storage.googleapis.com/as-piepme/1465/livestream/1465.fef238cdc9d9eb0b958d4eb23080e28b/index.m3u8"))
.build();
DefaultHlsExtractorFactory defaultHlsExtractorFactory = new DefaultHlsExtractorFactory(DefaultTsPayloadReaderFactory.FLAG_IGNORE_H264_STREAM, false);
MediaSource mediaSource = new HlsMediaSource.Factory(new DefaultHlsDataSourceFactory(new DefaultDataSourceFactory(context)))
.setExtractorFactory(defaultHlsExtractorFactory)
.setAllowChunklessPreparation(true)
.createMediaSource(mediaItem);
player.setMediaSource(mediaSource);
You need to use a Media source.
Try this sample code.
DataSource.Factory dataSourceFactory = new DefaultHttpDataSourceFactory();
// Create a HLS media source pointing to a playlist uri.
HlsMediaSource hlsMediaSource =
new HlsMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(hlsUri));
// Create a player instance.
SimpleExoPlayer player = new SimpleExoPlayer.Builder(context).build();
// Set the media source to be played.
player.setMediaSource(hlsMediaSource);
// Prepare the player.
player.prepare();
For more details check the documentation.
Update
Use this one.
DefaultTrackSelector trackSelector = new DefaultTrackSelector(this, new AdaptiveTrackSelection.Factory());
DefaultTrackSelector.Parameters trackSelectorParameters = trackSelector.buildUponParameters().setMaxAudioChannelCount(0).build();
trackSelector.setParameters(trackSelectorParameters);
RenderersFactory renderersFactory = new DefaultRenderersFactory(this);
SimpleExoPlayer audioPlayer = = new SimpleExoPlayer.Builder(this, renderersFactory).setTrackSelector(trackSelector).build();
HttpDataSource.Factory factory = new DefaultHttpDataSourceFactory("Online Audio Player", DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS, DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, true);
audioPlayer.setMediaSource(new ProgressiveMediaSource.Factory(factory).createMediaSource(MediaItem.fromUri("https://storage.googleapis.com/as-piepme/1465/livestream/1465.fef238cdc9d9eb0b958d4eb23080e28b/index.m3u8")));
audioPlayer.prepare();
audioPlayer.setPlayWhenReady(true);

Android ExoPlayer Can't Play HLS (HTTP Live Streaming)

I want to use ExoPlayer to play HLS (HTTP Live Streaming).
But I got the following error:
E/ExoPlayerImplInternal: Source error.
com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to https://my_url/file.m3u8
Below is my setup code:
private fun playTest() {
player = ExoPlayerFactory.newSimpleInstance(
DefaultRenderersFactory(this.requireContext()), DefaultTrackSelector(), DefaultLoadControl())
val uri = Uri.parse("https://my_url/file.m3u8")
ep_video_view.player = player
val dataSourceFactory = DefaultDataSourceFactory(this.requireContext(), "user-agent")
val mediaSource = HlsMediaSource(uri, dataSourceFactory, handler, null)
player?.prepare(mediaSource)
player?.playWhenReady = true
}
Thank you in advance.
in java
TrackSelection.Factory adaptiveTrackSelection = new AdaptiveTrackSelection.Factory(new DefaultBandwidthMeter());
player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(mContext),
new DefaultTrackSelector(adaptiveTrackSelection),
new DefaultLoadControl());
playerView.setPlayer(player);
DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(mContext,
Util.getUserAgent(mContext, "Exo2"), defaultBandwidthMeter);
String hls_url = "YOUR STREAMING URL HERE";
Uri uri = Uri.parse(hls_url);
Handler mainHandler = new Handler();
MediaSource mediaSource = new HlsMediaSource(uri,
dataSourceFactory, mainHandler, null);
player.prepare(mediaSource);
player.setPlayWhenReady(true);
https://medium.com/#haxzie/adaptive-hls-streaming-on-android-with-googles-exoplayer-64820017edf0
Total newbie here but hope it'll help. I've been doing the same thing as you and I noticed that unencrypted hls stream works. Try using a link with http. Just to check. I can't get Exoplayer to play https hls stream.

How to display video in full screen mode using ExoPlayer?

I am using Customised ExoPlayer to display videos in my project. I set some fixed height for ExoPlayer view let say 300dp the video is playing without any issues. But the problem is if I set the height of ExoPlayer view to match parent and change the screen orientation to landscape the video is playing but it keeps on buffering. The state of the video most of the time is reaming in the buffering state. Please help me to solve the issue and I am posting the code snippet of my data source below.
public void play(String url) {
defaultBandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory(defaultBandwidthMeter);
exoPlayer = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(VideoNewFullScreenMode.this),
new DefaultTrackSelector(trackSelectionFactory), new DefaultLoadControl());
MediaSource datasource = buildMediaStore(url);
exoPlayer.prepare(datasource, true, true);
simpleExoPlayer.setPlayer(exoPlayer);
exoPlayer.setPlayWhenReady(true);
simpleExoPlayer.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM);
exoPlayer.seekTo(getIntent().getLongExtra("position", 0));
//updateTimers();
exoPlayer.addListener(this);
}
private MediaSource buildMediaStore(String mediaUrl) {
Uri videoUri = Uri.parse(mediaUrl);
DataSource.Factory dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(this, getApplicationInfo().packageName), defaultBandwidthMeter);
DefaultExtractorsFactory extractorFactory = new DefaultExtractorsFactory();
return new ExtractorMediaSource(videoUri, dataSourceFactory, extractorFactory, null, null);
}

How to create a dialog with available qualities of DASH content in ExoPlayer?

I am using Exoplayer in my application and I want to show DashMediaSource.
I did it and the video will play this Code:
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "ExoPlayer"));
Uri uri = Uri.parse(videoUrl);
DashMediaSource dashMediaSource = new DashMediaSource(uri, dataSourceFactory,
new DefaultDashChunkSource.Factory(dataSourceFactory), null, null);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelector trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory(bandwidthMeter));
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
simpleExoPlayerView.setPlayer(player);
player.prepare(dashMediaSource);
But I need to show the user a selector for the quality of this vide0.
I just want to get all available qualities from my dash file and show it to the use.
In ExoPlayer 1.5.8, I used getTrackCount() to get all available qualities but in ExoPlayer 2.5.3 it is not available anymore.
How can I do that?
I really appreciate your help.
Have you tried using AnalyticsListener?
player.addAnalyticsListener(new AnalyticsListener() {
#Override
public void onBandwidthEstimate(EventTime eventTime, int totalLoadTimeMs, long totalBytesLoaded, long bitrateEstimate) {
}
});

Android Exoplayer 2 UDP Decoding issue

I'm new on ExoPlayer , i'm currently heading to use it to play Native Udp Stream ( From french digital Television : 1080p 5-10 mbps in Variable bitrate )
I manage to play some udp stream with some tests videos from http://jell.yfish.us/ on different devices .
I have make some different video decoding test with HLS and Udp Streaming with this code for UDP :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myactivity);
sufaceview = (SurfaceView) findViewById(R.id.surfaceView2);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector =
new DefaultTrackSelector(videoTrackSelectionFactory);
LoadControl loadControl = new DefaultLoadControl(
new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE),
15000, 60000, 2500, 6000);
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
Uri uri =
Uri.parse
("udp://#239.192.2.2:1234");
final DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "teveolauncher"), bandwidthMeterA);
extractorsFactory = new DefaultExtractorsFactory();
DataSource.Factory udsf = new UdpDataSource.Factory() {
#Override
public DataSource createDataSource() {
return new UdpDataSource(null, 3000, 100000);
}
};
ExtractorsFactory tsExtractorFactory = new ExtractorsFactory() {
#Override
public Extractor[] createExtractors() {
return new TsExtractor[]{new TsExtractor(MODE_SINGLE_PMT,
new TimestampAdjuster(0), new DefaultTsPayloadReaderFactory())};
}
};
MediaSource videoSource = new ExtractorMediaSource
(uri, udsf, tsExtractorFactory, null, null);
player.setVideoSurfaceView(sufaceview);
player.prepare(videoSource);
player.setPlayWhenReady(true);
}
For HLS I just Change the MediaSource and the datasourceFactory :
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "teveolauncher"), bandwidthMeterA);
MediaSource videoSource = new HlsMediaSource
(uri, dataSourceFactory, null, null);
I Know Udpstreaming is not officialy supported by ExoPlayer but the UdpDataSource class seems to work well.
After all the test , i noticed video with a variable biterate like french DTT can't be decoded correctly but with Constatnt biterate video like Jell yfish the decoding process is perfect .
There is some coding improvement to make VBR video decoded correctly ?
Thank you by advance :)
Sorry for my bad english :)
Uri uri = Uri.parse("udp://#239.192.2.2:1234");
I think UDP is not a protocol - it's a transport, (like TCP). You can't use a tcp://host:port/ URL either.
Or does it work?

Categories

Resources