I have a problem that I tried to find a solution for a long time. My situation is this:
I have an application that downloads zipped videos and unpacks them in a private folder of the application and, more specifically, in a subfolder. For example, /data/data/my.app.package.name.here/files/assets/assets-955.
Inside this folder, the video is unpacked. The unpacking process was completed successfully, since I can pull and watch the video without problems when I run the application on the emulator.
Then I have another activity that accesses this folder, finds a video file and tries to open it. At this point, I get an "Sorry, this video cannot be played" error message with the following error stack:
01-30 17:36:17.770: D/ContentDemoActivity(6757): File: /data/data/xxxx/files/assets/assets-955/bank_2.mp4 01-30 17:36:17.830: I/MediaPlayer(6757): prepareAsync called in state 4 01-30 17:36:17.830: E/MediaPlayer(6757): error (1, -2147483648) 01-30 17:36:17.860: E/MediaPlayer(6757): Error (1,-2147483648) 01-30 17:36:17.860: D/VideoView(6757): Error: 1,-2147483648 01-30 17:36:19.370: E/MediaPlayer(6757): stop called in state 0 01-30 17:36:19.370: E/MediaPlayer(6757): error (-38, 0) 01-30 17:36:19.370: W/MediaPlayer(6757): mediaplayer went away with unhandled events
The code I'm trying to play the video with is pretty simple:
mView = (VideoView) findViewById(R.id.videoView); mMediaPlayer = new MediaPlayer(); mView.requestFocus(); mHolder = mView.getHolder(); Log.d(tag, "Populating content. Assets path: " + mAssetsPath); File f = new File(mAssetsPath); File[] files = f.listFiles(); Log.d(tag, "File: " + files[0].toString()); mView.setVideoURI(Uri.parse(files[0].toString())); mView.setMediaController(new MediaController(this));
and there’s a simple video viewer in the activity layout, nothing special.
The strangest thing is that for testing I used the same video, this time downloading it from the "raw" folder, and it works without problems. In this case, although I had to download it with:
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.bank_2); mVideoView.setVideoURI(video); mVideoView.start();
I would do the same with the downloaded videos, but there is no function in the API that will allow me to load Uri videos from the private folder of the application.
I found various solutions using file descriptors, listeners for video, flags indicating MODE_WORLD_READABLE, preliminary calculation of the sizes of the video viewer, etc., but none of them had positive results.
In short, my questions are:
- Why do I get errors that, in accordance with what I found on the Internet, are errors related to problematic encoding of a video file?
- What is best used in my case, VideoView or surfaceView?
- What is the ideal method for downloading video from a private folder of the application and the ability to play it?
Thanks.
EDIT
After the CommonsWare suggestion, I went with the following implementation:
File f = new File(mAssetsPath); File[] files = f.listFiles(); Log.d(tag, "File: " + files[0].toString()); URI uri = URI.create("file://" + (files[0].toString())); File file = new File(uri); try { Log.d(tag, "1"); ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE); Log.d(tag, "2"); mMediaPlayer.setDataSource(parcel.getFileDescriptor()); Log.d(tag, "3"); mMediaPlayer.start(); Log.d(tag, "4"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Log.d(tag, "5");
Unfortunately, this time I get the following errors:
01-31 12:40:11.480: D/ContentDemoActivity(15896): File: /data/data/com.houseofradon.meb/files/assets/assets-955/bank_2.mp4 01-31 12:40:11.480: D/ContentDemoActivity(15896): 1 01-31 12:40:11.480: D/ContentDemoActivity(15896): 2 01-31 12:40:11.500: D/ContentDemoActivity(15896): 3 01-31 12:40:11.500: E/MediaPlayer(15896): start called in state 2 01-31 12:40:11.500: E/MediaPlayer(15896): error (-38, 0) 01-31 12:40:11.500: D/ContentDemoActivity(15896): 4 01-31 12:40:11.500: D/ContentDemoActivity(15896): 5 01-31 12:40:11.530: E/MediaPlayer(15896): Error (-38,0)
So, something happens when the media player starts. The error code -38 does not seem to mean anything specific, as I found here .
Any idea what I am missing ???
EDIT # 2
Now I use mediaPlayer and SurfaceView to execute the whole process with the surfaceHolder listener. Here is the code:
mMediaPlayer = new MediaPlayer(); mSurfaceView = (SurfaceView) findViewById(R.id.surface); mHolder = mSurfaceView.getHolder(); mHolder.addCallback(this); public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d(tag, "surfaceChanged"); try { mMediaPlayer.setDisplay(mHolder); Log.d(tag, "7"); mMediaPlayer.start(); Log.d(tag, "8"); } catch (IllegalStateException e) { e.printStackTrace(); } Log.d(tag, "9"); } public void surfaceCreated(SurfaceHolder holder) { Log.d(tag, "surfaceCreated"); File f = new File(mAssetsPath); File[] files = f.listFiles(); Log.d(tag, "File: " + files[0].toString()); URI uri = URI.create("file://" + (files[0].toString())); File file = new File(uri); try { Log.d(tag, "1"); ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE); Log.d(tag, "2"); mMediaPlayer.setDataSource(parcel.getFileDescriptor()); Log.d(tag, "3"); mMediaPlayer.setVolume(100, 100); Log.d(tag, "4"); mMediaPlayer.prepare(); Log.d(tag, "5"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Log.d(tag, "6"); }
I can listen to audio video, but the image is just black. I also get an error almost at the end of the video playback, which says:
01-31 14:26:01.300: W/AudioSystem(17165): AudioFlinger server died! 01-31 14:26:01.300: W/IMediaDeathNotifier(17165): media server died 01-31 14:26:01.300: E/MediaPlayer(17165): error (100, 0) 01-31 14:26:01.300: E/MediaPlayer(17165): Error (100,0)
I am using the actual device, Samsung Galaxy Tab 10.1. Any ideas?