The wording on this is most likely wrong, but I want to play this video without having the background black. If you look at this webpage you will see that the video is on a white background which leads me to believe that it is cropped or masked. Which view would I use to do this? I have tried both TextureView and VideoView but both have a black background by default.
I solve it with this:
#Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
Log.d(TAG, "onInfo, what = " + what);
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
// video started; hide the placeholder.
placeholder.setVisibility(View.GONE);
return true;
}
return false;
}
});
I think onPrepared just means the video is ready to play, but not means video started playing. If hide placeholder in onPrepared, the screen still show a black screen.
On my Note4 and Nexus, this solution works well.
Related
I am working with some code that creates a Surface programmatically and uses it to display the camera preview. I am trying to modify it to instead display a video. The changed code (below) plays the video's audio but there is no video--just a black screen.
The camera preview version works fine, so I don't think the issue is with how the SurfaceTexture or Surface are created or displayed.
int texid = getTexture(); //native method
mSurfaceTexture = new SurfaceTexture(texid);
Log.e(TAG, "texid is "+texid);
mSurfaceTexture.setOnFrameAvailableListener(new OnFrameAvailableListener() {
#Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
Log.d(TAG, "onFrameAvailable");
}
});
final Surface surface = new Surface(mSurfaceTexture);
mediaPlayer.setSurface(surface);
String mSourceString = "clips/key_frames_movie_small.mp4";
AssetManager assetManager = mContext.getResources().getAssets();
AssetFileDescriptor clipFd = assetManager.openFd(mSourceString);
mediaPlayer.setDataSource(clipFd.getFileDescriptor(),
clipFd.getStartOffset(),
clipFd.getLength());
clipFd.close();
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(TAG, "ERROR: "+what + ", " + extra);
return false;
}
});
mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
Log.e(TAG, "INFO: "+what + ", " + extra);
return false;
}
});
mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.e(TAG, "onVideoSizeChanged: "+width + ", " + height);
}
});
mediaPlayer.prepare();
mediaPlayer.start();
Things I've tried:
Using the MediaPlayer to play the same video in a SurfaceView that's in the xml layout. This works fine, so I don't think there's any problem with the video itself.
Removing background colors from xml, as suggested here. No effect.
Playing a small video (320x240) (screen dimens are 1920x1080) in case resolution was a problem, as described here
Used logs to verify that the surface was created before calling mediaPlayer.setSurface(surface) as suggested here.
Called surfaceView.setZOrderOnTop(true), surfaceView.setZOrderMediaOverlay(true), surfaceView.setVisibility(View.VISIBLE) to make sure the view isn't partially hidden by anything. No effect.
Called holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) as described here out of desperation, even though I'm running on 6.0.1.
How can I get the video to play in the surface without changing how the surface texture or surface are created?
Edit:
Logs look like this:
E/com.package: texid is 1
D/MediaPlayer: setSubtitleAnchor in MediaPlayer
W/MediaPlayer: info/warning (3, 0)
D/MediaPlayer: setSubtitleAnchor in MediaPlayer
E/com.package: onVideoSizeChanged: 960, 540
E/com.package: onVideoSizeChanged: 960, 540
E/com.package: INFO: 3, 0
D/com.package: onFrameAvailable
According to the docs, the info code 3 indicates that "The player just pushed the very first video frame for rendering."
onFrameAvailable is called only once. If I do surfaceTexture.updateTexImage(); inside the onFrameAvailable() callback, there are (perhaps once a second) additional calls to onFrameAvailable(), but it doesn't affect the display, which stays black.
I am developing multi player video app, so in that i created 9 views 3*3.
when i initialize all (3*3) videoview then working properly for few seconds and after some time video is goes to black screen, not show single video, i am not understand this issue is device oriented or android not supports more than 1 video in activity, anyone know how to resolve this issue, otherwise if video is turn into black then how to identify video is turned into black screen, if we found this then i will refresh view and again start video, i don't know it is correct way or not.
please anyone know about how to resolve this issue then please share information !
i use below code for show multiple video view in one activity
videoPlayer.setVideoPath("path");
videoPlayer.start();
videoPlayer.requestFocus();
videoPlayer.setKeepScreenOn(true);
set prepare listener
videoPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
}
set completion listener
videoPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//play next
}
});
handle error listener
videoPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
// play next
return true;
}
});
when video play next before that i set some propertied to mediaplyer object
mediaPlayer.setDisplay(null);
mediaPlayer.reset();
mediaPlayer.setDisplay(videoPlayer.getHolder());
i share basic code of my project, please tell me if anything is missing from me or android is not supported multiple videos in same activity.
I tried the below code but did not worked for me
videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mediaPlayer, int what, int i2) {
if (what == mediaPlayer.MEDIA_INFO_BUFFERING_START){
progressBarWait.setVisibility(View.VISIBLE);
}
if (what == mediaPlayer.MEDIA_INFO_BUFFERING_END){
progressBarWait.setVisibility(View.GONE);
}
return false;
}
});
I have to get every state when videoview stop playing video due to buffering so that I can show progressbar for buffering state.
Any help would be appreciable.
this following source code snippet is given:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END){
activity.dismissDialog(DialogID.DIALOG_LOADING);
return true;
}
return false;
}
});
}
});
I am streaming HLS streams with Android 3.x+ devices and trying to hide a loading dialog once the buffering is completed.
The video streaming works, but the info events are never fired.
Any ideas?
I know its too late, But posting it for the users still seeking for the solution (This worked for me):
progressDialog.show();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END){
progressDialog.dismiss();
return true;
} else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START){
progressDialog.show();
}
return false;
}
});
progressDialog.dismiss();
videoView.start();
}
});
You're right, the events are never fired. This is a known HLS bug that I don't think Google will fix.
This applies to the onInfo and the buffering events.
See https://code.google.com/p/android/issues/detail?id=42767 and https://code.google.com/p/googletv-issues/issues/detail?id=2
Sorry!
Not fully sure as to what the OP is asking, but here are some very untimely bits of information.
I wouldn't rely on onPrepared. I find it to be unreliable.
I have found the two most useful pieces of information for HLS streaming through the MediaPlayer are the duration of the video and the progress position of the video. You get both of these by listening to progress updates.
When the duration is greater than zero, you know the video is truly prepared and can be manipulate (scrub). When progress position changes, you know the video is done buffering and has commenced playback. This last item only works when the video is playing of course. The MediaPlayer tends to relay inaccurate information.
These pieces of information are mostly accurate and can usually be relied upon to be "fairly" timely. This timeliness varies from device to device.
onPrepared is called when the MediaPlayer is prepared to start buffering, not when the video is completely buffered. However, it is completely natural to dismiss the loading dialog from within the onPrepared method.
Also MEDIA_INFO_BUFFERING_END is used when MediaPlayer is resuming playback after filling buffers, so I do not think it should be something to use to dismiss the dialog. So this should work:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
activity.dismissDialog(DialogID.DIALOG_LOADING);
}
});
You can able to set OnPreparedListener on videoView because its your object but if you checkout source of VideoView you will find that mMediaPlayer is its private member so any change that you do from external will not be applied to it.
As per your requirement you need buffering status so you can have thread or handler or some thing so you can update your UI to get buffer status there is one method
int percent = videoView.getBufferPercentage();
if(percent == 100){
// buffering done
}
You no need to go through setOnInfoListener
by overriding setOnPreparedListener method is enough. as in the api show
public void setOnPreparedListener (MediaPlayer.OnPreparedListener l)
Register a callback to be invoked when the media file is loaded and
ready to go.
so, you can dismiss your dialog inside setOnPreparedListener method is enough
like this
vv.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "finish11", Toast.LENGTH_LONG).show();
}
});
}
});
If you want to show loading each time it's buffering (initial time or subsequent buffer underruns) just ensure to show it again:
// at the beginning
show
boolean onInfo(int what, int extra) {
switch (what) {
case MEDIA_INFO_BUFFERING_END:
"hide";
break;
case MEDIA_INFO_BUFFERING_START
"show":
}
}
So this event sequence will do as desired:
- whenever you start (setVideoURI or start): show
- onPrepared: just plug the info listener
- onInfo BUFFERING_END hide (it's playing)
- onInfo BUFFERING_START show (it's buffering again)
- onInfo BUFFERING_END hide (it's playing)
Update:
This is assuming the info events work. Of course.
I am using MediaPlayer to play a video in my app. The video takes a while to buffer and the videoview is blank for that time.
Is there a way to start the buffering when the user is in the previous screen, so that when he comes to the video playing screen, the video is ready to play?
Thanks
Chris
MediaPlayer lets you register an OnPreparedListener and an OnBufferingUpdateListener.
I've not tried it, but you could try calling MediaPlayer.prepareAsync() while the user is on the previous screen, then call .start() when the user moves to the right screen. Not sure where the media player can live during this process... You might need to do this all within one activity that you dynamically update when the user wants to see the video.
like below:
mp.setOnInfoListener(new OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
loadingDialog.setVisibility(View.VISIBLE);
} else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
loadingDialog.setVisibility(View.GONE);
}
return false;
}
});
mediaPlayer.setOnInfoListener(new OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == 703) {
// Not documented :(
// See http://stackoverflow.com/a/9622717/435605
isBuffering = true;
} else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
isBuffering = false;
}
return false;
}
});