簡體   English   中英

在 Android 10 上將視頻保存並插入到圖庫

[英]Save and Insert video to gallery on Android 10

我正在嘗試將視頻保存到圖庫,以下代碼適用於除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();

我使用第 3 方庫來錄制SurfaceView ,這個庫需要一個路徑來保存錄制的視頻:

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

錄制視頻完成后,錄制的視頻以給定的路徑savedVideoPath保存,除Android Q外,所有 android 版本一切正常

保存視頻后,當我檢查時,我在圖庫中得到一個空視頻

在此處輸入圖片說明

我已經在你的另一篇文章中回答了你......你需要一個輸入流(文件、位圖等)並從輸入文件中寫入一個輸出流。

您必須更改庫才能使其與 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);

我想創建一個使用它的路徑

您正在從MediaStore獲取Uri 沒有“路徑”。 不僅不能將Uri轉換為路徑,而且您在 Android 10 及更高版本上無法訪問該位置的文件系統。

擺脫這個:

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

因為它不會工作。

將其替換為您的代碼,以將您的視頻寫入Uri標識的位置。 使用resolver.openOutputStream()獲取到該位置的OutputStream 特別是,0IS_PENDING調用resolver.update()之前執行此操作,因為這特別說明“我已完成對Uri寫入;您現在可以使用該內容”。

或者,你可以使用,如文件系統位置使用一個getExternalFilesDir()Context ,並擺脫MediaStore東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM