在Android 10上将视频保存并插入图库

时间:2019-09-13 12:04:45

标签: java android mediastore android-mediascanner android-10.0

我正在尝试将视频保存到图库中,以下代码在除 Android Q 以外的所有Android版本上都能正常运行:

private void getPath() {
        String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        ContentResolver resolver = getContentResolver();
        ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, videoFileName);
        contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
        contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, "Movies/" + "Folder");
        contentValues.put(MediaStore.Video.Media.IS_PENDING, 1);
        Uri collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
        Uri videoUri = resolver.insert(collection, contentValues);
        if (videoUri != null) {
            try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(videoUri, "w", null)) {
                OutputStream outputStream = null;
                if (pfd != null) {
                    outputStream = resolver.openOutputStream(videoUri);
                    outputStream.flush();
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        contentValues.clear();
        contentValues.put(MediaStore.Video.Media.IS_PENDING, 0);
        if (videoUri != null) {
            resolver.update(videoUri, contentValues, null, null);
        }
        } else {
            File storageDir = new File(
                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)
                            + "/Folder");
            boolean success = true;
            if (!storageDir.exists()) {
                success = storageDir.mkdirs();
            }
            if (success) {
                File videoFile = new File(storageDir, videoFileName);
                savedVideoPath = videoFile.getAbsolutePath();
            }
        }
    }

我也尝试使用get getExternalFilesDir(),但是不起作用,画廊中没有创建视频

String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            File imageFile = null;
            File storageDir = new File(getExternalFilesDir(Environment.DIRECTORY_DCIM),
                    "Folder");
            boolean success = true;
            if (!storageDir.exists()) {
                success = storageDir.mkdirs();
            }
            if (success) {
                imageFile = new File(storageDir, videoFileName);
            }
            savedVideoPath = imageFile.getAbsolutePath();

我使用一个第三方库来录制SurfaceView,该库需要一个路径来保存录制的视频:

 mRenderPipeline = EZFilter.input(this.effectBmp)
                    .addFilter(new GalleryEffects().getEffect(VideoMaker.this, i))
                    .enableRecord(savedVideoPath, true, false)
                    .into(mRenderView);

录制视频完成后,录制的视频将以给定路径savedVideoPath保存,除了 Android Q

之外,所有版本在所有Android版本上都可以正常运行

保存视频后,当我检查时,我在图库中看到一个空视频

enter image description here

2 个答案:

答案 0 :(得分:2)

  

我想创建一个使用它的路径

您从Uri获得了MediaStore。没有“路径”。不仅无法将Uri转换为路径,而且您无法在Android 10及更高版本上访问该位置的文件系统。

摆脱这个:

        if (videoUri != null) {
            savedVideoPath = getRealPathFromURI(videoUri);
        }

因为它不起作用。

将其替换为代码,以将视频写到Uri所标识的位置。使用resolver.openOutputStream()OutputStream移至该位置。特别是,请在您致电resolver.update()IS_PENDING的{​​{1}}之前进行,因为这特别说明“我已经写完0 ;您可以立即使用内容。”

或者,使用您可以访问的文件系统位置之一,例如Uri上的getExternalFilesDir(),摆脱掉Context的东西

答案 1 :(得分:1)

我已经回答了您的其他帖子,以便...您需要输入流(文件,位图等),并从输入文件写入输出流。

您必须更改库才能使其与Android Q一起使用。如果无法执行此操作,则可以将视频复制到媒体库,然后删除在getExternalFilesDir()中创建的旧视频。之后,您就拥有了视频的uri,可以使用uri做您想做的事情

如果使用getExternalFilesDir()保存了视频,则可以在这里使用我的示例:获得的媒体uri是“ uriSavedVideo”。这仅仅是一个例子。大型视频也应在后台复制。

String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";

    ContentValues valuesvideos;
    valuesvideos = new ContentValues();
    valuesvideos.put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/" + "Folder");
    valuesvideos.put(MediaStore.Video.Media.TITLE, videoFileName);
    valuesvideos.put(MediaStore.Video.Media.DISPLAY_NAME, videoFileName);
    valuesvideos.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
    valuesvideos.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
    valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
    valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1);
    ContentResolver resolver = mContext.getContentResolver();
    Uri collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
    Uri uriSavedVideo = resolver.insert(collection, valuesvideos);


    ParcelFileDescriptor pfd;

    try {
        pfd = mContext.getContentResolver().openFileDescriptor(uriSavedVideo, "w");

        FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());

// Get the already saved video as fileinputstream from here
        File storageDir = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_MOVIES), "Folder");
        File imageFile = new File(storageDir, "Myvideo");

        FileInputStream in = new FileInputStream(imageFile);


        byte[] buf = new byte[8192];
        int len;
        while ((len = in.read(buf)) > 0) {

            out.write(buf, 0, len);
        }


            out.close();
        in.close();
        pfd.close();




    } catch (Exception e) {

        e.printStackTrace();
    }


    valuesvideos.clear();
    valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 0);
    mContext.getContentResolver().update(uriSavedVideo, valuesvideos, null, null);