0

I have a working youtube video area that is called by ajax. The first time a visitor enters this area, the video works perfectly. If the visitor goes to another area of the app, and returns (second ajax call), the video area doesn't show any video, and it seems that window.onYouTubeIframeAPIReady() is never called (neither the onReady event who calls playVideo() ...)

the goal is to always show the video

Once the code is the same but has different behavior I have tried to dynamically insert and remove youtube_api, make window.onYouTubeIframeAPIReady() null and reconstruct, so that the second call would be exactly like the first, but nothing (I guess I don't understand exactly what the problem is)

The javascript code is:

function loadScript() {

    if (typeof (YT) == 'undefined' || typeof (YT.Player) == 'undefined') {
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }
}


function loadPlayer() {


console.log(window.onYouTubePlayerAPIReady)


console.log("3");


    window.onYouTubePlayerAPIReady = function () {

        console.log("4");

        onYouTubeIframeAPIReady();

        console.log("5");
    };

}


$(function () {
    loadScript();
})



var VidID;


$(document).ready(function() {



console.log("0");



VidID = $("#videoWraper").attr("data-PlayingVid");

console.log("1");

loadPlayer();

console.log("2");




});



function onYouTubeIframeAPIReady() {

console.log("7");
player = new window.YT.Player('YouTubeVideo', {
    videoId: VidID, // YouTube Video ID lUlOptJolAA
    //width: 560,               // Player width (in px)
    //height: 3160,              // Player height (in 316 px)
    playerVars: {
        enablejsapi: 1,
        autoplay: 1,        // Auto-play the video on load
        controls: 1,        // Show pause/play buttons in player
        showinfo: 0,        // Hide the video title
        modestbranding: 1,  // Hide the Youtube Logo
        loop: 0,            // Run the video in a loop
        fs: 0,              // Hide the full screen button
        cc_load_policy: 1, // Hide closed captions
        iv_load_policy: 3,  // Hide the Video Annotations
        autohide: 1,         // Hide video controls when playing
        rel: 0,           // Hide recommended videos
    },

    events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
    }
});

console.log("8");
}

function onPlayerReady(event) {
    event.target.playVideo();
}

As mentioned the youtube video works on the first call but not on the second.

The console track is (i inserted the console.logs to have this info):

0 //starts
VM9066:53 1 // got to video ID
VM9066:15 undefined //window.onYouTubePlayerAPIReady not defined
VM9066:19 3
VM9066:58 2
VM9066:69 7 // window.onYouTubePlayerAPIReady is being defined
VM9066:94 8 // window.onYouTubePlayerAPIReady is defined
VM9066:24 4
VM9066:69 7 //dont understand why the second time
VM9066:94 8 //dont understand why the second time
VM9066:28 5
ERROR: www-widgetapi.js:115 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.youtube.com') does not match the recipient window's origin ('http://localhost:44600').
ERROR: www-widgetapi.js:115 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.youtube.com') does not match the recipient window's origin ('http://localhost:44600').
VM9066:104 10 //event onstatechange
VM9066:106 a1[object Object]
VM9066:107 a20

On the second ajax call console just shows:

0
VM9574:53 1
VM9574:15 ƒ () {

        console.log("4");

        onYouTubeIframeAPIReady();

        console.log("5");
    }
VM9574:19 3
VM9574:58 2

The html code is:

<div id="videoWraper" class="video-container" data-PlayingVid="@Model.SM_Identifier">
        <div id="YouTubeVideo"></div>
        <script async src="https://www.youtube.com/iframe_api"></script>
</div>

Please if someone can help me find the bug I would really appreciate it.

Thank you and sorry for the long post.

SemBauke
  • 147
  • 11
Diogo Almeida
  • 124
  • 2
  • 12

2 Answers2

0

On first call the video is directly binded into the page but on the second call of the ajax it is made through the localhost that gives a cross origin request try cord headers

Hitech Hitesh
  • 1,641
  • 1
  • 9
  • 18
0

The answer to this question was found in an answer for a similar question:

https://stackoverflow.com/a/48038558/2358046

Instead of making an external call, it makes an internal call to same code with minor changes, solving the error:

ERROR: www-widgetapi.js:115 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.youtube.com') does not match the recipient window's origin ('http://localhost:44600')

This makes unecessary to dinamicaly load yt_api, so the js script is changed to:

var player;
var VidID;


//When ready, gets YT_ID and calls API do youtube
$(document).ready(function () {

VidID = $("#videoWraper").attr("data-PlayingVid");
    onYouTubeIframeAPIReady();
});




// Call to youtube API (internal) to start the video
function onYouTubeIframeAPIReady() {

player = new window.YT.Player('YouTubeVideo', {
    videoId: VidID, // YouTube Video ID lUlOptJolAA
    playerVars: {
        enablejsapi: 1,
        autoplay: 1,        // Auto-play the video on load
        controls: 1,        // Show pause/play buttons in player
        showinfo: 0,        // Hide the video title
        modestbranding: 1,  // Hide the Youtube Logo
        loop: 0,            // Run the video in a loop
        fs: 0,              // Hide the full screen button
        cc_load_policy: 1, // Hide closed captions
        iv_load_policy: 3,  // Hide the Video Annotations
        autohide: 1,         // Hide video controls when playing
        rel: 0,           // Hide recommended videos
    },

    events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
    }
});

}


function onPlayerReady(event) {
    event.target.playVideo();
}

The created files should be loaded before this code.

Monolitic and Not perfect, but solves the problem.

Diogo Almeida
  • 124
  • 2
  • 12