'Access 'Stats for nerds' data in youtube iFrame

I'm currently doing measures on the quality of a video youtube depending on given network conditions. I wrote a custom Chrome extension to play videos and get buffering informations thanks to the youtube player api.

What I would need now is the content of the 'Stats for nerds' panel that appears when you right-click on the video (example). I can display it thanks to UI automation. But, when I try to access the content of this panel with javascript, I get an error because of Cross-origin resource sharing (CORS).

I only want to read the Current/OptimalRes of the panel. Do you have any idea of a way to get it?

I've been searching for an answer to this question for long now. It has been mentioned here, but the answer to this post is not what I'm looking for as it only gives the general information about the video, not the resolution that is actually being played.



Solution 1:[1]

Apologies that this code is in 'AutoIT', but it should be easy to pipe to Javascript or any other similar language. This is a complete list of the 'Stats for Nerds' data:

#include <IE.au3>

;Attach to open YouTube player within browser
$oIE = _IEAttach ("https://www.youtube.com", "url",1)

;Get a reference to the movie player
$oPlayerRef = $oIE.document.getElementById("movie_player")

;Video ID / sCPN
msgbox(0,"",$oPlayerRef.getStatsForNerds(0).video_id_and_cpn)
;Viewport / Frames
msgbox(0,"",$oPlayerRef.getStatsForNerds(0).dims_and_frames)
;Current / Optimal Res
msgbox(0,"",$oPlayerRef.getStatsForNerds(0).resolution)
;Volume / Normalized
msgbox(0,"",$oPlayerRef.getStatsForNerds(0).volume)
;Codecs
msgbox(0,"",$oPlayerRef.getStatsForNerds(0).codecs)
;Connection Speed
msgbox(0,"",$oPlayerRef.getStatsForNerds(0).bandwidth_kbps)
;Network Activity
msgbox(0,"",$oPlayerRef.getStatsForNerds(0).network_activity_bytes)
;Buffer Health
msgbox(0,"",$oPlayerRef.getStatsForNerds(0).buffer_health_seconds)
;Mystery Text
msgbox(0,"",$oPlayerRef.getStatsForNerds(0).debug_info)

Solution 2:[2]

player.getPlaybackQuality();

Just call this function in the code given below

This code is from https://developers.google.com/youtube/iframe_api_reference

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

    <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: 'M7lc1UVf-VE',
          playerVars: {
            'playsinline': 1
          },
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }
           // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        event.target.playVideo();
      }

      // 5. The API calls this function when the player's state changes.
      //    The function indicates that when playing a video (state=1),
      //    the player should play for six seconds and then stop.
      var done = false;
      function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING && !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
      }
      function stopVideo() {
        player.stopVideo();
      }


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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MarkyT
Solution 2 Anar Salimkhanov