1

I'm building an app in which you first can choose a video from the phone and then the video is shown twice in another activity. That is to say, the same video is shown at the left half and at the right half of the screen. What I've done this far: In the first activity, the user has a button to choose the video:

gallybutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(checkPermissionForReadExtertalStorage()) {
                    Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(i, 0);
                }
                else
                    requestPermissionForReadExtertalStorage();
            }
});

Then, when it's selected, the second activity is launched passing the uri to the selected video:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            Uri selectedMediaUri = data.getData();
            if(selectedMediaUri != null) {
                Intent i = new Intent();
                i.setClass(this, VideoActivity.class);
                i.putExtra("uri", selectedMediaUri.toString());
                startActivity(i);
            }
        }
    }

The problem appears due to the way I want the videos to be played. With the screen in landscape orientation, I want the video on the left half of the screen to fill the height of the screen and be center-cropped in its half mantaining the aspect ratio. Here's what I've tried:

First I recover the uri and get the dimensions of its container, which occupies all the left half of the screen, in the OnCreate:

String uriString = getIntent().getStringExtra("uri");
uri = Uri.parse(uriString);
final VideoView vv = findViewById(R.id.videoView);
final FrameLayout fl = findViewById(R.id.videoFrame);
    fl.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            setDimension(vv, fl.getWidth(), fl.getHeight());
            fl.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });

And, as you can see, setDimension is called to set the dimension of the videoView:

private void setDimension(VideoView videoView, int width, int height) {
    // Adjust the size of the video
    // so it fits on the screen
    float videoProportion = getVideoProportion();
    float screenProportion = (float) height / (float) width;
    android.view.ViewGroup.LayoutParams lp = videoView.getLayoutParams();

    if (videoProportion < screenProportion) {
        lp.height= height;
        lp.width = (int) ((float) height / videoProportion);
    } else {
        lp.width = width;
        lp.height = (int) ((float) width * videoProportion);
    }
    videoView.setLayoutParams(lp);

    videoView.setVideoURI(uri);
    videoView.start();
}

The problem comes when I call getVideoProportion() which has to get the "aspectRatio" (height/width) of the video:

private float getVideoProportion(){
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    retriever.setDataSource(uri.getPath());
    Bitmap bmp = retriever.getFrameAtTime();
    return (float)bmp.getHeight() / (float)bmp.getWidth();
}

Because this line retriever.setDataSource(uri.getPath()); throws an FileNotFoundException, which is weird because if I call

videoView.setVideoURI(uri);
videoView.start();

The video is played, so the problem is not that the file doesn't exist. The uri.getPath() has this form: /-1/2/content://media/external/video/media/6685/ORIGINAL/NONE/1567971923

Josemafuen
  • 682
  • 2
  • 16
  • 41

1 Answers1

0

setDataSource()expects a file system path. You obtained a content scheme from Intent.ACTION_PiCK. You could check yourself that uri.getPath() gives you a non existing file system path. You should use uri.toString(). Tell the value too. But that will not be accepted too as it is a content scheme.

greenapps
  • 11,154
  • 2
  • 16
  • 19