I'm trying to create a custom video playback, which has a video view and media controller:
VideoView mVideoView =(VideoView) findViewById(R.id.videoView);
mVideoView.setVideoURI(uri);
MediaController mMediaController = new MyMediaController(this);
mMediaController.findFocus();
mMediaController.setEnabled(true);
mMediaController.setAnchorView(mVideoView);
mVideoView.setMediaController(mMediaController);
Problem is that: when I programmatically change value of seekbar:
mVideoView.pause();
mVideoView.seekTo(newValue);
MediaController doesn't update these changes immediately. It updates only after I touch it again. Can anybody tell me the right way to update state of media controller? Thanks a a lot!
for this you have to set an handler that is call after every one second like below code-
static Runnable musicSchedular = new Runnable() {
#Override
public void run() {
resetSeek();
}
};
public static void resetSeek(){
long currentDuration = mediaPlayer.getCurrentPosition();
int cPos = (int)currentDuration/1000;
seekBar.setProgress(cPos);
}
and when you start playing music paste this line of code
myHandler.postDelayed(musicSchedular,100);
hope it will solve your problem.
Related
I'm using VideoView to loop a small video, all works fine on the emulators, but when I deploy that to TV, after the first loop video turns black, but sound keeps going. This is the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
VideoView videoview = (VideoView) findViewById(R.id.videoview1);
Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.video);
videoview.setVideoURI(uri);
videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
videoview.start();
}
});
}
The Emulator is using Android 6.0, the TV is Sony Bravia with Android 6.0.1.
I tested using SurfaceView, instead of VideoView - the same thing happens.
Any idea how to get rid of that black screen?
PS: There is a workaround that works - make OnCompletionListener and do videoview.start() there - this way it loops, but there's an ugly gap between the loops.
Just use this mVideoView.setZOrderOnTop(true); It will not show the black screen as the view appears.
Try to set your VideoView using handler like this.
videoview.setBackgroundColor(Color.WHITE); //color what you want as background
videoview.postDelayed(new Runnable() {
#Override
public void run() {
videoview.setVideoURI(videoUri);
}
}, 100);
videoview.postDelayed(new Runnable() {
#Override
public void run() {
vv.setBackgroundColor(Color.TRANSPARENT);
}
}, 300);
videoview.requestFocus();
videoview.start();
videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { #Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
}
});
I have looked into the source code of VideoView and the first thing that I would like to point out is that inside the setVideoURI() method the MediaPlayer object will be created, and the OnPreparedListener will be set.
Your mistake is that you set the OnPreparedListener after the MediaPlayer may already have prepared the video, thus never call the onPrepared in the listener you have set after that, which means the setLooping(true) was maybe never set on the MediaPlayer.
TL;DR:
Put videoview.setVideoURI(uri); after videoview.setOnPreparedListener().
videoview.start() should be after setVideoURI(). On finish it should start again without additional input because this time mp.setLooping(true); was correctly set and will be executed. No videoview.start() is necessary after the initial one.
I actually ended up using ExoPlayer instead of the default one.
It's a bit harder to set up, but this problem didn't show up there.
Im trying to get the seekbar to update and show progress whenever I play an mp3 with mediaPlayer. Music plays fine everytime, seekbar will always snap to 0 position when mp3 is playing.
I was trying to follow this answer but it just wont work... SeekBar and media player in android
I have this code in main activity
private Handler mHandler = new Handler();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (Assets.mediaPlayer != null) {
int mCurrentPosition = Assets.mediaPlayer.getCurrentPosition() / 1000;
if(OnionFragment.seekBar!= null) {
OnionFragment.seekBar.setProgress(mCurrentPosition);
}
}
mHandler.postDelayed(this, 1000);
}
});
in OnionFragment I have
public static SeekBar seekBar;
seekBar = (SeekBar) rootView.findViewById(R.id.seekBar);
and in OnionFragments onclick (the play button)I have
Assets.playMusicFile(MainActivity.items.get(MainActivity.selectedItem).getSongId(), true);
if(Assets.mediaPlayer!=null) {
seekBar.setMax(Assets.mediaPlayer.getDuration());
}
OnionFragment is loaded into MainActivity right away and looks like this
P.S. If anyone has extra time, how do i change size of seekbar ball and color
Change
seekBar.setMax(Assets.mediaPlayer.getDuration());
to
seekBar.setMax(Assets.mediaPlayer.getDuration()/1000);
Hi in my android application I am using videoview for streaming my videos. I face very unwanted behaviour from my videoview. The scenario is like this. I have activity A and activity B. Activity A has one simple button and on click of that button I am starting activity B which contains videoview and starts playing video as soon as it start my activity. So my observation is like this: Once I start Activity B it will call setVideoURI and start(). there are few callback methods one of them is setOnPreparedListener. when I call start() after some time It is executing setOnPreparedListener and after that it will start playing video. But in between before executing setOnPreparedListener if I come back to Activity A it will block that activity UI for some time. But if I wait till setOnPreparedListener get executes and then come back to Activity A then its working properly. This is not happening with all devices only with google devices like moto g and nexus. But I tried with htc or intel device it is working properly. My code looks like :
VideoView mVideoView =(VideoView)findViewById(R.id.myVideo);
//Creating MediaController
MediaController mediaController= new MediaController(this);
mediaController.setAnchorView(mVideoView);
//specify the location of media file
Uri uri=Uri.parse("http://abcExample.com/playlist.m3u8");
//Setting MediaController and URI, then starting the videoView
mVideoView.setMediaController(mediaController);
mVideoView.setVideoURI(uri);
mVideoView.requestFocus();
mVideoView.start();
mVideoView.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i("this is video view sample ... ", "this is video view sample ... this is on error listener ");
return true;
}
});
mVideoView.setOnPreparedListener(new OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp)
{
Log.i("this is video view sample ... ", "this is video view sample ... this is on prepared listener ");
}
});
mVideoView.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
Log.i("this is video view sample ... ", "this is video view sample ... this is on complete listener ");
}
});
Am I missing something or doing something wrong? Need some help. Thank you.
I'm having the same behaviour with videoview. I was looking for a solution but i didn't find anything. Maybe, It's possible that making a new task fix that issue. I'll try it
This below activity works fine but the mediaController display only if I click on the screen. And the second problem is the media controller display only for 3 sec. what should I do to remove this problem?
public class PlayingActivity extends Activity
{
private VideoView mVideoView;
private EditText mPath;
MediaController mediaController;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playingactivity);
mPath = (EditText) findViewById(R.id.path);
mPath.setText(GlobalVariable.getstrEmail());
mVideoView = (VideoView) findViewById(R.id.surface_view);
Uri uri = Uri.parse("/sdcard/download/test.mp3");
mediaController = new MediaController(this);
mediaController.findFocus();
mediaController.setEnabled(true);
mediaController.show(0);
mediaController.setAnchorView(mVideoView);
mVideoView.setMediaController(mediaController);
mVideoView.setVideoURI(uri);
mVideoView.start();
}
}
mediaController.requestFocus();
will make it display as soon as the video starts ( without requiring the click)
and
mVideoView.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mediaController.show(0);
}
});
Will keep it on the screen.
Hope it helps
Requesting focus or specifying 0 in show method never worked for me.
The problem is that MediaController class has default timeout of 3000ms or 3seconds. And its show() method replaces our given parameter to its default parameter. Its a stupid bug resulting from untested code at Google.
We need to implement a lousy workaround of replacing the default value by desired value.
Try the below code. It should work.
mediaControls = new MediaController(getActivity()){
#Override
public void show (int timeout){
if(timeout == 3000) timeout = 20000; //Set to desired number
super.show(timeout);
}
};
mVideoView.setMediaController(mediaControls);
Neo's suggestions are perfect. But I would like to add "mp.start()" to onPrepared(MediaPlayer mp) method, without which the media file won't start playing.
There are two main problem in MediaController:
auto hide is 3s by default
Tapping on the video shows/hide the control bar
For the first part it's easly fixed changing the default timeout value of start to zero (zero means indefinite,it is used internally as the video starts) like this:
mediaController = new MediaController(this){
#Override
public void show() {
super.show(0);//Default no auto hide timeout
}
};
The second problem is a little tricky because the click handler is declared as private and final so we do not have any control on that.
My solution is to use another function to set visibility and disable the hide function like this:
mediaController = new MediaController(this){
#Override
public void show() {
super.show(0);//Default no auto hide timeout
}
#Override
public void hide() {
//DOES NOTHING
}
void setVisible(boolean visible){//USE THIS FUNCTION INSTEAD
if(visible)
super.show();
else
super.hide();
}
};
You can also add a variable to re-enable standard functionality if visibility is set to false like so:
mediaController = new MediaController(this){
private boolean forceVisible=false;
#Override
public void show() {
super.show(0);//Default no auto hide timeout
}
#Override
public void hide() {
if(!forceVisible)super.hide();
}
void setVisible(boolean visible){
forceVisible=visible;
if(visible)
super.show();
else
super.hide();
}
};
I am using MediaController in my app. But unfortunately the MediaController disappears after a time period of 3 secs. But I want my MediaController to be visible until my video plays fully.
How to achieve this.
By default the MediaController hides itself after 3 secs of time. In order to make it visible throughout our video playback we will have to override the hide() of MediaController. I have given the code snippet below.
final MediaController mc = new MediaController(this);
video.setMediaController(new MediaController(this) {
#Override
public void hide()
{
mc.show();
}
});
video.setMediaController(mc);
For stop hiding the MediaController we can make a new Mediacontroller by extending the base class. Then we can disable the hide method by simply overriding it. For getting the actual hide functionality, we can fetch the hide() method in base class. We can hide the Mediacontroller after playback is completed using that.
Here is the code for MediaController:
public class MediaController_2 extends MediaController{
public MediaController_2(Context context) {
super(context);
}
public void hide() {
}
public void hidecontroller() {
super.hide();
}
}
Now the mediacontroller won't be hiding even after the completion of the playback. For hiding the controllers after completing playback we can use OnCompletionListener.
MediaController_2 mediaController = new MediaController_2(getActivity());
mediaPlayer.prepare();
mediaPlayer.start();
mediaController.show(0);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mediaController.hidecontroller();
}
});
More Succinct
First off, using an int timeout as a parameter in the show() method did nothing for me.
Secondly, this succinct piece of code forced the controls to stay on the screen after the first touch:
// Assumes you have a VideoView in your layout called 'video_preview'.
VideoView videoPreview = (VideoView) findViewById(R.id.video_preview);
MediaController mediaController = new MediaController(this) {
#Override
public void hide() {} // Prevent hiding of controls.
};
videoPreview.setMediaController(mediaController);
VideoView videoPlayer;
MediaController mediaController;
videoPlayer = view.findViewById(R.id.videoPlayer);
Uri uri = Uri.parse(URL);
videoPlayer.setVideoURI(uri);
mediaController = new MediaController(getContext()) {
#Override
public void hide() {} // on hide do nothing
};
videoPlayer.setMediaController(mediaController);
videoPlayer.requestFocus();
videoPlayer.start();