Reputation: 788
I've found that you can't use cdvfile://
when using cordova-ios 6.1.0
because of how WKWebView
works. You now need to use window.WkWebView.convertFilePath([your file path]);
to convert your path to something WKWebView
.
I'm now using the toURL()
method found when getting a FileEntry
from the cordova-plugin-file
plugin and feeding that value into window.WkWebView.convertFilePath
.
I'm still getting a similar error, but I think I'm getting closer to cracking this egg:
Refused to load unsafe:app://localhost/_app_file_/var/mobile/Containers/Data/Application/{ID}/Library/NoCloud/videos/recording.MOV because it does not appear in the media-src directive of the Content Security Policy.
I added app:
to the CSP and added <access origin=app://* />
to config.xml
.
Does anyone know how I can get rid of the error and get the video playing within the <video>
element?
When trying to play a cdvfile://
file in a <video>
element I get the following error, even though I've added, what I think, is the correct properties to my Content Security Policy (found below):
Refused to load unsafe:cdvfile://localhost/library-nosync/videos/recording.MOV because it does not appear in the media-src directive of the Content Security Policy.
What is required to get a locally stored video file working in a basic <video>
element using Angular + Cordova?
I'm using Angular 9.0.7
, cordova 10.0.0
and cordova-ios 6.1.0
to build an app that plays video recordings. Recordings are created using cordova-plugin-media-capture 3.0.3
and saved to the local device using cordova-plugin-file 6.0.2
.
I've added the following to my config.xml
:
<access origin="cdvfile://*" />
<preference name="scheme" value="app" />
<preference name="hostname" value="localhost" />
I'm also using the most open/insecure Content Security Policy I could find, with cdvfile:
added to default-src
, connect-src
and media-src
:
<meta http-equiv="Content-Security-Policy" content="
default-src * data: blob: filesystem: about: ws: wss: gap: cdvfile: 'unsafe-inline' 'unsafe-eval';
script-src * filesystem: gap: cdvfile: data: blob: 'unsafe-inline' 'unsafe-eval';
connect-src * filesystem: gap: cdvfile: data: blob: 'unsafe-inline';
img-src * filesystem: gap: cdvfile: data: blob: 'unsafe-inline';
frame-src * data: blob: ;
style-src * data: blob: 'unsafe-inline';
font-src * data: blob: 'unsafe-inline';
media-src * filesystem: gap: cdvfile: data: blob: mediastream: ;
">
In the documentation for the cordova-plugin-file
plugin (link) they provide an example Content Security Policy, but it doesn't appear to be valid:
<meta http-equiv="Content-Security-Policy" content="
default-src 'self' data: gap:cdvfile:https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline';
media-src *
">
When using the above, I get the following error on load:
The source list for Content Security Policy directive 'default-src' contains an invalid source: 'gap:cdvfile:https://ssl.gstatic.com'. It will be ignored.
The only way to remove the error is to add a space betweem gap:
, cdvfile:
and https://ssl.gstatic.com
. I ended up removing https://ssl.gstatic.com
to make the CSP as generic and "open" as possible.
I can load the MOV file and validate that is exists using the following:
window.resolveLocalFileSystemURL([PATH TO FILE ENTRY], entry => {
entry.getMetadata(metadata => {
console.log(metadata); // If metadata.size exists and isn't 0, I believe I have the file
}, err => {
console.error(err);
});
});
Once I have the file (variable named entry
in this example) I use the following in my component to get the filepath:
let videoSrc: string = entry.toInternalURL();
This get's me the cdvfile://
path that I then use as the source to play in my video element:
<video *ngIf="videoSrc" id="video" width="640" height="360" preload controls>
<source [src]="videoSrc" type="video/mp4" />
</video>
... So, yeah. That's my life story... Can anyone shed some light as to what's required to allow me to play local cdvfile
files in a standard <video>
element?
Upvotes: 0
Views: 1865
Reputation: 1473
I believe you need to add an explicit permission for app:
in the <meta http-equiv="Content-Security-Policy"
.
<!-- Enable all requests, inline styles, and eval() -->
<meta http-equiv="Content-Security-Policy" content="
default-src * app: gap: data: cdvfile: android-webview-video-poster: file:;
style-src 'self' 'unsafe-inline';
script-src * 'unsafe-inline'">
(For some reason default-src *
wasn't enough. I had to add default-src * app:
to make it work on http://
urls.)
It also appears to work if you just don't have a <meta http-equiv="Content-Security-Policy"
at all.
My life story since it took me a long time to figure out why it wouldn't be working for you:
I can confirm that this should work.
Based on your "Updated Info"...
I am doing exactly what you are with cdvfile > nativeUrl > schemeUrl
When I use the schemeUrl in an <img>
and <video>
src tag on:
app://localhost/...
):
https://...
url:
http://
Notes / Other possibilities thoughts:
Your <access origin=app://* />
Should probably be <access origin="app://*" />
But I don't think this is your problem as I don't have an <access origin/>
tag at all in my config.xml.
You can try adding:
<allow-navigation hap-rule="yes" href="app://localhost/*" />
to your config.xml
(same place where you would have <access origin=.../>
)
But I also just tried my app without this and it was fine.
You could also try upgrading to [email protected]
Upvotes: 0