MediaMetadataRetriever FileNotFoundException

Я создаю приложение, в котором вы сначала можете выбрать видео с телефона, а затем видео дважды показывается в другом действии. То есть одно и то же видео отображается в левой и правой половине экрана. Что я сделал до сих пор: в первом действии у пользователя есть кнопка для выбора видео:

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

Затем, когда он выбран, запускается второе действие, передавая uri выбранному видео:

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

Проблема возникает из-за того, как я хочу, чтобы видео воспроизводились. Когда экран находится в альбомной ориентации, я хочу, чтобы видео в левой половине экрана занимало всю высоту экрана и было обрезано по центру в его половине, сохраняя соотношение сторон. Вот что я пробовал:

Сначала я восстанавливаю uri и получаю размеры его контейнера, занимающего всю левую половину экрана, в 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);
        }
    });

И, как вы можете видеть, setDimension вызывается для установки размера 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();
}

Проблема возникает, когда я вызываю getVideoProportion(), который должен получить "aspectRatio" (высота/ширина) видео:

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

Поскольку эта строка retriever.setDataSource(uri.getPath()); выдает исключение FileNotFoundException, что странно, потому что если я вызову

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

Видео воспроизводится, так что проблема не в том, что файла нет. uri.getPath() имеет следующую форму: /-1/2/content://media/external/video/media/6685/ORIGINAL/NONE/1567971923


person JOSEMAFUEN    schedule 01.02.2018    source источник


Ответы (1)


setDataSource()ожидает путь к файловой системе. Вы получили схему контента от Intent.ACTION_PiCK. Вы можете проверить сами, что uri.getPath() дает несуществующий путь к файловой системе. Вы должны использовать uri.toString(). Цену тоже скажи. Но это тоже не будет принято, так как это схема содержания.

person greenapps    schedule 01.02.2018