1

我正在构建一个应用程序,您首先可以在其中从手机中选择一个视频,然后该视频在另一个活动中显示两次。也就是说,相同的视频显示在屏幕的左半边和右半边。到目前为止我所做的:在第一个活动中,用户有一个按钮来选择视频:

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

由于我希望播放视频的方式出现问题。屏幕处于横向时,我希望屏幕左半部分的视频填充屏幕的高度,并在其一半保持纵横比的情况下进行中心裁剪。这是我尝试过的:

首先,我在 OnCreate 中恢复 uri 并获取其容器的尺寸,该容器占据了屏幕的所有左半部分:

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

4

1 回答 1

0

setDataSource()需要一个文件系统路径。您从 Intent.ACTION_PiCK 获得了一个内容方案。您可以检查自己是否uri.getPath()为您提供了一个不存在的文件系统路径。你应该使用uri.toString(). 也告诉价值。但这也不会被接受,因为它是一个内容方案。

于 2018-02-01T13:43:51.720 回答