Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android MediaPlayer/VideoView error (1, -2147483648)

Tags:

I've been having an inconsistent experience with setting a VideoView's video from a file path.

VideoView myVideoView = findViewById(R.id.videoView); ... myVideoView.setVideoPath(videoFilename); ... myVideoView.start(); 

videoFilename is the absolute path of a video in my cache directory:

String videoFilename = new File(context.getCacheDir(), "myawesomevideo.mp4").getAbsolutePath(); 

In Android SDK >= 16 (Jelly Bean), this works just fine and my awesome video plays. In Android 4.0.4 (SDK = 15), the MediaPlayer breaks when myVideoView.start() is called.

The error is the ever-unhelpful:

error (1, -2147483648) 

What am I missing here? Loading a file directly from my package assets (res/raw) or the internet (http://something.com/myawesomeinternetvideo.mp4), but I can't figure out how to read files out of my cache directory!

like image 946
spitzanator Avatar asked Sep 16 '13 17:09

spitzanator


People also ask

What is MediaPlayer in Android?

android.media.MediaPlayer. MediaPlayer class can be used to control playback of audio/video files and streams. MediaPlayer is not thread-safe. Creation of and all access to player instances should be on the same thread. If registering callbacks, the thread must have a Looper.

How to set MediaController with VideoView in Android?

Just define the MediaController object in on create and then add the view to that otherwise the error will like adding a view in a null object reference......

What is the use of VideoView Create simple application which run video from gallery?

Introducing the Android VideoView Class. By far the simplest way to display video within an Android application is to use the VideoView class. This is a visual component which, when added to the layout of an activity, provides a surface onto which a video may be played.

What are the most common Android media player errors?

Android Media Player: Start called in state 4 error(-38,0) 11 Android MediaPlayer java.io.IOException: Prepare failed.: status=0x1 14 Can't stream videos 3 cant play raw video in android studio using java 4 Android media player error (1, -2147483648) 3 Android VideoView plays video only once 2 Android 7 MediaPlayer Error (1,-2147483648)

Does mediaplayer work with Android SDK 16 (Jelly Bean)?

In Android SDK >= 16 (Jelly Bean), this works just fine and my awesome video plays. In Android 4.0.4 (SDK = 15), the MediaPlayer breaks when myVideoView.start () is called. What am I missing here?

Why does the videoview ask the contentprovider for a file descriptor?

This is a really long-winded way of telling the VideoView to ask your ContentProvider for the file descriptor to the data. File descriptors aren't permissioned, so you open the file using your app's permissions and hand it off to the VideoView rather than asking the VideoView to open the file using its own permissions.


2 Answers

As it turns out, error -2147483648 indicates an unknown error. This could have something to do with the video encoding, but it's also worth checking that the file path exists and that the VideoView has permission to read it.

My issue was that I was writing my files with Context.MODE_PRIVATE (the default).

openFileOutput(filename, Context.MODE_PRIVATE); 

This indicates that only your application can access the file. I don't know specifically how or why, but in Jelly Bean and above, it appears that the video view is allowed to access the file you specify as if it were your application, but before Jelly Bean, the video view tries to open the file in its own context (not your application's). Since the mode is private, it fails.

One solution is to write your file with Context.MODE_WORLD_READABLE, which is now deprecated. This indicates that anyone can open the file at that path. This is obviously unsafe and discouraged.

I ended up creating a content provider and my own URI to handle this case. Specifically:

AndroidManfest.xml:

...     <provider         android:name="com.myexampleapp.video.VideoProvider"             android:authorities="com.myexampleapp.video.VideoProvider.files"         android:exported="false" />     </application> </manifest> 

VideoProvider.java:

package com.myexampleapp.video;  import java.io.File; import java.io.FileNotFoundException;  import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.ParcelFileDescriptor;  public class VideoProvider extends ContentProvider {      public static final Uri CONTENT_URI_BASE =             Uri.parse("content://com.myexampleapp.video.VideoProvider.files.files/");      private static final String VIDEO_MIME_TYPE = "video/mp4";      @Override     public boolean onCreate() {         return true;     }      @Override     public String getType(final Uri uri) {         return VIDEO_MIME_TYPE;     }      @Override     public ParcelFileDescriptor openFile(final Uri uri, final String mode)             throws FileNotFoundException {         File f = new File(uri.getPath());          if (f.exists())             return (ParcelFileDescriptor.open(f,                     ParcelFileDescriptor.MODE_READ_ONLY));          throw new FileNotFoundException(uri.getPath());     }      @Override     public int delete(final Uri uri, final String selection, final String[] selectionArgs) {         throw new UnsupportedOperationException();     }      @Override     public Uri insert(final Uri uri, final ContentValues values) {         throw new UnsupportedOperationException();     }      @Override     public Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) {         throw new UnsupportedOperationException();     }      @Override     public int update(final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) {         throw new UnsupportedOperationException();     } } 

And then, where I access my video files:

VideoView myVideoView = findViewById(R.id.videoView); ... myVideoView.setVideoURI(     Uri.parse(         CachedActionProvider.CONTENT_URI_BASE + Uri.encode(videoFilename))); ... myVideoView.start(); 

This is a really long-winded way of telling the VideoView to ask your ContentProvider for the file descriptor to the data. File descriptors aren't permissioned, so you open the file using your app's permissions and hand it off to the VideoView rather than asking the VideoView to open the file using its own permissions.

This fixes my issue and hopefully yours, too!

like image 108
spitzanator Avatar answered Oct 10 '22 23:10

spitzanator


I also had this problem while loading a video file from the cache-directory. The problem seemed to occure on Nexus-devices only but I coundn't test it on much devices.

I tried to write the file with Context.MODE_WORLD_READABLE but that fix didn't work for me. The VideoProvider.java also didn't fixed it.

So I found a other solution that worked for me. I created a tempFile in my Activity and gave the VideoView the absolut path to it.

Maybe my code can help someone :)

 private MediaController mController;  private VideoView mVideoView;  private File mTmpFile = null;  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_video);      init(); }  private void init() {     mProgressDialog = new ProgressDialog(this);      mVideoView = (VideoView) findViewById(R.id.surface_video);     mVideoView.requestFocus();     mController = new MediaController(this);     mVideoView.setMediaController(mController);      mVideoView.setOnPreparedListener(this);     mVideoView.setOnCompletionListener(this);     mVideoView.setOnErrorListener(this);      String url = getIntent().getExtras().getString(MainActivity.VIDEO_URL_EXTRA_KEY);     if (VideoLoaderTask.hasVideo(this, url)) {         url = getCacheDir().toString().concat("/" + VideoLoaderTask.VIDEO_DIR + "/").concat(url);         copyToTmpFile(url);         mVideoView.setVideoPath(mTmpFile.getAbsolutePath());     } else {         mVideoView.setVideoURI(Uri.parse(url));     }      mProgressDialog.show();     mVideoView.start(); }  @Override public void onDestroy() {     if (mTmpFile != null) {         mTmpFile.delete();     }     super.onDestroy(); }  private void copyToTmpFile(String url) {     File f = new File(url);     try {         mTmpFile = File.createTempFile("video", null);         mTmpFile.deleteOnExit();          FileInputStream is = new FileInputStream(f);         int size = is.available();         byte[] buffer = new byte[size];         is.read(buffer);         is.close();          FileOutputStream fos = new FileOutputStream(mTmpFile);         fos.write(buffer);         fos.close();     } catch (Exception e) {         mVideoView.setVideoURI(Uri.parse(url));     } } 
like image 41
Maik Peschutter Avatar answered Oct 10 '22 23:10

Maik Peschutter