Can a videoview play a video stored on internal storage?

前端 未结 6 1472
一向
一向 2020-11-29 04:12

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 th

相关标签:
6条回答
  • 2020-11-29 04:30

    You can use:

    videoView.setVideoURI(Uri.parse(file.getAbsolutePath()));
    

    if the file is world readable

    Or you can use a content provider

    0 讨论(0)
  • 2020-11-29 04:33

    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.

    0 讨论(0)
  • 2020-11-29 04:35

    I came across this thread with the same problem, I'm downloading my videos from the web to the internal storage, turns out when saving you can specify the RW mode, i.e change from PRIVATE to WORLD_READABLE

    URL url = new URL(_url);
    InputStream input = null;
    FileOutputStream output = null;
    
    try {
    String outputName = "video.mp4";
    
    input = url.openConnection().getInputStream();
    output = c.openFileOutput(outputName, Context.MODE_WORLD_READABLE);
    
    int read;
    byte[] data = new byte[5120]; //5MB byte array
    while ((read = input.read(data)) != -1)
    output.write(data, 0, read);
    
    return true;
    
    } finally {
    if (output != null)
       output.close();
    if (input != null)
       input.close();
        }
    }
    
    0 讨论(0)
  • 2020-11-29 04:37

    For detail check this tutorial

    public class AndroidVideoViewExample extends Activity {
    
        private VideoView myVideoView;
        private int position = 0;
        private ProgressDialog progressDialog;
        private MediaController mediaControls;
    
        @Override
        protected void onCreate(final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // set the main layout of the activity
            setContentView(R.layout.activity_main);
    
            //set the media controller buttons
            if (mediaControls == null) {
                mediaControls = new MediaController(AndroidVideoViewExample.this);
            }
    
            //initialize the VideoView
            myVideoView = (VideoView) findViewById(R.id.video_view);
    
            // create a progress bar while the video file is loading
            progressDialog = new ProgressDialog(AndroidVideoViewExample.this);
            // set a title for the progress bar
            progressDialog.setTitle("JavaCodeGeeks Android Video View Example");
            // set a message for the progress bar
            progressDialog.setMessage("Loading...");
            //set the progress bar not cancelable on users' touch
            progressDialog.setCancelable(false);
            // show the progress bar
            progressDialog.show();
    
            try {
                //set the media controller in the VideoView
                myVideoView.setMediaController(mediaControls);
    
                //set the uri of the video to be played
                myVideoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.kitkat));
    
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
    
            myVideoView.requestFocus();
            //we also set an setOnPreparedListener in order to know when the video file is ready for playback
            myVideoView.setOnPreparedListener(new OnPreparedListener() {
    
                public void onPrepared(MediaPlayer mediaPlayer) {
                    // close the progress bar and play the video
                    progressDialog.dismiss();
                    //if we have a position on savedInstanceState, the video playback should start from here
                    myVideoView.seekTo(position);
                    if (position == 0) {
                        myVideoView.start();
                    } else {
                        //if we come from a resumed activity, video playback will be paused
                        myVideoView.pause();
                    }
                }
            });
    
        }
    
        @Override
        public void onSaveInstanceState(Bundle savedInstanceState) {
            super.onSaveInstanceState(savedInstanceState);
            //we use onSaveInstanceState in order to store the video playback position for orientation change
            savedInstanceState.putInt("Position", myVideoView.getCurrentPosition());
            myVideoView.pause();
        }
    
        @Override
        public void onRestoreInstanceState(Bundle savedInstanceState) {
            super.onRestoreInstanceState(savedInstanceState);
            //we use onRestoreInstanceState in order to play the video playback from the stored position 
            position = savedInstanceState.getInt("Position");
            myVideoView.seekTo(position);
        }
    }
    
    0 讨论(0)
  • 2020-11-29 04:45

    I posted a custom VideoView implementation there.

    The VideoView implementation has the setVideoFD(FileDescriptor fd) method and solves this issue.

    0 讨论(0)
  • 2020-11-29 04:50

    You can't just play it directly.

    You need to implement a ContentProvider then pass the defined Uri to setVideoUri(uri) method.

    0 讨论(0)
提交回复
热议问题