java - 在 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();
我使用一个第三方库来录制SurfaceView
,这个库需要一个路径来保存录制的视频:
mRenderPipeline = EZFilter.input(this.effectBmp)
.addFilter(new GalleryEffects().getEffect(VideoMaker.this, i))
.enableRecord(savedVideoPath, true, false)
.into(mRenderView);
录制视频完成后,录制的视频以给定的路径保存,除Android QsavedVideoPath
之外的所有 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);