To record a SurfeceView
I'm using a 3rd-party library , this library requires a path where the output (the recorded video) saved in my case is savedVideoPath :
mRenderPipeline = EZFilter.input(this.effectBmp)
.addFilter(new Effects().getEffect(VideoMaker.this, i))
.enableRecord(savedVideoPath, true, false)
.into(mRenderView);
After the recording stopped, the video should be saved with savedVideoPath as a path, when I test the code, that is to say , when I open the gallery app, I see the saved video there, but when I tested on Android Q, I can't see anything.
Since getExternalStoragePublicDirectory
and getExternalStorageDirectory
are deprecated ,I tried to use getExternalFilesDir
as following :
private void getPath() {
String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
fileName = videoFileName;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
File imageFile = null;
File storageDir = new File(
getExternalFilesDir(Environment.DIRECTORY_MOVIES),
"Folder");
source = storageDir;
boolean success = true;
if (!storageDir.exists()) {
success = storageDir.mkdirs();
}
if (success) {
imageFile = new File(storageDir, videoFileName);
savedVideoPath = imageFile.getAbsolutePath();
}
} 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();
}
}
}
After the recording stopped, I go to Files Explorer app > Android > data > com.packageName > files > Movies > Folder ,I can see all saved videos there,but I can't see them on the gallery.
I tried to use Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
to refresh the gallery, but unfortunately doesn't work.
I also tried MediaScannerConnection
:
MediaScannerConnection.scanFile(
context,
new String[]{savedVideoPath},
new String[]{"video/mp4"},
new MediaScannerConnection.MediaScannerConnectionClient() {
public void onMediaScannerConnected() {
}
public void onScanCompleted(String s, Uri uri) {
}
});
Method 1. Save YouTube Videos to Gallery with an App You can download YouTube videos to the gallery by using some video downloader apps, be computer-based or mobile-based. Each type of app has its pros and cons. Personally, we recommend using computer-based apps. Here are the reasons why you should do that.
Step 1. Open the InShot app and tap on the option that says "Video" to start a video project. Step 2. Tap on "New" and choose the video you want to add a picture to. Step 3. Tap on the "+" (plus) sign at the bottom-left corner and select the option that says "Video/Photo".
2.How to download youtube videos and save them into the phone gallery using Ins Tube. InsTube is one of the best easy, fast and free apps which is used to download youtube video and save into the phone gallery. it is used to download the videos from other sites also. step.1: Install the InsTube app on your Android phone from the InsTube website.
Open the YouCut app on your phone, tap on the "+" (plus) sign, and choose your video. Step 2. Tap on the "+" (plus) sign at the lower-left corner, and it will let you select the picture you want to add to your video.
You have to change the library to make it work with Android Q. If you cannot do this you could copy the video to the media gallery and then delete the old video created in getExternalFilesDir()
. After this you have the URI of the video and can do what you want with the URI.
If you have saved the video with getExternalFilesDir()
you could use my example here: The media URI you get is "uriSavedVideo". This is only an example. A large video should also be copied in the background.
Uri uriSavedVideo;
File createdvideo = null;
ContentResolver resolver = getContentResolver();
String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
ContentValues valuesvideos;
valuesvideos = new ContentValues();
if (Build.VERSION.SDK_INT >= 29) {
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);
Uri collection =
MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
uriSavedVideo = resolver.insert(collection, valuesvideos);
} else {
String directory = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + Environment.DIRECTORY_MOVIES + "/" + "YourFolder";
createdvideo = new File(directory, videoFileName);
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.DATA, createdvideo.getAbsolutePath());
uriSavedVideo = getContentResolver().insert(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
valuesvideos);
}
if (Build.VERSION.SDK_INT >= 29) {
valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1);
}
ParcelFileDescriptor pfd;
try {
pfd = getContentResolver().openFileDescriptor(uriSavedVideo, "w");
FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());
// get the already saved video as fileinputstream
// The Directory where your file is saved
File storageDir = new File(
getExternalFilesDir(Environment.DIRECTORY_MOVIES),
"Folder");
//Directory and the name of your video file to copy
File videoFile = new File(storageDir, "Myvideo");
FileInputStream in = new FileInputStream(videoFile);
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();
}
if (Build.VERSION.SDK_INT >= 29) {
valuesvideos.clear();
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 0);
getContentResolver().update(uriSavedVideo, valuesvideos, null, null);
}
Here it is my solution - save photo/video to Gallery.
private fun saveMediaFile2(filePath: String?, isVideo: Boolean, fileName: String) {
filePath?.let {
val context = MyApp.applicationContext
val values = ContentValues().apply {
val folderName = if (isVideo) {
Environment.DIRECTORY_MOVIES
} else {
Environment.DIRECTORY_PICTURES
}
put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
put(MediaStore.Images.Media.MIME_TYPE, MimeUtils.guessMimeTypeFromExtension(getExtension(fileName)))
put(MediaStore.Images.Media.RELATIVE_PATH, folderName + "/${context.getString(R.string.app_name)}/")
put(MediaStore.Images.Media.IS_PENDING, 1)
}
val collection = if (isVideo) {
MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
} else {
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
}
val fileUri = context.contentResolver.insert(collection, values)
fileUri?.let {
if (isVideo) {
context.contentResolver.openFileDescriptor(fileUri, "w").use { descriptor ->
descriptor?.let {
FileOutputStream(descriptor.fileDescriptor).use { out ->
val videoFile = File(filePath)
FileInputStream(videoFile).use { inputStream ->
val buf = ByteArray(8192)
while (true) {
val sz = inputStream.read(buf)
if (sz <= 0) break
out.write(buf, 0, sz)
}
}
}
}
}
} else {
context.contentResolver.openOutputStream(fileUri).use { out ->
val bmOptions = BitmapFactory.Options()
val bmp = BitmapFactory.decodeFile(filePath, bmOptions)
bmp.compress(Bitmap.CompressFormat.JPEG, 90, out)
bmp.recycle()
}
}
values.clear()
values.put(if (isVideo) MediaStore.Video.Media.IS_PENDING else MediaStore.Images.Media.IS_PENDING, 0)
context.contentResolver.update(fileUri, values, null, null)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With