I'm new to Android Studio and ExoPlayer
I started the player to play videos but I don't know to detect if the player is buffering and show a progress bar to notify the user, any help please?
Maybe it will be helpful to someone:
<com.google.android.exoplayer2.ui.PlayerView
android:id="#+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black"
app:show_buffering="true"/>
you can simply change XML attribute show_buffering if you are using Exoplayer2.
Also see PlayerView.setShowBuffering(PlayerView.ShowBuffering) for more details.
in layout file:
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"/>
in player activity:
player.addListener(new ExoPlayer.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, Object manifest) {}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {}
#Override
public void onLoadingChanged(boolean isLoading) {}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (playbackState == ExoPlayer.STATE_BUFFERING){
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.INVISIBLE);
}
}
#Override
public void onPlayerError(ExoPlaybackException error) {}
#Override
public void onPositionDiscontinuity() {}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {}
});
You should implement ExoPlayer.EventListener and override onPlayerStateChanged() to detect state of playing video progress (STATE_IDLE, STATE_BUFFERING, STATE_READY, STATE_ENDED)
Seeing the answers of others, i did it this way. I used ExoPlayer version 2.7.0.
private Player.EventListener eventListener = new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
//Log.i(TAG,"onTracksChanged");
}
#Override
public void onLoadingChanged(boolean isLoading) {
//Log.i(TAG,"onLoadingChanged");
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_ENDED:
Log.i("EventListenerState", "Playback ended!");
exoPlayer.setPlayWhenReady(false);
break;
case Player.STATE_READY:
Log.i("EventListenerState", "Playback State Ready!");
hideProgressBar();
break;
case Player.STATE_BUFFERING:
Log.i("EventListenerState", "Playback buffering");
showProgressBar();
break;
case Player.STATE_IDLE:
break;
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
};
mPlayer.addListener(eventListener);
Player.EventListener eventListener = new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_ENDED:
Log.i("EventListenerState", "Playback ended!");
finish();
break;
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
};
You can simply add app:show_buffering="when_playing" attr in playerView in your xml file
see this for more information https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/ui/PlayerView.html#SHOW_BUFFERING_WHEN_PLAYING
It is working for me.
<com.google.android.exoplayer2.ui.PlayerView
android:id="#+id/videoPlayer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:resize_mode="fill"
app:surface_type="texture_view"
app:use_controller="true"
app:show_buffering="always" />
Now Player.EventListener is deprecated, instead of use Player.Listener
simpleExoPlayer.addListener(object : Player.Listener {
override fun onTracksChanged(
trackGroups: TrackGroupArray,
trackSelections: TrackSelectionArray
) {
}
override fun onLoadingChanged(isLoading: Boolean) {}
override fun onPlayerStateChanged(
playWhenReady: Boolean,
playbackState: Int
) {
if (playbackState == Player.STATE_BUFFERING) {
}
}
override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters) {}
})
Related
I am trying to create simple video player in android studio, using exoplayer but i got this error
Process: com.example.smschecker, PID: 30203
java.lang.NoSuchMethodError: No interface method addListener(Lcom/google/android/exoplayer2/ExoPlayer$EventListener;)V in class Lcom/google/android/exoplayer2/ExoPlayer; or its super classes (declaration of 'com.google.android.exoplayer2.ExoPlayer' appears in /data/app/com.example.smschecker-2/base.apk)
at com.google.android.exoplayer2.ui.PlaybackControlView.setPlayer(PlaybackControlView.java:361)
at com.google.android.exoplayer2.ui.SimpleExoPlayerView.setPlayer(SimpleExoPlayerView.java:384)
at com.example.smschecker.MovieDetails.iniPlayer(MovieDetails.java:137)
at com.example.smschecker.MovieDetails.onStart(MovieDetails.java:120)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1244)
at android.app.Activity.performStart(Activity.java:6183)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2619)
at android.app.ActivityThread.access$800(ActivityThread.java:178)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1475)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5648)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Below is the java code snippet.
#Override
protected void onStart() {
super.onStart();
iniPlayer();
}
private void iniPlayer() {
String videoUr = "https://torrent243454.herokuapp.com/stream/magnet%3A%3Fxt%3Durn%3Abtih%3A65046701a31f23b2bb7e6d38537ca8498970d1ff%26dn%3DMortal.Kombat.Legends.Battle.of.the.Realms.2021.HDRip.XviD.AC3-EVO%26xl%3D1453573916%26tr%3Dudp%253A%252F%252Ftracker.opentrackr.org%3A1337%2Fannounce%26tr%3Dudp%253A%252F%252Ftracker.internetwarriors.net%3A1337%2Fannounce%26tr%3Dudp%253A%252F%252Fopentor.org%3A2710%2Fannounce%26tr%3Dudp%253A%252F%252F9.rarbg.me%3A2980%2Fannounce%26tr%3Dudp%253A%252F%252F9.rarbg.to%3A2940%2Fannounce%26tr%3Dudp%253A%252F%252Ftracker.uw0.xyz%3A6969%2Fannounce%26tr%3Dudp%253A%252F%252Fopen.stealth.si%3A80%2Fannounce%26tr%3Dudp%253A%252F%252Ftracker.torrent.eu.org%3A451%2Fannounce%26tr%3Dudp%253A%252F%252Fipv4.tracker.harry.lu%3A80%2Fannounce%26tr%3Dudp%253A%252F%252Ftracker.openbittorrent.com%3A1337%2Fannounce%26tr%3Dudp%253A%252F%252Fexodus.desync.com%3A6969%2Fannounce%26tr%3Dudp%253A%252F%252Fexplodie.org%3A6969%2Fannounce%26tr%3Dudp%253A%252F%252Ftracker.tiny-vps.com%3A6969%2Fannounce%26tr%3Dudp%253A%252F%252Ftracker.moeking.me%3A6969%2Fannounce%26tr%3Dudp%253A%252F%252Ftracker.cyberia.is%3A6969%2Fannounce?file=Mortal.Kombat.Legends.Battle.of.the.Realms.2021.HDRip.XviD.AC3-EVO%2FMortal.Kombat.Legends.Battle.of.the.Realms.2021.HDRip.XviD.AC3-EVO.avi";
Uri uri = Uri.parse(videoUr);
SimpleExoPlayerView playerView = findViewById(R.id.player_view);
LoadControl loadControl = new DefaultLoadControl();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelector trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory(bandwidthMeter));
SimpleExoPlayer simpleExoPlayer1 = ExoPlayerFactory.newSimpleInstance(MovieDetails.this, trackSelector, loadControl);
DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("exoplayer_video");
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource mediaSource = new ExtractorMediaSource(uri, factory, extractorsFactory, null, null);
playerView.setPlayer(simpleExoPlayer1);
playerView.setKeepScreenOn(true);
simpleExoPlayer1.prepare(mediaSource);
simpleExoPlayer1.setPlayWhenReady(true);
simpleExoPlayer1.addListener(new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, #Nullable Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (playbackState == Player.STATE_BUFFERING){
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
}
Try adding event listener as like this
simpleExoPlayer1.addListener(new ExoPlayer.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity() {
}
});
During the Rewarded video play i want to disable the back button and set a minimum waiting time . is it possible to do?On which function should i change to complete my desired functionality?
here is my code
if (mAd.isLoaded()) {
mAd.show();
} else {
startActivity(new Intent(EssayActivityQstnShow2.this, Essay_Answer_Show.class));
}
and here is Rewarded video ads handling methods
private void loadRewardedVideoAds() {
if (!mAd.isLoaded()) {
mAd.loadAd(getResources().getString(R.string.rewardedvideoid), new AdRequest.Builder().build());
}
}
#Override
public void onRewardedVideoAdLoaded() {
}
#Override
public void onRewardedVideoAdOpened() {
// onBackPressed();
}
#Override
public void onRewardedVideoStarted() {
// onBackPressed();
}
#Override
public void onRewardedVideoAdClosed() {
startActivity(new Intent(EssayActivityQstnShow2.this, Essay_Answer_Show.class));
}
#Override
public void onRewarded(RewardItem rewardItem) {
}
#Override
public void onRewardedVideoAdLeftApplication() {
}
#Override
public void onRewardedVideoAdFailedToLoad(int i) {
loadRewardedVideoAds();
}
#Override
public void onRewardedVideoCompleted() {
startActivity(new Intent(EssayActivityQstnShow2.this, Essay_Answer_Show.class));
}
Try below code
private boolean isVideoPlaying;
#Override
public void onRewardedVideoStarted() {
isVideoPlaying = true;
}
#Override
public void onRewardedVideoAdClosed() {
isVideoPlaying = false;
}
and than onBackPress() check, if the video is playing or not
#Override
public void onBackPressed() {
if (!isVideoPlaying)
super.onBackPressed();
}
Before implementing this, please read the policies carefully.
You must override the onBackPressed callback in activity and remove line super.onBackPressed(). then if the user taps the back button the activity will not close.
If you have no access to the Essay_Answer_Show activity check can you create another activity which extends that or clone library and tries to modify activity?
i'm trying to use the onVideoEnded() method, but by any reason it is not working.
I've implemented PlayerStateChangeListener but it did not seems to be working. I've added toasts on every method of the implementation, they are not firing.
when this activity starts, it automatically plays the video:
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player,
boolean wasRestored) {
if (!wasRestored) {
player.loadVideo(videoId);
}
}
And this is the interface implementation:
//start interface implementation
#Override
public void onLoading() {
android.widget.Toast.makeText(getApplicationContext(), "onloading",
android.widget.Toast.LENGTH_LONG).show();
}
#Override
public void onLoaded(String s) {
android.widget.Toast.makeText(getApplicationContext(), "onloaded",
android.widget.Toast.LENGTH_LONG).show();
}
#Override
public void onAdStarted() {
android.widget.Toast.makeText(getApplicationContext(), "onadstarted",
android.widget.Toast.LENGTH_LONG).show();
}
#Override
public void onVideoStarted() {
android.widget.Toast.makeText(getApplicationContext(), "onvideostarted",
android.widget.Toast.LENGTH_LONG).show();
}
#Override
public void onVideoEnded() {
android.widget.Toast.makeText(getApplicationContext(), "onvideoended",
android.widget.Toast.LENGTH_LONG).show();
}
#Override
public void onError(YouTubePlayer.ErrorReason errorReason) {
android.widget.Toast.makeText(getApplicationContext(), "onerror",
android.widget.Toast.LENGTH_LONG).show();
}
Am i missing something?
thanks!
I just figured it out and i'll post it in case somebody have the same issue. You just need to add a new class with the state listener just as it is described on
this website
Gdata API for YouTube feed is not working, from last some days.. so any alternative for to get feed from YouTube API..??
http://gdata.youtube.com/feeds/api/playlists/PL_yIBWagYVjyyqx_qPkbat5zufWZOyZEZ
Download YouTubePlyaer API https://developers.google.com/youtube/android/player/downloads/
Register your app on google developer console https://console.developers.google.com
Take an unique API Key and use that in your App.
use below code
public class AboutUs extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_about_us);
YouTubePlayerView youTubePlayerView = (YouTubePlayerView) findViewById(R.id.youtube_player);
youTubePlayerView.initialize(Constants.YOUTUBE_API_KEY, this);
initViews();
}
private void initViews() {
Button btnVisitMega = (Button) findViewById(R.id.btn_visit_megaforties);
Button btnVisitSecurity = (Button) findViewById(R.id.btn_visit_security_seals);
btnVisitMega.setOnClickListener(this);
btnVisitSecurity.setOnClickListener(this);
}
#Override
public void onInitializationFailure(Provider arg0, YouTubeInitializationResult arg1) {
Toast.makeText(this, "Failured to Initialize!", Toast.LENGTH_LONG).show();
}
#Override
public void onInitializationSuccess(Provider provider, YouTubePlayer player, boolean wasRestored) {
/** add listeners to YouTubePlayer instance **/
player.setPlayerStateChangeListener(playerStateChangeListener);
player.setPlaybackEventListener(playbackEventListener);
/** Start buffering **/
if (!wasRestored) {
player.cueVideo(Constants.YOUTUBE_VIDEO_ID);
}
}
private PlaybackEventListener playbackEventListener = new PlaybackEventListener() {
#Override
public void onBuffering(boolean arg0) {
}
#Override
public void onPaused() {
}
#Override
public void onPlaying() {
}
#Override
public void onSeekTo(int arg0) {
}
#Override
public void onStopped() {
}
};
private PlayerStateChangeListener playerStateChangeListener = new PlayerStateChangeListener() {
#Override
public void onAdStarted() {
}
#Override
public void onError(ErrorReason arg0) {
}
#Override
public void onLoaded(String arg0) {
}
#Override
public void onLoading() {
}
#Override
public void onVideoEnded() {
}
#Override
public void onVideoStarted() {
}
};
I have been successfully using YouTubePlayerSupportFragment to play YouTube videos.
But I still need to continue playing in the background, when the back button is pressed.
If you have any ideas, please share with me. Thanks!
Here is my code -
YoutubePlayerFragment class
public class YoutubePlayerFragment {
public static String DEVELOPER_KEY = "DEVELOPER_KEY";
public static boolean isFullScreen;
public static void setYoutubePlayerFragment(final Fragment fragment) {
MainFragment.youtubePlayerFragment = new YouTubePlayerSupportFragment();
MainFragment.youtubePlayerFragment.initialize(DEVELOPER_KEY, new OnInitializedListener() {
#Override
public void onInitializationFailure(Provider arg0, YouTubeInitializationResult arg1) {
}
#Override
public void onInitializationSuccess(Provider arg0, YouTubePlayer player,
boolean paramBoolean) {
PlayerService.youTubePlayer = player;
PlayerService.youTubePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT);
setListener(fragment.getActivity());
}
});
replaceFragment(fragment);
}
public static void replaceFragment(final Fragment fragment) {
if (fragment == null)
return;
FragmentManager fragmentManager = fragment.getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.youtubeplayerFrameLayout,
MainFragment.youtubePlayerFragment);
fragmentTransaction.commit();
}
public static void setListener(final Activity activity) {
PlayerService.youTubePlayer.setOnFullscreenListener(new OnFullscreenListener() {
#Override
public void onFullscreen(boolean isFullScreen) {
YoutubePlayerFragment.isFullScreen = isFullScreen;
Log.d(App.tagName, "setOnFullscreenListener : onFullscreen");
}
});
PlayerService.youTubePlayer.setPlayerStateChangeListener(new PlayerStateChangeListener() {
#Override
public void onAdStarted() {
Log.d(App.tagName, "setPlayerStateChangeListener : onAdStarted");
}
#Override
public void onError(ErrorReason arg0) {
Log.d(App.tagName, "setPlayerStateChangeListener : onError : " + arg0);
}
#Override
public void onLoaded(String arg0) {
Log.d(App.tagName, "setPlayerStateChangeListener : onLoaded");
}
#Override
public void onLoading() {
Log.d(App.tagName, "setPlayerStateChangeListener : onLoading");
}
#Override
public void onVideoEnded() {
Log.d(App.tagName, "setPlayerStateChangeListener : onVideoEnded");
}
#Override
public void onVideoStarted() {
Log.d(App.tagName, "setPlayerStateChangeListener : onVideoStarted");
}
});
PlayerService.youTubePlayer.setPlaybackEventListener(new PlaybackEventListener() {
#Override
public void onBuffering(boolean arg0) {
Log.d(App.tagName, "setPlaybackEventListener : onBuffering");
if (MainActivity.isBack && PlayerService.youTubePlayer != null) {
PlayerService.youTubePlayer.play();
}
}
#Override
public void onPaused() {
Log.d(App.tagName, "setPlaybackEventListener : onPaused");
PlayerFrameLayout.ibPlay.setImageResource(R.drawable.ic_play_arrow_white_36dp);
if (MainActivity.isBack && PlayerService.youTubePlayer != null) {
PlayerService.youTubePlayer.play();
}
}
#Override
public void onPlaying() {
Log.d(App.tagName, "setPlaybackEventListener : onPlaying");
PlayerFrameLayout.ibPlay.setImageResource(R.drawable.ic_pause_white_36dp);
}
#Override
public void onSeekTo(int arg0) {
Log.d(App.tagName, "setPlaybackEventListener : onSeekTo");
}
#Override
public void onStopped() {
Log.d(App.tagName, "setPlaybackEventListener : onStopped");
}
});
}}
Using Service to play Youtube video.
public class PlayerService extends Service {
public static YouTubePlayer youTubePlayer = null;
private int MSG;
#Override
public void onCreate() {
super.onCreate();
Log.d(App.tagName, "PlayerService : onCreate");
YoutubePlayerFragment.setYoutubePlayerFragment(MainFragment.mainFragment);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(App.tagName, "PlayerService : onStartCommand");
MediaInfo mediaInfo = MusicListFragment.getCurrentMp3Info();
youTubePlayer.loadVideo(mediaInfo.video_id);
youTubePlayer.play();
return super.onStartCommand(intent, flags, startId);
} }