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

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

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>