Izaias
Izaias

Reputation: 389

Chromecast + Youtube embed + HTML5 video tag = bug

I have been trying to play two videos (not necessarily simultaneously) on a Chromecast app. Once of them is embedded via the Youtube API and the other is a standard HTML5 video loaded via the tag.

It turns out that the Youtube video simply won't be played back on Chromecast if I also have a standard tag in my HTML5 page. But if I remove that video tag, then the Youtube video will play back nicely.

Any advice is highly appreciated!

Upvotes: 1

Views: 1513

Answers (2)

rlittrell
rlittrell

Reputation: 1

I ran into this same problem.

The key elements to solve it are, unload the cast player and don't let a video tag linger in the DOM with a SRC attribute set when you attempt to play Youtube.

As for YouTube, dont let the IFRAME that contains their video player linger in the DOM either when attempting to use the HTML5 video tag.

You'll need to tear down the previous player before attempting to trigger playback through the opposing mechanism.

Here is my sample receiver I used to troubleshoot and solve the problem. This is a working example.

<html>
<head>
    <title></title>
    <style type="text/css">
    body {
        background-color: #000;
        overflow: hidden;
    }

    </style>
</head>
<body>
    <script type="text/javascript" src="//code.jquery.com/jquery-2.1.4.min.js"></script>
    <script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js"></script>
    <script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/mediaplayer/1.0.0/media_player.js"></script>
    <video id="chromecast" style="width: 50%; height: 50%;"></video>

    <script>
    var ytCode = 'sSwLhYhYgI0'
    var hlsUrl = 'http://host.com/playlist.m3u8'
    </script>


    <!-- Chromecast -->
    <script type="text/javascript">
        var castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
        var messageBus = castReceiverManager.getCastMessageBus('urn:x-cast:tv.domain');

        cast.receiver.logger.setLevelValue(cast.receiver.LoggerLevel.DEBUG);
        cast.player.api.setLoggerLevel(cast.player.api.LoggerLevel.DEBUG);


        castReceiverManager.onReady = function() {
            console.info('[castReceiverManager.onReady]');
            castReceiverManager.setApplicationState('Ready');
        };

        castReceiverManager.onSenderConnected = function(sender) {
            console.info('[castReceiverManager.onSenderConnected]', sender.userAgent);
        };

        messageBus.onMessage = function(event) {
            var message = JSON.parse(event.data);
            console.info('[messageBus.onMessage]', message);
        };

        // Normal
        castReceiverManager.start({
            maxInactivity: 8,
            statusText: 'Ready to play',
            dialData: undefined
        });

        window.playDirect = function(id) {

            // Tear down any YT player
            $('#youtube').remove();

            if(!id) id = 'chromecast'; 
            var mediaElement = document.getElementById(id);
            window.host = new cast.player.api.Host({'mediaElement':mediaElement, 'url':hlsUrl});
            window.host.onError = function(errorCode) {
              console.log('ERROR ' + errorCode);
            };

            var protocol = cast.player.api.CreateHlsStreamingProtocol(window.host);
            window.CCplayer = new cast.player.api.Player(window.host);
            window.CCplayer.load(protocol, 25);
            setTimeout(function() {
                mediaElement.play();
            }, 1000);
        };
    </script>




    <!-- Youtube -->
    <script>
        window.onYouTubeIframeAPIReady = function() {
            console.log('Initialized Youtube');
        };

        var playYT = function() {

            // Tear down any direct player
            if(window.CCplayer) {
                window.CCplayer.unload();
            }
            $('video').attr('src', '');


            // Inject div tag that will be converted to iframe with player
            $('body').append('<div id="youtube" style="width: 50%; height: 50%;"></div>');

            window.YTPlayer = new YT.Player(
                'youtube', 
                {
                    height: '100%',
                    width: '100%',
                    playerVars: {
                        'autoplay': 0,
                        'controls': 0,
                        'cc_load_policy': 0,
                        'fs': 0,
                        'iv_load_policy': 0,
                        'modestbranding': 0,
                        'rel': 0,
                        'showinfo': 0,
                        'enablejsapi': 1
                    },
                    events: {
                    'onReady': function() {
                        var params = { videoId: ytCode, startSeconds: 170 };
                        window.YTPlayer.cueVideoById(params);
                        window.YTPlayer.playVideo();
                    },
                    'onError': function(err) {
                        console.log('YT Error ' + err);
                    }
                }
            });
        };


        var iframeScript = document.createElement('script');
        iframeScript.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(iframeScript, firstScriptTag);
    </script>

</body>
</html>

Test:

Load up the sample receiver above, and alternate the following inside the chrome debug console:

playDirect()

or

playYT()

Upvotes: 0

Leon Nicholls
Leon Nicholls

Reputation: 4656

Only one active video stream is supported on Chromecast.

Upvotes: 1

Related Questions