I am Very Beginner in Exoplayer with IMA, I am creating Video player with Exoplayer and IMA extension. I Created Exoplayer using https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side
Its Play ads only one time. But I want to play Linear Inline ads every 5 mins. I tried How to show ads at specific points using ExoPlayer's IMA extension?
Uri adTagUri = Uri.parse(getString(R.string.ad_tag_url));
AdPlaybackState adPlaybackState = new AdPlaybackState(0, 300 * C.MICROS_PER_SECOND);
// add the uri of the first ad of the first ad group
adPlaybackState = adPlaybackState.withAdUri(0, 0, adTagUri);
// add the uri of the first ad of the second ad group
adPlaybackState = adPlaybackState.withAdUri(1, 0, adTagUri);
// add the uri of the second ad of the second ad group
adPlaybackState = adPlaybackState.withAdUri(1, 1, adTagUri);
Got error in eventListener.onAdPlaybackState(adPlaybackState);
My Lib implementation 'com.google.android.exoplayer:extension-ima:2.11.1'
MyCode
MainActivity.java
private PlayerView playerView;
private SimpleExoPlayer player;
private ImaAdsLoader adsLoader;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerView = findViewById(R.id.player_view);
adsLoader = new ImaAdsLoader(this, Uri.parse(getString(R.string.ad_tag_url)));
}
private void releasePlayer() {
adsLoader.setPlayer(null);
playerView.setPlayer(null);
player.release();
player = null;
}
private void initializePlayer() {
// Create a SimpleExoPlayer and set it as the player for content and ads.
player = new SimpleExoPlayer.Builder(this).build();
playerView.setPlayer(player);
adsLoader.setPlayer(player);
DataSource.Factory dataSourceFactory =
new DefaultDataSourceFactory(this, Util.getUserAgent(this, getString(R.string.app_name)));
ProgressiveMediaSource.Factory mediaSourceFactory =
new ProgressiveMediaSource.Factory(dataSourceFactory);
MediaSource mediaSource =
mediaSourceFactory.createMediaSource(Uri.parse(getString(R.string.content_url)));
AdsMediaSource adsMediaSource =
new AdsMediaSource(mediaSource, dataSourceFactory, adsLoader, playerView);
player.prepare(adsMediaSource);
player.setPlayWhenReady(false);
}
Help me to Complete Code
Related
I am building Music App in which I have uploaded music on firebase. I am using SimpleExoPlayer and PlayerView to run the music. The problem is when I click on the music, the music start after 10 seconds or more. I search it but did not find any solution
ExoPLayer library:
implementation "com.google.android.exoplayer:exoplayer:2.14.1"
public void initPlayer(MusicModel dataModel) {
if (playerLayout.getVisibility() == View.GONE && !isFullScreenOn) {
playerLayout.setVisibility(View.VISIBLE);
}
assignPlayerLayout(dataModel);
assignFullScreenPlayerLayout(dataModel);
try {
playerView.setControllerShowTimeoutMs(0);
playerView.setCameraDistance(10);
playerView.setShowFastForwardButton(false);
playerView.setShowRewindButton(false);
playerView.setShowNextButton(false);
playerView.setShowPreviousButton(false);
playerView.setShutterBackgroundColor(R.color.white);
simpleExoPlayer = new SimpleExoPlayer.Builder(MainActivity.this).build();
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MOVIE)
.build();
simpleExoPlayer.setAudioAttributes(audioAttributes, true);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(MainActivity.this,
Util.getUserAgent(MainActivity.this, getResources().getString(R.string.app_name)));
MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(getString(dataModel.getAudioFile())));
playerView.setPlayer(simpleExoPlayer);
simpleExoPlayer.seekTo(0);
// Tell it to play the sound
simpleExoPlayer.prepare(mediaSource);
simpleExoPlayer.setPlayWhenReady(true);
isPlaying = true;
}catch (Exception e){
Log.e("except",e.toString());
}
}
Please give me a solution
Blockquote
, I shall be very thankful to you.
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);
}
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)
I use the exoplayer 3 times in my application so I thought it would be better to implement it in its own class and just use it 3 times.
In doing this I introduced a memory leak so it is leaking the activity and causing the app to crash.
I am not really sure why this would be happening because I haven't closed the activity. I guess it is because there is some change in the activity or the view.
If you could tell me what is wrong with my implementation to cause a memory leak it would be greatly appreciated.
This is my exoplayer control class:
public class ExoPlayerControls {
Context context;
SimpleExoPlayerView simpleExoplayerView;
SimpleExoPlayer player;
boolean preview;
public ExoPlayerControls(Context context, SimpleExoPlayerView simpleExoplayerView, SimpleExoPlayer player, Boolean preview) {
this.context = context;
this.simpleExoplayerView = simpleExoplayerView;
this.player = player;
this.preview = preview;
}
public boolean setUPExoPlayer (String alarmMediaLocation){
try {
if (player != null){
player.setPlayWhenReady(false);
//URI location of audio
Uri mediaURI = Uri.parse(alarmMediaLocation);
// Data source Factory
DefaultHttpDataSourceFactory datasourceFactory = new DefaultHttpDataSourceFactory("alarm video");
// Extractor Factory
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
// Media source
MediaSource mediasource = new ExtractorMediaSource(mediaURI, datasourceFactory, extractorsFactory, null, null);
// Prepare the exoplayer
player.prepare(mediasource);
player.setPlayWhenReady(false);
} else {
// Create a bandwith meter
BandwidthMeter bandwidthmeter = new DefaultBandwidthMeter();
// Create a track selector
TrackSelector trackselector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory(bandwidthmeter));
// Create the player
player = ExoPlayerFactory.newSimpleInstance(context, trackselector);
//URI location of audio
Uri mediaURI = Uri.parse(alarmMediaLocation);
// Data source Factory
DefaultHttpDataSourceFactory datasourceFactory = new DefaultHttpDataSourceFactory("alarm video");
// Extractor Factory
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
// Media source
MediaSource mediasource = new ExtractorMediaSource(mediaURI, datasourceFactory, extractorsFactory, null, null);
// Bind the player to the view.
simpleExoplayerView.setPlayer(player);
// Prepare the exoplayer
player.prepare(mediasource);
player.setPlayWhenReady(false);
}
} catch (Error e){
Toast.makeText(context, "Exoplayer error" + e, Toast.LENGTH_SHORT).show();
}
return true;
}
public void playAlarmMedia(String alarmMediaLocation){
try {
boolean exoPlayerSet = setUPExoPlayer(alarmMediaLocation);
if (exoPlayerSet){
// Tell exoplayer to start playing immediately
player.setPlayWhenReady(true);
}
} catch (Error e){
Toast.makeText(context, "Exoplayer error" + e, Toast.LENGTH_SHORT).show();
}
}
}
And I implement it in my activity like this:
// Initialise exoplayer controls
exoPlayerControls = new ExoPlayerControls(this, simpleExoplayerView, player, preview);
String alarmMediaLocation = downloadedAlarmToPlay.getAlarmMediaLocation();
exoPlayerControls.setUPExoPlayer(alarmMediaLocation);
The exoplayer class has three nested static classes/interfaces ExoplayerComponent, Factory and Listener. In general any Static objects will hold reference to an activity. Could the memory leak be caused by orientation changes? Because the activity will be unable to destroy itself. So older instances of the activity will be retained in memory causing a memory leak. A way to get over this is to use getAppplicationContext() instead of the Activity context (this). The application context is a singleton object. So every time Activity gets created due to screen rotation, no new instances of context are being created.
I have a dog.mp4 video file in res/raw folder, which I want to play with ExoPlayer. I'm trying to figure out how to get video Uri for this line of code from ExoPlayer developers guide (https://google.github.io/ExoPlayer/guide.html):
MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri,
dataSourceFactory, extractorsFactory, null, null);
To get it, I use this line:
Uri mp4VideoUri = Uri.parse("android.resources://"+getPackageName()+"/"+R.raw.dog);
Also tried this syntax: android.resource://[package]/[res type]/[res name]
But SimpleExoPlayerView stays black and I get following error:
com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to android.resources://lt.wilkas.deleteexoplayer/2131099648
What am I doing wrong?
Don't move your videos from raw to any another folder
Use this code to play video:
PlayerView playerView = findViewById(R.id.player_view);
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(this);
// Bind the player to the view.
playerView.setPlayer(player);
// Produces DataSource instances through which media data is loaded.
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "yourApplicationName"));
// This is the MediaSource representing the media to be played.
MediaSource firstSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(RawResourceDataSource.buildRawResourceUri(R.raw.dog));
// Prepare the player with the source.
player.prepare(firstSource);
According to ExoPlayer 2.12 its even easier to use MediaItem.
To create it we need Uri that could be generated from RawResourceDataSource.buildRawResourceUri.
And that's it. Just set this MediaItem do prepare() and play when ready:
SimpleExoPlayer.Builder(view.context).build().apply {
val uri = RawResourceDataSource.buildRawResourceUri(R.raw.video)
setMediaItem(MediaItem.fromUri(uri))
prepare()
playWhenReady = true
}
I've found out that res/raw folder cant be used to store local videos for ExoPlayer. They should be placed in assets folder.
res/raw folder can be used to access local video file for ExoPlayer via it's URI. Here's the solution that will not give the Malformed URL exception and it works for me. You have to use RawResourceDataSource.buildRawResourceUri(R.raw.video) method of the RawResourceDataSource class. Keep in mind that i used the 2.8.0 version of ExoPlayer.
public class MainActivity extends AppCompatActivity {
PlayerView playerView;
SimpleExoPlayer simpleExoPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerView=findViewById(R.id.playerView);
}
#Override
protected void onStart() {
simpleExoPlayer= ExoPlayerFactory.newSimpleInstance(this,new DefaultTrackSelector());
DefaultDataSourceFactory defaultDataSourceFactory=new DefaultDataSourceFactory(this, Util.getUserAgent(this,"yourApplicationName"));
simpleExoPlayer.setPlayWhenReady(true);
ExtractorMediaSource extractorMediaSource=new ExtractorMediaSource.Factory(defaultDataSourceFactory).createMediaSource(RawResourceDataSource.buildRawResourceUri(R.raw.video));
simpleExoPlayer.prepare(extractorMediaSource);
playerView.setPlayer(simpleExoPlayer);
super.onStart();
}
#Override
protected void onStop() {
playerView.setPlayer(null);
simpleExoPlayer.release();
simpleExoPlayer=null;
super.onStop();
}
}
here is the sample to load video/audio file from res/raw with ExoPlayer :
val player = ExoPlayerFactory.newSimpleInstance(context,DefaultTrackSelector())
val rawDataSource = RawResourceDataSource(context)
rawDataSource.open(DataSpec(RawResourceDataSource.buildRawResourceUri(R.raw.brown)))
val mediaSource = ExtractorMediaSource.Factory(DataSource.Factory { rawDataSource })
.createMediaSource(rawDataSource.uri)
player.playWhenReady = true
player.prepare(mediaSource)
sample copied from
This code works for me.
fun buildMediaSourceRaw() : MediaSource{
val dataSourceFactory = DefaultDataSourceFactory(context, "exoPlayer")
val uri = RawResourceDataSource.buildRawResourceUri(R.raw.my_video)
return ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri)
}
Then
player?.prepare(buildMediaSourceRaw())