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

标签 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

最佳答案

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

您必须更改该库才能使其与 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);

关于java - 在 Android 10 上保存视频并将其插入图库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57923329/

相关文章:

android - RxAndroid : Manage events of interdependent objects

c# - Plugin.MediaManager.Forms:无法从Xamarin.Forms应用程序数据目录播放视频

java - 使用 Intent 相机时给图像命名

Android 使用 MediaStore

java - 遍历目录并获取 UnsupportedOperationException

java - 如何使用Java streams和reduce()获取Map的key和value的计算总和?

java - Java 中缀到后缀转换的括号错误检查

java - 使用 APPMK 创建 Android 杂志应用程序

android - 选项卡文本随 viewpager 消失

android - 分区存储 : how to delete multiple audio files via MediaStore?