Whenever videoview is playing a video and there is a network connection drop and the video freezes, my code is not throwing an error even though I have set the videoview error listener.
public class MainActivity extends Activity {
static MediaController mc;
static VideoView vw;
/** Called when the activity is first created. */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
mc = new MediaController(this);
vw = (VideoView) findViewById(R.id.videoView);
vw.setVideoPath("http://173.45.164.105:1935/live/myStream/playlist.m3u8");
vw.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
vw.stopPlayback();
vw.start();
Log.i("VIDEO ERROR ", "FROZE");
return true;
}
});
vw.requestFocus();
vw.start();
}
}
To my understanding the native VideoView element only calls the onError() method when opening the video.
See: VideoView Source
In the openVideo() method -- called when setting the VideoView path/URI -- a couple of exceptions are handled by throwing a MediaPlayer.MEDIA_ERROR_UNKNOWN error.
I'm not positive what goes on in the background with the MediaPlayer whenever a connection is lost with the video source, but it seems that it simply waits indefinitely waiting to re-establish a connection. It will never throw an error via the onErrorListener.
However if you call the setVideoPath() or setVideoUri() method again it will call the onError() method b/c an Exception will be thrown in openVideo().
You'll have to either figure out some way to detect that the connection is lost or wait to see if the time on the video is getting updated and throw an error manually.
If anyone finds a better way to fix this let me know.
Related
I'm working on an application that records video from the camera and then moves to Activity with video preview. Basically, it works fine, but if user records video, moves to video preview screen and returns back to camera multiple times in a row, VideoView eventually returns an error
(E/MediaPlayer: error (1, -19))
and can't play video. After that, this error repeats for every recorded video until I kill the app and start it again. Recorded video is valid, MediaMetadataRetriever can parse it and I can play it via other video player apps.
After searching for a possible solution I checked whether the problem in unreleased MediaPlayer. But moving VideoView.suspend(), that releases MediaPlayer, in onStop() of Activity or in onError() of VideoView hasn't helped.
Is there any idea why this error occurs how to avoid it and why it repeats until I kill the app?
This issue reproduces on Samsung Galaxy S8 (Android 7.0)
compileSdkVersion 25
buildToolsVersion 25.0.2
targetSdkVersion 25
Here is simplified code of VideoView initialization
public class ErrorVideoViewActivity extends AppCompatActivity {
private static final String EXTRA_URI = "EXTRA_URI";
private VideoView mVideoView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_trimmer);
mVideoView = (VideoView) findViewById(R.id.video_view);
mVideoView.setOnPreparedListener(mp -> {
//Do some UI stuff
});
mVideoView.setOnClickListener(view -> {
if (mVideoView.isPlaying()) {
mVideoView.pause();
} else {
mVideoView.start();
}
});
mVideoView.setOnCompletionListener(mp -> mp.seekTo(0));
final Intent intent = getIntent();
if (!intent.hasExtra(EXTRA_URI)) {
throw new IllegalArgumentException();
}
mVideoView.setVideoURI(intent.getParcelableExtra(EXTRA_URI));
}
#Override
protected void onStop() {
super.onStop();
mVideoView.suspend();
}
}
There are so many posts on the same topic but no one is giving proper reason for this error, Could some one help me to solving this error.
My code is working fine for SDCARD videos. whenever I try to access it from url it throws this error.
W/MediaPlayer: Couldn't open file on client side; trying server side: java.io.FileNotFoundException: No content provider: http://download.itcuties.com/teaser/itcuties-teaser-480.mp4
E/MediaPlayer: error (1, -2147483648)
I tried several formats and several urls for everything i am getting the same error.
Internet permissions given.
Code:
public class MainActivity extends AppCompatActivity {
VideoView video1;
String url ="http://download.itcuties.com/teaser/itcuties-teaser-480.mp4";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
video1 = (VideoView) findViewById(R.id.video1);
video1.setVideoURI(Uri.parse(url));
video1.setMediaController(new MediaController(this));
video1.requestFocus();
Thread view1=new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DISPLAY);
video1.start();
}
});
}
}
You just need to start your view1 thread. Your code loads the video but doesn't play it. Adding this will solve the issue.
view1.start();
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
I have a problem in running a video in Samsung S3(Android 4.1.1), the issue seems to be because the videoview is on a fragment because if I put it on and activity, it works.
Also I found out that if I turn on the GPU hardware acceleration on, the video works.
I have also a game made by drawing on a SurfaceView and that view doesn't work as well(only with GPU on)... The rest of the app content is displayed as it supposed to (buttons and other layouts).
I tested the app on Nexus S and on the emulator and it works fine, also on other devices..
Does anyone know what the problem could be?
Thank you!
And here is the code:
public class VideoFragment extends Fragment implements MediaPlayer.OnCompletionListener,
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {
private Video mVideo;
private VideoView mVideoView;
// The video position
private int mPosition;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.screen_video, container, false);
mVideoView = (VideoView) fragmentView.findViewById(R.id.VideoView);
return fragmentView;
}
#Override
public void onPause() {
super.onPause();
// Pause the video if it is playing
if (mVideoView.isPlaying()) {
mVideoView.pause();
}
// Save the current video position
mPosition = mVideoView.getCurrentPosition();
}
#Override
public void onResume() {
super.onResume();
mVideoView.setOnCompletionListener(this);
mVideoView.setOnPreparedListener(this);
mVideoView.setOnErrorListener(this);
mVideoView.setKeepScreenOn(true);
// Initialize the media controller
MediaController mediaController = new MediaController(getActivity());
mediaController.setMediaPlayer(mVideoView);
// Set-up the video view
mVideoView.setMediaController(mediaController);
mVideoView.requestFocus();
mVideoView.setVideoPath(mVideo.getUrl());
if (mVideoView != null) {
// Restore the video position
mVideoView.seekTo(mPosition);
mVideoView.requestFocus();
}
}
#Override
public void onDestroy() {
super.onDestroy();
// Clean-up
if (mVideoView != null) {
mVideoView.stopPlayback();
mVideoView = null;
}
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
Log.e("VIDEO PLAY", "end video play");
}
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
// Start the video view
mediaPlayer.start();
Log.e("VIDEO PLAY", "video ready for playback");
}
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
Log.e("VIDEO PLAY", "error: " + i);
return true;
}
}
I don't think it's something related to context(Application or Activity).. because on all other devices the Video and the games are displayed..
Thanks for the help!
I have a similar problem, and i solved it changing:
MediaController mediaController = new MediaController(getActivity().getApplicationContext());
to this (In a fragmet):
MediaController mediaController = new MediaController(getActivity());
Hope this helps,...
EDIT
Look at this class
http://code.google.com/p/sinaweibo-honeycomb/source/browse/branches/sinaweibo-merged/src/com/lenovo/dll/SinaWeibo/VideoFragment.java?r=71
If hardware acceleration fixes your issue then I would enable it for that view/window on that device.
In general I've found that when code works on one device but not another it is typically caused by one of the following problems:
Bug in the manufacturer's API implementation
Different interpretation of the API by the manufacturer
Concurrency problem (e.g. race condition, improper synchronization) in your own code that happens to trigger more frequently on a particular device
As far as I can tell you seem to be using the UI thread appropriately so I would imagine your issue falls into one of the first two categories and you'll just need to work around it.
Move MediaController mediaController = new MediaController(getActivity()) from onResume() to onCreateView.
Hi all i've ran into another problems with VideoView.
Then video is playing, and I put device asleep, using hard button, onPause() is called. But it followed by:
03-17 11:26:33.779: WARN/ActivityManager(884): Activity pause timeout for HistoryRecord{4359f620 com.package/com.package.VideoViewActivity}
And then i have onStart()/onResume() again and Video starts playing. I've try to move code around onStart()/onStop() - doesn't seems to make difference.
sample code :
public class VideoViewActivity extends Activity {
private String path = "";
private VideoView mVideoView;
private static final String MEDIA_URL = "media_url";
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.videoview);
mVideoView = (VideoView)findViewById(R.id.surface_view);
path = getIntent().getStringExtra(MEDIA_URL);
}
#Override
public void onResume() {
super.onResume();
mVideoView.setVideoPath(path);
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
mVideoView.start();
}
#Override
public void onPause() {
super.onPause();
mVideoView.stopPlayback();
mVideoView.setMediaController(null);
}
}
Why is it happening? And how do I stop that?
It's not a greatest experience than you put your device to sleep and it starts playing video
OK, Looks like the behavior is related to activity lifecycle and the fact that VideoViewActivity is set to landscape in the manifest. Adding
android:configChanges="keyboardHidden|orientation"
for that activity
seems to fix the problem and then you put device to sleep only onPause() called vs before - all lifecycle methods were executed.
I'll do more testing to make sure it fixed...