About C:Amie · Technical Articles · GFX & Artwork · Analog C:Amie Edition Friday, 23 June 2017

Simple Fourm YouTube API Video Embed Sample Script

System Requirements:

  • HTML

The Problem:

www.hpcfactor.com's forum software dates from 2004. At some point in the interim I rigged it to support a basic [video] BBS markup tag which uses a <embed> tag and the legacy a Flash object to inject a video from YouTube onto the page:

<object width="640" height="390"><param name="movie" value="{param}"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="{param}" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="640" height="390"></embed></object>

It is however currently 2016 and HTML 5 is the norm now, so at the behest of a user I wanted to update it.

More Info

Using the formal YouTube APU Reference for iframe Embeds sample. I needed to make something quick and easy that could be injected into the (extremely limited) BBS Markup system on the 12 year old hpcfactor.com forum. The only default substitution available without re-writing the forum core is {param} which takes the <URL> value from the BBS [video=<URL>] markup.

View: YouTube Player API Reference for iframe embeds

 

The code sample shown below was the quickly generated solution. The steps it goes through are:

  1. Drop a DIV in-line on the page for the YouTube API to replace with the iFrame
  2. Drop the JavaScript in-line as well (it has some unnecessary duplication but won't execute)
  3. The JavaScript checks to see if the YouTube API is already on the stack, if it is not it loads the YouTube API, if it is, it skips to the call to the JavaScript to embed the iFrame
  4. If the youTube API is not loaded, it loads the youTube API, sets up an array structure to act as a callback and pointer reference source to track all video files requested to be embedded on the page
  5. It sets up the onYouTubePlayerAPIReady listener to listen for the 'ready' callback from the youTube API, at which point JavaScript will be told to parse the sources array and create the iFrame's
  6. A registration function is provided. This receives video registrations even before the YouTube API is ready. As soon as the YouTube API callback to the onYouTubePlayerAPIReady listener, the video registrations are processed. Until it does, they queue.
  7. A function to test to see if the video has already been embedded is provided and is flagged once it has been embedded
<div id="videoPlayer_{param}"></div>
<script type="text/javascript">
// Load the IFrame Player API code asynchronously.
if (document.getElementById('youTubeExternal') === null) {
    var tag = document.createElement('script');
        tag.id = 'youTubeExternal';
        tag.type = 'text/javascript';
        tag.src = "https://www.youtube.com/player_api";
    var headTag = document.getElementsByTagName('head')[0];
        headTag.appendChild(tag);
    var arrVideoStack = new Array();
        arrVideoStack[0] = new Array(); // 0 = player reference, 1 = Display Elm ID, 2 = Video ID, 3 = IsLoaded
        arrVideoStack[1] = new Array();
        arrVideoStack[2] = new Array();
        arrVideoStack[3] = new Array();
    var iVideoCount = 0;
    var bolYtReady = false;

  // Replace the 'ytplayer' element with an <iframe> and
  // YouTube player after the API code downloads.
  function onYouTubePlayerAPIReady() {
    bolYtReady = true;
    loadVideos();
  }

  function registerNewVideo(strTargetElmId, strVideoId) {
    strVideoId = strVideoId.replace('https://www.youtube.com/watch?v=', '');
    strVideoId = strVideoId.replace('https://www.youtube.com/v/', '');
    strVideoId = strVideoId.split('&')[0]; // In case there are any more parameters
    arrVideoStack[0][iVideoCount] = null;
    arrVideoStack[1][iVideoCount] = strTargetElmId;
    arrVideoStack[2][iVideoCount] = strVideoId;
    arrVideoStack[3][iVideoCount] = false; iVideoCount++;
    if (bolYtReady) {
      loadVideos();
    }
  }

  function loadVideos() {
    if (bolYtReady) {
      if (iVideoCount > 0) {
        for (i = 0; i < iVideoCount; i++) {
          // If it hasn't already loaded, load it
          if (!arrVideoStack[3][i]) {
            arrVideoStack[0][i] = new YT.Player(arrVideoStack[1][i], {
                                          height: '640',
                                          width: '390',
                                          videoId: arrVideoStack[2][i]
                                      });
            arrVideoStack[3][i] = true;
          }
        }
      }
    }
  }
}

registerNewVideo('videoPlayer_{param}', '{param}');
</script>

If you would like to test it without the BBS markup parts in-situ you can copy and paste the following version into a .html file and double click on it

<div id="videoPlayer_Test1"></div>
<div id="videoPlayer_Test2"></div>
<div id="videoPlayer_Test3"></div>


<script type="text/javascript">
// Load the IFrame Player API code asynchronously.
if (document.getElementById('youTubeExternal') === null) {
    var tag = document.createElement('script');
        tag.id = 'youTubeExternal';
        tag.type = 'text/javascript';
        tag.src = "https://www.youtube.com/player_api";
    var headTag = document.getElementsByTagName('head')[0];
        headTag.appendChild(tag);
    var arrVideoStack = new Array();
        arrVideoStack[0] = new Array(); // 0 = player reference, 1 = Display Elm ID, 2 = Video ID, 3 = IsLoaded
        arrVideoStack[1] = new Array();
        arrVideoStack[2] = new Array();
        arrVideoStack[3] = new Array();
    var iVideoCount = 0;
    var bolYtReady = false;

  // Replace the 'ytplayer' element with an <iframe> and
  // YouTube player after the API code downloads.
  function onYouTubePlayerAPIReady() {
    bolYtReady = true;
    loadVideos();
  }

  function registerNewVideo(strTargetElmId, strVideoId) {
    strVideoId = strVideoId.replace('https://www.youtube.com/watch?v=', '');
    strVideoId = strVideoId.replace('https://www.youtube.com/v/', '');
    strVideoId = strVideoId.split('&')[0]; // In case there are any more parameters
    arrVideoStack[0][iVideoCount] = null;
    arrVideoStack[1][iVideoCount] = strTargetElmId;
    arrVideoStack[2][iVideoCount] = strVideoId;
    arrVideoStack[3][iVideoCount] = false; iVideoCount++;
    if (bolYtReady) {
      loadVideos();
    }
  }

  function loadVideos() {
    if (bolYtReady) {
      if (iVideoCount > 0) {
        for (i = 0; i < iVideoCount; i++) {
          // If it hasn't already loaded, load it
          if (!arrVideoStack[3][i]) {
            arrVideoStack[0][i] = new YT.Player(arrVideoStack[1][i], {
                                          height: '640',
                                          width: '390',
                                          videoId: arrVideoStack[2][i]
                                      });
            arrVideoStack[3][i] = true;
          }
        }
      }
    }
  }
}

registerNewVideo('videoPlayer_Test1', 'dQw4w9WgXcQ');
registerNewVideo('videoPlayer_Test2', 'm2ATf01v4hw');
registerNewVideo('videoPlayer_Test3', 'YVhxcpItk_M');
</script>

 

Article Published: Sunday, 30 October, 2016
Article Revision Date: Sunday, 4 December, 2016

This site is not associated with the Microsoft Corporation. The information on this page is provided as is and is free for those who visit to use. Microsoft Operating Systems, Internet Browsers and applications are the property of the Microsoft Corporation. Windows software patches and updates are the property of the Microsoft Corporation and are provided through the hard work and dedication of the Microsoft Security, Operating System, and Application development teams.

© C:Amie
1996 - 2017. All Rights Reserved (1,011)
All trademarks mentioned are the property of their respective owners.