I'm using Xamarin.iOS but everything is easily translatable to ObjC / Swift.
I have a WKWebView
which loads a remote URL (html, js, css) that will then load mp4 videos stored locally within the app. The problem is these videos are not being loaded.
The site uses HTML 5 video tags and I'm setting the local urls by communicating C# with Javascript.
The video paths are something like this: /var/mobile/Containers/Data/Application/F535FA1C-752B-4B46-B237-6781464EE0E5/Documents/../Library/Vimeo/7b2723fa-b0f1-40c5-bc58-d43949273329.mp4
.
This is my WKWebView setup:
var userController = new WKUserContentController();
userController.AddScriptMessageHandler(new iOSSiteWrapper(this.ViewModel, () => this.webView), "iOSWrapper");
var configuration = new WKWebViewConfiguration
{
AllowsInlineMediaPlayback = true,
UserContentController = userController
};
configuration.Preferences.JavaScriptCanOpenWindowsAutomatically = true;
configuration.Preferences.JavaScriptEnabled = true;
configuration.Preferences.SetValueForKey(NSObject.FromObject(true), new NSString("allowFileAccessFromFileURLs"));
configuration.AllowsInlineMediaPlayback = true;
configuration.AllowsPictureInPictureMediaPlayback = true;
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
configuration.MediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypes.None;
}
else
{
configuration.MediaPlaybackRequiresUserAction = false;
}
this.webView = new WKWebView(
new CoreGraphics.CGRect(),
configuration)
{
WeakNavigationDelegate = this
};
// add to view hierarchy...
// this.ViewModel.HtmlContent is a string which contains the html page
this.webView.LoadHtmlString(this.ViewModel.HtmlContent, NSUrl.FromString(Constants.BASE_URL));
I have configured ATS exceptions in the Info.plist file.
I tried loading this simple html string:
var videoToPlay = "file:///var/mobile/Containers/Data/Application/F535FA1C-752B-4B46-B237-6781464EE0E5/Documents/../Library/Vimeo/7b2723fa-b0f1-40c5-bc58-d43949273329.mp4";
var html = $"<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body id=\"page\"><div id=\"VideoBean\" style=\"position:relative;\" width=\"305\" height=\"242\"><video id=\"video\" type=\"video/mp4\" controls=\"controls\" role=\"presentation\" width=\"305\" height=\"242\"><source id=\"source\" src=\"{videoToPlay}\"></video></div></body></html>";
this.webView.LoadHtmlString(html, NSUrl.FromString(Constants.BASE_URL));
And the result is the same. The video does not play and I can see this error on the Safari output:
Not allowed to load local resource: file:///var/mobile/Containers/Data/Application/F535FA1C-752B-4B46-B237-6781464EE0E5/Documents/../Library/Vimeo/7b2723fa-b0f1-40c5-bc58-d43949273329.mp4
If I load the html snippet setting the local path as base url, it works:
this.webView.LoadHtmlString(html, NSUrl.FromFilename(videoToPlay));
But as I'm trying to load a remote site, I need the base url to be the remote base url. So a new question would be: is it possible to set two base urls on WKWebView?
Otherwise, do I have any option other than loading the entire site locally?
This is what I've done to make it work:
1) Download the html file into the local storage
2) Look for all relative urls in the html file and set the base url on them. I mean something like this: src="myvideo.mp4
--> src="https://myhomeurl.com/myvideo.mp4"
3) Use webView.LoadFileUrl
instead of LoadHtmlString
(I also changed the second parameter from NSUrl.FromString
to NSUrl.FromFilename
).
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