Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rwaldron/808573 to your computer and use it in GitHub Desktop.
Save rwaldron/808573 to your computer and use it in GitHub Desktop.
var supportedMimeTypes = ['video/mp4', 'video/x-ms-wmv'];
var supportedVideoExtensions = ['.mp4', '.wmv', '.mp4v', '.m4v'];
var getSupportedMediaSource = function(videoElement)
{
// If the video element source is supported, then we replace the tag.
if (videoElement.src
&& isWMPSupported(videoElement))
{
return videoElement.src;
}
// "If all src videos are [supported], the video tag is replaced otherwise
// it is not. Basically if there is at least one video that WMP is not able
// to play we should not replace the Video tag."
var sources = videoElement.getElementsByTagName("source");
var supportedSource = null;
for (var i=0; i<sources.length; i++)
{
if (sources[i].src)
{
if (isWMPSupported(sources[i]))
{
supportedSource = sources[i].src;
}
else
{
return null;
}
}
}
return supportedSource;
}
var isWMPSupported = function(videoOrSourceElement)
{
if (videoOrSourceElement.type)
{
var type = videoOrSourceElement.type.toLowerCase();
var index = type.indexOf(';');
if (index != -1)
type = type.slice(0, index);
for (var i=0; i<supportedMimeTypes.length; i++)
{
if (supportedMimeTypes[i] == type)
return true;
}
}
else if (videoOrSourceElement.src)
{
var src = videoOrSourceElement.src.toLowerCase();
var lastIndex = src.lastIndexOf(".");
if (lastIndex != -1)
src = src.slice(lastIndex);
for (var i=0; i<supportedVideoExtensions.length; i++)
{
if (supportedVideoExtensions[i] == src)
return true;
}
}
return false;
}
var createControlFromVideo = function(videoElement)
{
var supportedMediaSource = getSupportedMediaSource(videoElement);
if (!supportedMediaSource)
{
return null;
}
else
{
}
var control = document.createElement("object");
control.type = "application/x-ms-wmp";
// assign height/width
var width = videoElement.width;
if (width <= 0)
{
// try to use clientWidth if the video element doesn't have explicit width
if (videoElement.clientWidth > 0)
{
width = videoElement.clientWidth;
// adjust for padding
if (videoElement.style.paddingRight != "")
{
width -= parseInt(videoElement.style.paddingRight);
}
if (videoElement.style.paddingLeft != "")
{
width -= parseInt(videoElement.style.paddingLeft);
}
}
else
{
// default to 320 if we can't get width or clientWidth
width = 320;
}
width += 'px';
}
control.width = width;
var height = videoElement.height;
if (height <= 0)
{
// try to use clientHeight if the video element doesn't have explicit height
if (videoElement.clientHeight > 0)
{
height = videoElement.clientHeight;
// adjust for padding
if (videoElement.style.paddingTop != "")
{
height -= parseInt(videoElement.style.paddingTop);
}
if (videoElement.style.paddingBottom != "")
{
height -= parseInt(videoElement.style.paddingBottom);
}
}
else
{
// default to 240 if we can't get height or clientHeight
height = 240;
}
height += 'px';
}
control.height = height;
// following standard attributes need to be assigned only when they are present in the video tag
if (videoElement.id != "") { control.id = videoElement.id; }
if (videoElement.dir != "") { control.dir = videoElement.dir; }
if (videoElement.class != "") { control.class = videoElement.class; }
if (videoElement.title != "") { control.title = videoElement.title; }
if (videoElement.draggable) { control.draggable = true; }
if (videoElement.lang != "") { control.lang = videoElement.lang; }
if (videoElement.spellcheck) { control.spellcheck = true; }
if (videoElement.style.cssText != "") { control.style.cssText = videoElement.style.cssText; }
// controls attribute - boolean for video tag.
// for WMP, uiMode => "full" shows controls, "none" shows only video window
var controls = (videoElement.controls == true) ? "full" : "none";
control.setAttribute("uiMode", controls);
var autostart = videoElement.autoplay; // boolean - maps to object.autostart property
var paramAutoStart = document.createElement("param");
paramAutoStart.name = "autostart";
paramAutoStart.value = autostart;
control.appendChild(paramAutoStart);
// OPEN: Should we always set autostart when "controls" are hidden ?
var paramUrl = document.createElement("param");
paramUrl.name = "url";
paramUrl.value = supportedMediaSource;
control.appendChild(paramUrl);
return control;
}
var processVideoElements = function()
{
var videoElements = document.getElementsByTagName("video");
for (var i=0; i<videoElements.length; i++)
{
videoElement = videoElements[i];
videoElement.removeEventListener("DOMSubtreeModified", processVideoElements, true);
var objectElement = createControlFromVideo(videoElement);
if (objectElement)
{
videoElement.parentNode.insertBefore(objectElement, videoElement);
videoElement.setAttribute("class", "__wmpff_replaced");
}
else
{
videoElement.addEventListener("DOMSubtreeModified", processVideoElements, true);
}
}
while (replacedVideoElement = document.querySelector(".__wmpff_replaced"))
{
replacedVideoElement.parentNode.removeChild(replacedVideoElement);
}
}
var supportsH264BaselineProfile = function()
{
return document.createElement("video").canPlayType('video/mp4; codecs="avc1.42E01E"');
}
window.addEventListener("load", function()
{
if (!supportsH264BaselineProfile())
{
processVideoElements();
}
}, false);
@rwaldron
Copy link
Author

rwaldron commented Feb 2, 2011

L 52 - 54: Missing curly braces

L 52 : Uses == instead of ===

L 61 - 63: Missing curly braces

L 61 : Uses != instead of !==

L 67 - 69: Missing curly braces

L 67 : Uses == instead of ===

@ryanflorence
Copy link

Nah, that's beautiful code. Allman style JavaScript FTW!

Also love the if > if > if > if > else hilarity. Guy couldn't figure out what he wanted to do.

@rwaldron
Copy link
Author

rwaldron commented Feb 2, 2011

L 84 - 85 : Empty block

L 100 : Uses != instead of !==

L 104 : Uses != instead of !==

L 128 : Uses != instead of !==

L 132 : Uses != instead of !==

L 100, 104, 128, 132 : Should evaluate falsy, instead of for empty strings

@rwaldron
Copy link
Author

rwaldron commented Feb 2, 2011

L 149 - 156 : Atrocious. Try writing a reusable extend() and augment the object iteratively

@rwaldron
Copy link
Author

rwaldron commented Feb 2, 2011

L 149 - 156 : Atrocious. Try writing a reusable extend() and augment the object iteratively

L 91 - 145 : DRY it out.

L 160 : Unnec. explicit boolean test

L 182 : Missing early return if !videoElements.length

@rwaldron
Copy link
Author

rwaldron commented Feb 2, 2011

L 212 : document.addEventListener("DOMContentLoaded", function() {}, false); might avoid the Flashed content change

@ericf
Copy link

ericf commented Feb 2, 2011

L 102, 106, 130, 134 : calls to parseInt without specifying a radix which should be set to 10

@rwaldron
Copy link
Author

rwaldron commented Feb 3, 2011

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment