2
votes

Problem

attempting to play video from within the webview (android 5.0) results in many "Cross origin requests" failures and video does not play. HOWEVER, on Google Chrome, on the laptop, the HTML below makes the video plays perfectly fine !

HTML

<!DOCTYPE html>
<html>
    <head>
        <style>
            html{width:100%;height:100%;}
            body{margin:0;width:100%;height:100%;background-color:black;}
        </style>
    </head>
    <body>
        <div id='player'></div>
        <script> 
            var playerLoaded = false;
            var percentReported = 0;
            var percentCurrent = 0;
            var tag = document.createElement('script');
            tag.src = 'http://www.youtube.com/player_api'; 
            var firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
            var player; 

            function onYouTubePlayerAPIReady() { 
                playerLoaded = true;
                player = new YT.Player('player', { 
                    width:'100%', 
                    height:'100%', 
                    videoId:'CpaOh4poNms', 
                    playerVars: { playsinline: 1 }, 
                    events: { 
                        'onReady': onPlayerReady, 
                        'onStateChange': onPlayerStateChange, 
                        'onError': onPlayerError 
                    }
                }); 
            }

            function onPlayerReady(event) { 
                event.target.playVideo(); 
                setInterval(onPlayerTimeUpdate, 1000); 
            }

            function onPlayerStateChange(event) {
                if (event.data == YT.PlayerState.ENDED) {
                } 
            }

            function onPlayerError(event) {
            }

            function onPlayerTimeUpdate() { 
                percentCurrent = Math.round(player.getCurrentTime() / player.getDuration() * 100); 
                if (percentCurrent > percentReported) { 
                     percentReported = percentCurrent; 
                }
            }

            setTimeout(function() { 
                if (!playerLoaded) { 
                } 
            }, 10000);
        </script> 
    </body>
</html>

Errors

01-15 11:21:42.410 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.youtube.com') does not match the recipient window's origin ('http://www.youtube.com').", source: (0) 01-15 11:21:42.898 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.899 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.899 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.901 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.901 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.911 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.914 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.914 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.917 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.921 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.922 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.923 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.926 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.928 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.928 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.929 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.930 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.931 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.931 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.931 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.935 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.939 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.940 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.943 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.946 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.947 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.948 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.958 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.961 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.962 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:42.964 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "XMLHttpRequest cannot load chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js. Cross origin requests are only supported for HTTP.", source: http://www.youtube.com/embed/CpaOh4poNms?playsinline=1&enablejsapi=1&origin=http%3A%2F%2Fwww.youtube.com (0) 01-15 11:21:43.246 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.youtube.com') does not match the recipient window's origin ('http://www.youtube.com').", source: (0) 01-15 11:21:43.305 21328-21328/com.my.android.app I/chromium﹕ [INFO:CONSOLE(0)] "Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.youtube.com') does not match the recipient window's origin ('http://www.youtube.com').", source: (0)

How the Webview is initialized

@SuppressLint("SetJavaScriptEnabled")
public void setupWebView(WebView webView) {
    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setUseWideViewPort(false);
    webSettings.setLoadWithOverviewMode(false);

    webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);

    webSettings.setSaveFormData(false);
    webSettings.setSupportZoom(false);
    webSettings.setBuiltInZoomControls(false);

    webSettings.setSupportMultipleWindows(false);
    webSettings.setAppCacheEnabled(true);
    webSettings.setAppCachePath("");

    webSettings.setDefaultTextEncodingName("UTF-8");

    webSettings.setDomStorageEnabled(true);

    webSettings.setAllowFileAccess(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        webSettings.setAllowFileAccessFromFileURLs(true);
        webSettings.setAllowUniversalAccessFromFileURLs(true);
    }

    webView.setBackgroundColor(Color.TRANSPARENT);
    webView.setVerticalScrollBarEnabled(false);
    webView.setHorizontalScrollBarEnabled(false);
    webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);

}

private FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER = new FrameLayout.LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT,
        ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);

    // this will allow the webview to play embedded video and full screen video
    mYoutubeVideoViewContainer = (FrameLayout) findViewById(R.id.fullscreen_youtube_video);
    mWebChromeClient = new WebChromeClient() {
        @Override
        public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
        {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

            // if a view already exists then immediately terminate the new one
            if (mCustomView != null)
            {
                callback.onCustomViewHidden();
                return;
            }

            // Add the custom view to its container.
            mYoutubeVideoViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
            mCustomView = view;
            mCustomViewCallback = callback;

            // hide main browser view
            mContentFlipper.setVisibility(View.GONE);

            // Finally show the custom view container.
            mYoutubeVideoViewContainer.setVisibility(View.VISIBLE);
            mYoutubeVideoViewContainer.bringToFront();
        }

        @Override
        public void onHideCustomView()
        {
            if (mCustomView == null) {
                return;
            }

            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

            // Hide the custom view.
            mCustomView.setVisibility(View.GONE);

            // Remove the custom view from its container.
            mYoutubeVideoViewContainer.removeView(mCustomView);
            mCustomView = null;
            mYoutubeVideoViewContainer.setVisibility(View.GONE);
            mCustomViewCallback.onCustomViewHidden();

            // Show the content view.
            mContentFlipper.setVisibility(View.VISIBLE);
        }
    };
    mTargetWebView.setWebChromeClient(mWebChromeClient);
    mTargetWebView.setWebViewClient(new WebViewClient());

How the HTML is loaded into the webview

mTargetWebView.loadDataWithBaseURL("http://www.youtube.com", youtubeHTML, "text/html", "utf-8", null);

Layout XML

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/fullscreen_youtube_video"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#FF000000">

        <ViewSwitcher
            android:id="@+id/contentFlipper"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <WebView
                android:id="@+id/youtubeWebview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/white" />

        </ViewSwitcher>

    </FrameLayout>

</RelativeLayout>

What did I miss ?

PROGRESS...

The only way I can get this crap to work on Android's (5.0) webview is to use the following HTML...

<html>
<body>
<iframe width="100%" height="100%" src="http://www.youtube.com/embed/CpaOh4poNms?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe>
</body>
</html>

At least this will show the video player. This whole dynamic div-to-iframe crap is totally non-functional on Android: https://developers.google.com/youtube/iframe_api_reference#Getting_Started

1
The Getting Started HTML fails the same way developers.google.com/youtube/iframe_api_reference /facepalmSomeone Somewhere

1 Answers

0
votes

I've worked out that onYouTubeIframeAPIReady() and onYouTubePlayerAPIReady() are never called on Android.

I wonder if this is on purpose to force people to switch to the YouTube Library - which I would if the library didn't depend on the YouTube app. I think there should be a "fat" and "thin" version of the library; the thin version depends on the youtube app and the fat version optionally requires it.

To make the video autoplay, I'm using the following code: https://stackoverflow.com/a/27722504/550471 and trigger it from onPageFinished()

To load the HTML into the WebView, I'm using : webView.loadDataWithBaseURL("http://www.youtube.com", youtubeHTML, "text/html; charset=utf-8", "UTF-8", null);

The HTML consists of:

<html>
<head></head>
<body>
<iframe id="player" width="100%" height="100%" src="http://www.youtube.com/embed/CpaOh4poNms?rel=0&origin=youtube.com" frameborder="0" allowfullscreen></iframe>
</body>
</html>