xamarin/Xamarin.Forms

[Bug][iOS] Restricted YouTube video embedded in local HTML in WebView won't play, stating "Video is unavailable"

Open

#11,504 opened on 2020年7月22日

GitHub で見る
 (2 comments) (0 reactions) (0 assignees)C# (5,644 stars) (1,926 forks)batch import
a/webviewe/1 :clock1:good first issuehacktoberfest 🍻p/iOS 🍎t/bug :bug:up-for-grabs

説明

Description

This may be considered a feature request rather than a bug, so change as necessary.

A YouTube video that has restrictions set won't play in a Xamarin.Forms WebView, with YouTube message saying "Video is unavailable." This occurs when the video is embedded in local HTML string, and no base url or an improper base url is provided to the HtmlWebViewSource. e.g.:

var browser = new WebView();
var htmlSource = new HtmlWebViewSource();

htmlSource.Html = @"<html>
                        <body>  
                            <div style=' position: relative; padding-bottom: 56.25%; padding-top: 25px; overflow: hidden;'> 
                                <iframe style='position: absolute; top: 0; left: 0; width: 100%; height: 100%;' src='https://www.youtube.com/embed/ssP0GrK8Uws' frameborder='0' allow='accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>
                            </div> 
                        </body>
                    </html>";
       
browser.Source = htmlSource;

On android, the solution is simply to set the BaseUrl property on the HtmlWebViewSource to "https://www.youtube.com", e.g.

htmlSource.BaseUrl = "http://www.youtube.com";

However on iOS this does not work. I believe this is due to this line in the Xam.Forms source code: https://github.com/xamarin/Xamarin.Forms/blob/main/Xamarin.Forms.Platform.iOS/Renderers/WkWebViewRenderer.cs#L99

LoadHtmlString(html, baseUrl == null ? new NSUrl(NSBundle.MainBundle.BundlePath, true) : new NSUrl(baseUrl, true));

The issue is the second parameter for new NSUrl(baseUrl, true));, which according to apple docs using that constructor assumes that this is a file url. See: https://developer.apple.com/documentation/foundation/nsurl/1417505-initfileurlwithpath?language=objc

However, setting that second parameter to false does not allow the YouTube restricted video to play either (I believe because a file base url is expected, but we are setting a web base url), you have to use the single parameter constructor for NSUrl, e.g.:

LoadHtmlString(html, baseUrl == null ? new NSUrl(NSBundle.MainBundle.BundlePath, true) : new NSUrl(baseUrl)); // using single parameter constructor for NSUrl here

This can be worked around using a custom renderer for iOS:

class CustomWebViewRenderer : Xamarin.Forms.Platform.iOS.WkWebViewRenderer
{
    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null)
        {
            var webView  = e.NewElement as WebView;
            var source = webView.Source as HtmlWebViewSource;
            LoadHtmlString(source.Html, 
                source.BaseUrl == null ? new NSUrl(NSBundle.MainBundle.BundlePath, true) : (source.BaseUrl.StartsWith("http") ? new NSUrl(source.BaseUrl) : new NSUrl(source.BaseUrl, true)));
        }
    }
}

The above preserves the existing behavior unless the BaseUrl provided by the end developer starts with "http".

Steps to Reproduce

  1. Open the attached test project (derived from the Working with WebView sample)
  2. Launch to an iOS device or simulator
  3. Select the Local tab
  4. Click on the YouTube video's play button

Expected Behavior

Video will play

Actual Behavior

Video does not play. with a "Video Unavailable" message.

Add'l notes

If you select the BaseUrl tab, you will see that the same video will play as the web view in this tab uses the above custom renderer.

Worth noting is that it does not seem to matter what the web BaseUrl is, IOW it does not have to be "https://www.youtube.com", it can be anything. The important part seems to be to not use that NSUrl constructor that takes a boolean for IsDirectory

Basic Information

  • Version with issue: 4.7
  • Last known good version: Unknown
  • IDE: Visual Studio 2019
  • Platform Target Frameworks:
    • iOS: 13.5
  • Nuget Packages: Forms and Essentials

Reproduction Link

WebView.zip

Workaround

See above for custom renderer that can workaround this issue.

コントリビューターガイド