Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to specify where the capture should be saved #210

Open
ataylor32 opened this issue Feb 17, 2021 · 11 comments
Open

Add the ability to specify where the capture should be saved #210

ataylor32 opened this issue Feb 17, 2021 · 11 comments
Assignees
Milestone

Comments

@ataylor32
Copy link

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.

@chriskhongqarma
Copy link

chriskhongqarma commented Apr 12, 2021

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.

@breautek
Copy link
Contributor

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?

@chriskhongqarma
Copy link

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

@mirko77
Copy link

mirko77 commented Apr 26, 2021

@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?

@breautek
Copy link
Contributor

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.

@mirko77
Copy link

mirko77 commented Apr 26, 2021

@breautek I am not targeting api 30 yet

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

@mirko77
Copy link

mirko77 commented Apr 29, 2021

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

@ath0mas
Copy link
Contributor

ath0mas commented Nov 5, 2021

@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 added a commit to ath0mas/cordova-plugin-media-capture that referenced this issue Nov 6, 2021
ath0mas added a commit to ath0mas/cordova-plugin-media-capture that referenced this issue Jul 30, 2023
erisu pushed a commit that referenced this issue Aug 3, 2023
…File (#232)

* fix(android): standard way to get video uri from intent see #210, and follow doc https://developer.android.com/training/camera/videobasics#TaskVideoView
(removes partial changes done in #13 for old android and cordova versions)

* style(android): cleanup imports and remove unused method
* fix(android): prevent NPE with null checks on intent data and mediaFile
@breautek
Copy link
Contributor

breautek commented Dec 4, 2024

We are going to be taking the camera plugin approach. We won't provide an option of where the media should be stored. But the the media will be stored in a temporary location, and then the cordova-plugin-file APIs can be used to move it wherever.

Alternatively you can use a third-party plugin for file sharing/transfering assuming that plugin accepts file and/or content URIs.

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).

This is something we cannot guarantee. Currently images uses EXTRA_OUTPUT parameter, and we plan to expand that to video and audio as well in 6.0, and we will be using the app's private cache directory. Most applications that handles audio and video recording will respond to EXTRA_OUTPUT and exclusively store the media file at the provided location. However some applications may still store a copy into the user's gallery in addition to the EXTRA_OUTPUT location. This will vary by the underlying application handling the intent. Applications that saves a copy usually has a setting that the user can configure.

@breautek breautek added this to the 6.0.0 milestone Dec 4, 2024
@mirko77
Copy link

mirko77 commented Dec 4, 2024

@breautek

we will be using the app's private cache directory.

Could you confirm if this means explicitly forcing files to be saved in cordova.file.cacheDirectory? Based on our experience, we’ve found this directory to be unreliable on both Android and iOS. While documentation suggests it is suitable for temporary files, we’ve encountered numerous reports from thousands of users over the years indicating otherwise.

The issue manifests as code: 1 (file not found), often just moments after a file is saved. Unfortunately, despite extensive debugging, we’ve never been able to reproduce this issue ourselves. However, since we started using a custom cache folder within cordova.file.dataDirectory, we have not received a single such report.

We wanted to share this observation as it might be helpful for any implementation decision.

@breautek
Copy link
Contributor

breautek commented Dec 4, 2024

Could you confirm if this means explicitly forcing files to be saved in cordova.file.cacheDirectory?

Yes, that's the plan. I don't think we ever saw bug reports against the camera plugin, which have used the cache directory for quite some time now. The plan is to model this plugin after the camera plugin.

The issue manifests as code: 1 (file not found), often just moments after a file is saved. Unfortunately, despite extensive debugging, we’ve never been able to reproduce this issue ourselves.

It is strange, it sounds like the file is simply not flushed to disk. Perhaps it could be an issue more prominent if the app is stored on slower external storage like an sdcard (but if that were the case, I wouldn't expect a switch to dataDirectory to fix anything).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants