Android MediaPlayer / VideoView错误(1,-2147483648)

我一直在从文件path设置VideoView的video不一致的经验。

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

videoFilename是我的caching目录中video的绝对path:

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

在Android SDK> = 16(果冻豆),这工作得很好,我真棒video播放。 在Android 4.0.4(SDK = 15)中,当调用myVideoView.start()时,MediaPlayer中断。

错误是永远无益的:

 error (1, -2147483648) 

我在这里错过了什么? 直接从我的软件包资源(res / raw)或互联网( http://something.com/myawesomeinternetvideo.mp4 )加载文件,但我不知道如何从我的caching目录中读取文件!

Solutions Collecting From Web of "Android MediaPlayer / VideoView错误(1,-2147483648)"

事实certificate,错误-2147483648表明一个未知的错误。 这可能与video编码有关,但也值得检查文件path是否存在,以及VideoView是否具有读取权限

我的问题是,我用Context.MODE_PRIVATE(默认)写我的文件。

 openFileOutput(filename, Context.MODE_PRIVATE); 

这表明只有您的应用程序可以访问该文件。 我不知道具体如何或为什么,但在Jelly Bean及以上版本中,video视图允许访问您指定的文件,就像它是您的应用程序,但在Jelly Bean之前,video视图尝试打开文件在它自己的上下文中(而不是你的应用程序的)。 由于该模式是私人的,因此失败。

一种解决方法是用Context.MODE_WORLD_READABLE写入文件,现在已经废弃了。 这表示任何人都可以在该path上打开文件。 这显然是不安全的,也是令人沮丧的。

我最终创build了一个内容提供者和我自己的URI来处理这种情况。 特别:

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(); } } 

然后,我在哪里访问我的video文件:

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

这是一个非常冗长的方式告诉VideoView询问您的ContentProvider文件描述符的数据。 文件描述符没有权限,因此您可以使用应用程序的权限打开该文件,并将其交给VideoView,而不是让VideoView使用自己的权限打开该文件。

这解决了我的问题,希望你也是!

从caching目录加载video文件时,我也遇到了这个问题。 这个问题似乎只发生在Nexus设备上,但我没有在很多设备上进行testing。

我试图用Context.MODE_WORLD_READABLE来写这个文件,但是这个修复对我来说不起作用。 VideoProvider.java也没有修复它。

所以我find了一个适合我的解决scheme。 我在我的Activity中创build了一个tempFile,并为VideoView提供了绝对path。

也许我的代码可以帮助别人:)

  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)); } }