cordova-plugin-media-capture icon indicating copy to clipboard operation
cordova-plugin-media-capture copied to clipboard

Add the ability to specify where the capture should be saved

Open ataylor32 opened this issue 4 years ago • 8 comments

Feature Request

Motivation Behind Feature

For some apps, it is undesirable to have captured media visible in the user's standard photo/video viewing app (or any other app, for that matter). In these cases, the app's captured media should be isolated to the app (i.e. the captured media should be stored somewhere that's not visible to other apps).

Some developers have tried getting around this by moving the captured media, but have run into a problem (see issue #133).

In addition, some developers are having trouble accessing captured media (see issues #103 #135 #196).

If I'm understanding correctly, this change would also be important for Android 11 (see Google's "Storage updates in Android 11" article).

Feature Description

CaptureAudioOptions, CaptureImageOptions, and CaptureVideoOptions could all have a new property for specifying where the capture should be saved.

Alternatives or Workarounds

I don't know of any reliable alternatives or workarounds.

ataylor32 avatar Feb 17 '21 17:02 ataylor32

Hi @ataylor32 , you are right. Since the storage update on Android 11, the app will not be able to access the media file that is saved into external storage by the plugin (using native camera app). The idea for this is to use a ContentProvider (a FileProvider, in this case) as a common database to save files, so that both our app and other apps can get access to. I already implemented this for the captureVideo method, and it works well. Please assign this issue to me, I will create a PR as soon as I finish updating captureAudio and captureImage methods.

chriskhongqarma avatar Apr 12 '21 13:04 chriskhongqarma

Thank you @chriskhongqarma I'm looking forward in seeing that PR. I wonder if it's something easily replicatable to the file plugin and the camera plugin?

breautek avatar Apr 12 '21 13:04 breautek

@breautek You are right, the camera plugin is also using FileProvider, so it is a very good reference.

chriskhongqarma avatar Apr 12 '21 13:04 chriskhongqarma

@breautek @chriskhongqarma

when recording a video with

window.navigator.device.capture.captureVideo(_onCaptureVideoSuccess, _onCaptureVideoError, options);

on Android < 11, I get the file path in the callback like so: fullPath: "file:///storage/emulated/0/DCIM/Camera/VID_20210426_181817.mp4" and I can correctly access it.

on Android 11, I get: fullPath: "file:///data/user/0/{app_id}/cache/Capture.avi" But if I navigate there with a root explorer, there is not any Capture.avi file, and trying to access it via code will give me an error 1 (NOT FOUND), of course.

I am using the flag android:requestLegacyExternalStorage="true"

Am I missing something? Any suggestions?

mirko77 avatar Apr 26 '21 17:04 mirko77

Cordova does not support API 30 yet.

I am using the flag android:requestLegacyExternalStorage="true"

This flag only works on API 29, it's ignored on API >= 30. Therefore for the time being, It's recommended that you use this flag while targeting API 29 and the filesystem should work provided that the user has granted you the permission to read external files.

breautek avatar Apr 26 '21 17:04 breautek

@breautek I am not targeting api 30 yet

  <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" />

mirko77 avatar Apr 26 '21 17:04 mirko77

@breautek all good, apparently it is an issue with custom ROMs only.

mirko77 avatar Apr 29 '21 13:04 mirko77

@breautek @chriskhongqarma

when recording a video with

window.navigator.device.capture.captureVideo(_onCaptureVideoSuccess, _onCaptureVideoError, options);

on Android < 11, I get the file path in the callback like so: fullPath: "file:///storage/emulated/0/DCIM/Camera/VID_20210426_181817.mp4" and I can correctly access it.

on Android 11, I get: fullPath: "file:///data/user/0/{app_id}/cache/Capture.avi" But if I navigate there with a root explorer, there is not any Capture.avi file, and trying to access it via code will give me an error 1 (NOT FOUND), of course.

I am using the flag android:requestLegacyExternalStorage="true"

Am I missing something? Any suggestions?

Source code for video capture fallbacks to this stange(?) path to Capture.avi when the video uri could not be resolved from intent.getData() (see Capture.java#L425) - while this is the proper way to do it (see https://developer.android.com/training/camera/videobasics#TaskVideoView) 🤷

It was introduced years ago in #13 ... but really no idea why such a file would be written in this directory 🤔 (no EXTRA_OUTPUT or so defined) ... if ever it is useful, a check with file.exists() may be necessary??

ath0mas avatar Nov 05 '21 23:11 ath0mas