且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

videoview 可以播放存储在内部存储器上的视频吗?

更新时间:2023-01-30 16:27:58

MediaPlayer 要求正在播放的文件具有全局可读权限.可以在 adb shell 中使用以下命令查看文件的权限:

ls -al/data/data/com.mypackage/myfile

您可能会看到-rw------",这意味着只有所有者(您的应用,而不是 MediaPlayer)具有读/写权限.

注意:您的手机必须root才能使用ls命令而不指定文件(在内存中).

如果您的手机已root,您可以使用以下命令在adb shell中添加全局读取权限:

chmod o+r/data/data/com.mypackage/myfile

如果您需要以编程方式修改这些权限(需要root手机!),您可以在您的应用代码中使用以下命令:

Runtime.getRuntime().exec("chmod o+r/data/data/com.mypackage/myfile");

这基本上是一个 linux 命令.有关 chmod 的更多信息,请参阅 https://help.ubuntu.com/community/FilePermissions.>

找到另一种简单的方法 here(对于没有root手机的人很有用).由于应用程序拥有该文件,它可以创建一个文件描述符并将其传递给 mediaPlayer.setDataSource():

FileInputStream fileInputStream = new FileInputStream("/data/data/com.mypackage/myfile");mediaPlayer.setDataSource(fileInputStream.getFD());

这种方法完全避免了权限问题.

I'm trying to provide my users with the ability to use either external or internal storage. I'm displaying both images and videos (of a scientific nature). When storing the media on the SD card, all is fine. But when I store the media internally, only the images will display. No matter what I try I get various errors when trying to load and display the media stored under the applicationcontext.getFilesDir().

Is there a trick to setting a videoview's content to such a file?

Can a ContentResolver help me?

On a related note, is it considered bad form to assume that external storage exists?

Thanks in advance,

Sid

Below is one version that fails with "Cannot play video. Sorry, this video cannot be played". But I have many other modes of failure. I can copy the internal video to temp storage (external) and play it, so this copy to internal does indeed create a valid movie. It only fails when I try to play it directly from the internal storage.

videoFile = new File(this.getFilesDir() + File.separator + "test.mp4");


InputStream data = res.openRawResource(R.raw.moviegood);


try {
    OutputStream myOutputStream = new FileOutputStream(videoFile);


    byte[] buffer = new byte[8192];
    int length;
    while ( (length = data.read(buffer)) > 0 ) {
        myOutputStream.write(buffer);
    }

    //Close the streams
    myOutputStream.flush();
    myOutputStream.close();
    data.close();
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}




vview.setKeepScreenOn(true);
vview.setVideoPath(videoFile.getAbsolutePath());
vview.start();

MediaPlayer requires that the file being played has world-readable permissions. You can view the permissions of the file with the following command in adb shell:

ls -al /data/data/com.mypackage/myfile

You will probably see "-rw------", which means that only the owner (your app, not MediaPlayer) has read/write permissions.

Note: Your phone must be rooted in order to use the ls command without specifying the file (in the internal memory).

If your phone is rooted, you can add world-read permissions in adb shell with the following command:

chmod o+r /data/data/com.mypackage/myfile

If you need to modify these permissions programmatically (requires rooted phone!), you can use the following command in your app code:

Runtime.getRuntime().exec("chmod o+r /data/data/com.mypackage/myfile");

Which is basically a linux command. See https://help.ubuntu.com/community/FilePermissions for more on chmod.

EDIT: Found another simple approach here (useful for those without rooted phones). Since the application owns the file, it can create a file descriptor and pass that to mediaPlayer.setDataSource():

FileInputStream fileInputStream = new FileInputStream("/data/data/com.mypackage/myfile");
mediaPlayer.setDataSource(fileInputStream.getFD());

This approach avoids the permission issue completely.