安卓的MediaPlayer / VideoView错误(1,-2147483648) [英] Android MediaPlayer/VideoView error (1, -2147483648)

查看:337
本文介绍了安卓的MediaPlayer / VideoView错误(1,-2147483648)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直有与文件路径设置VideoView的视频不一致的体验。

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是一个视频在我的缓存目录的绝对路径:

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

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

在Android SDK中> = 16(果冻豆),这工作得很好,我真棒视频播放。在安卓4.0.4(SDK = 15),在MediaPlayer休息时myVideoView.start()被调用。

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.

的错误是不断无益的:

error (1, -2147483648)

我在想什么吗?直接从我的资产包(RES / RAW)或互联网(<加载一个文件href="http://something.com/myawesomeinternetvideo.mp4">http://something.com/myawesomeinternetvideo.mp4),但我不知道如何读文件了我的缓存目录!

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!

推荐答案

事实证明,错误-2147483648表示未知错误。这可能是与视频编码,但它也值得检查该文件路径存在的,而且VideoView有权阅读

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.

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

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.

解决方案之一是与<​​一写你的文件href="http://developer.android.com/reference/android/content/Context.html#MODE_WORLD_READABLE">Context.MODE_WORLD_READABLE,这是现在去precated。这表明,任何人都可以在这条道路打开该文件。这显然​​是不安全的,不建议采用。

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.

我结束了创建一个内容提供商和我自己的URI来处理这种情况。具体做法是:

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

这是告诉VideoView要问您的ContentProvider的文件描述符的数据的真正啰嗦的方式。文件描述符不许可管理,让您使用您的应用程序的权限和它交给了VideoView而不是要求VideoView利用自己的权限来打开文件打开该文件。

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!

这篇关于安卓的MediaPlayer / VideoView错误(1,-2147483648)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆