Created
March 3, 2010 16:46
-
-
Save remy/320747 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(window, document, undefined) { | |
// Enable all HTML5 elements in IE. For discussion and comments, see: http://remysharp.com/2009/01/07/html5-enabling-script/ | |
/*@cc_on'abbr article aside audio canvas details figcaption figure footer header hgroup mark menu meter nav output progress section summary time video'.replace(/\w+/g,function(n){document.createElement(n)})@*/ | |
if (![].forEach) { | |
Array.prototype.forEach = function (fn) { | |
var len = this.length || 0, that = arguments[1]; | |
if (typeof fn == 'function') { | |
for (var i = 0; i < len; i++) { | |
fn.call(that, this[i], i, this); | |
} | |
} | |
}; | |
} | |
var each = [].forEach; | |
/** | |
* Replaces all video tags with flowplayer video player if the browser does | |
* not support either the video tag the h.264 codex. | |
* | |
* This is run automatically on document ready, but can be run manually | |
* again after dynamically creating HTML5 video tags. | |
*/ | |
function html5media() { | |
each.call(document.getElementsByTagName('video'), function (video) { | |
var requiresFallback = true; | |
// Test if the video tag is supported. | |
if (video.canPlayType) { | |
// If the video has a src attribute, and can play it, then all is good. | |
if (video.src && video.canPlayType(guessFormat(video.src))) { | |
requiresFallback = false; | |
} else { | |
// Check for source child attributes. | |
each.call(video.getElementsByTagName('source'), function (source) { | |
if (video.canPlayType(guessFormat(source.src, source.type))) { | |
requiresFallback = false; | |
} | |
}); | |
} | |
} | |
// If cannot play video, create the fallback. | |
if (requiresFallback) { | |
createVideoFallback(video); | |
} | |
}); | |
} | |
/** | |
* The locations of the flowplayer and flowplayer controls SWF files. | |
* | |
* Override this if they are not located in the same folder as the | |
*/ | |
// HACK: This could be done much easier with a selector, but there is a bug in IE6 that doesn't allow dots in attribute selectors. | |
var scriptRoot = ""; | |
each.call(document.getElementsByTagName('script'), function (script) { | |
var src = script.src; | |
if (src.substr(src.length - 20) == "jquery.html5media.js" || src.substr(src.length - 24) == "jquery.html5media.min.js") { | |
scriptRoot = src.split("/").slice(0, -1).join("/") + "/"; | |
} | |
}); | |
html5media.flowplayerSwf = scriptRoot + "flowplayer.swf"; | |
html5media.flowplayerControlsSwf = scriptRoot + "flowplayer.controls.swf"; | |
/** | |
* Known video formats. Used to change the assumed format to a different | |
* format, such as Theora, if desired. | |
*/ | |
html5media.H264_FORMAT = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'; | |
html5media.THEORA_FORMAT = 'video/ogg; codecs="theora, vorbis"'; | |
/** | |
* The video format to assume if it cannot be determined what format a video | |
* file is. | |
*/ | |
html5media.assumedFormat = html5media.H264_FORMAT; | |
// Trys to determine the format of a given video file. | |
function guessFormat(src, type) { | |
// If a type is explicitly given, then use this. | |
if (type) { | |
return type; | |
} | |
// Try to guess based on file extension. | |
type = { | |
"avi": html5media.H264_FORMAT, | |
"mp4": html5media.H264_FORMAT, | |
"mkv": html5media.H264_FORMAT, | |
"h264": html5media.H264_FORMAT, | |
"264": html5media.H264_FORMAT, | |
"avc": html5media.H264_FORMAT, | |
"m4v": html5media.H264_FORMAT, | |
"3gp": html5media.H264_FORMAT, | |
"3gpp": html5media.H264_FORMAT, | |
"3g2": html5media.H264_FORMAT, | |
"ogg": html5media.THEORA_FORMAT, | |
"ogv": html5media.THEORA_FORMAT | |
}[src.split(".").slice(-1)[0]]; | |
return type || html5media.assumedFormat; | |
} | |
// Detects presence of HTML5 attributes. | |
function hasAttr(element, attr) { | |
var val = element.getAttribute(attr); | |
return val == true || typeof val == "string"; | |
} | |
/** | |
* Default callback for creating a fallback for html5 video tags. | |
* | |
* This implementation creates flowplayer instances, but this can | |
* theoretically be used to support all different types of flash player. | |
*/ | |
function createVideoFallback(video) { | |
// Standardize the src and poster. | |
var baseUrl = window.location.protocol + "//" + window.location.host; | |
function addDomain(url) { | |
if (url.substr(0, 1) == "/") { | |
return baseUrl + url; | |
} | |
return url; | |
} | |
var poster = addDomain(video.poster || ""); | |
var src = video.src; | |
if (!src) { | |
// Find a h.264 file. | |
each.call(video.getElementsByTagName('source'), function (source) { | |
if (guessFormat(source.src, source.type) == html5media.H264_FORMAT) { | |
src = source.src; | |
} | |
}); | |
} | |
src = addDomain(src || ""); | |
// Add in the replacement video div. | |
var replacement = document.createElement('div'); | |
"className id title".split(' ').forEach(function (k) { | |
replacement[k] = video[k]; | |
}); | |
replacement.style.width = video.width + 'px'; | |
replacement.style.height = video.height + 'px'; | |
video.parentNode.replaceChild(replacement, video); | |
// Activate flowplayer. | |
var flowplayerControls = null; | |
if (hasAttr(video, "controls")) { | |
flowplayerControls = { | |
url: html5media.flowplayerControlsSwf, | |
fullscreen: false, | |
autoHide: "always" | |
} | |
} | |
var playlist = [{ | |
url: src, | |
autoPlay: hasAttr(video, "autoplay"), | |
autoBuffering: hasAttr(video, "autobuffer"), | |
onBeforeFinish: function() { | |
return !hasAttr(video, "loop"); | |
} | |
}]; | |
if (poster) { | |
playlist.splice(0, 0, {url: poster}); | |
} | |
flowplayer(replacement, html5media.flowplayerSwf, { | |
play: null, | |
playlist: playlist, | |
clip: { | |
scaling: "fit", | |
fadeInSpeed: 0, | |
fadeOutSpeed: 0 | |
}, | |
plugins: { | |
controls: flowplayerControls | |
} | |
}); | |
} | |
// must be included before </body> or after all video elements | |
html5media(); | |
})(this, document); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment