RyGuy
RyGuy

Reputation: 305

Accessing element within iFrame

I need to get the current time of a youtube video I'm playing in an iFrame, but cannot access the video from my script.

I'm able to use console.alert($("#player").children[0].getCurrentTime()) without trouble after selecting the video in the browser dev tools.

However, I get TypeError: Cannot read property 'getCurrentTime' of undefined when that same code is run from the script.

This post on SO made me think it has to do with the element being hidden if dev tools isn't opened. However $("#player").children[0].removeClass("hidden") returns TypeError: $(...).contents is not a function at <anonymous>. The element just doesn't seem to exist.

Below is full code, 90% of which is straight from the first iframe example here.

<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<script>
    // 2. This code loads the IFrame Player API code asynchronously.
    var tag = document.createElement('script');

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

    // 3. This function creates an <iframe> (and YouTube player)
    //    after the API code downloads.
    var player;
    function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
            height: '390',
            width: '640',
            videoId: 'U03lLvhBzOw',
            events: {
                'onReady': onPlayerReady
            }
        });
    }

    // 4. The API will call this function when the video player is ready.
    function onPlayerReady(event) {
        event.target.playVideo();
        console.alert($("#player").children[0].getCurrentTime()) //DOESN'T WORK
    }

</script>
</body>
</html>

Upvotes: 2

Views: 768

Answers (4)

Debbie Kurth
Debbie Kurth

Reputation: 481

I used DOM to do the job. This became essential when interfacing with Vimeo video playback, where the iframe, simply was not going to have a id, but the DIV outside of it did. In order to control the playback of the video, I had to get the iframe inside.

I suspect you could do something similar with YouTube. For me Vimeo was the focus.

<div id="260309722" name="260309722" class="hook">
<iframe  src="https://player.vimeo.com/video/260309722" width="500" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>

<script>
var tmp          = document.getElementById("260309722").querySelectorAll("iframe"); 
var iframe       = tmp[0];          // grab the iframe inside

VideoControl(iframe, TeaserLen);

function VideoControl(iframe, TeaserLen)
{
var Videoplayer  = new Vimeo.Player(iframe);
    Videoplayer.on('timeupdate', function(progress) {
var Progress = progress.percent * 100;
var Playtime = progress.seconds;
var Playtime2 = Videoplayer.getCurrentTime();
  
   if (Playtime >= TeaserLen)
   {
     var bPaused = Playtime2;   
     Videoplayer.pause();

    // do something else
   }            //  if (Playtime >= TeaserLen)
 });            // Videoplayer.on('timeupdate', function(progress)
}               // function VideoControl(iframe, TeaserLen)
</script>

Upvotes: 1

Simon Fermor
Simon Fermor

Reputation: 116

You have the var object for the YouTube player already so there's no need to navigate the DOM.

For example:

// Play the video
function onPlayerReady(event) {
    player.playVideo();
    console.log(player.getCurrentTime());

    // Jump to 10 seconds
    player.seekTo(10);

    // Stop the video after 3 seconds
    setTimeout(stopVideo, 3000);
}

function stopVideo() {
    console.log(player.getCurrentTime());
    player.stopVideo();
}

Upvotes: 1

TheNikhilK
TheNikhilK

Reputation: 11

The simple rule when working with iFrame is that you can can access content within it only when it served from the same host/origin.

This is the standard behavior across all browsers with respect to security. Bottom line, no Direct way to access content of the iFrame if from different domain.

In this case the only solution I see is that, since you are creating with Youtube API, just cache the object of the player you created to a var and then just explore methods in it in the console

Upvotes: 2

You cannot change the content within an iFrame unless the iframe is from the same domain as your parent. That's why the query result gives you undefined.

Please refer to this post to further details to this issue.

Override body style for content in an iframe

Upvotes: 0

Related Questions