Created
February 3, 2011 00:06
-
-
Save rwaldron/808791 to your computer and use it in GitHub Desktop.
H264 Support Revision
This file contains hidden or 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>H264</title> | |
<script src="h264.js"></script> | |
</head> | |
<body> | |
<video id='video' style="display:" | |
controls> | |
<source id='mp4' | |
src="http://media.w3.org/2010/05/sintel/trailer.mp4" | |
type='video/mp4; codecs="avc1, mp4a"'> | |
<p>Your user agent does not support the HTML5 Video element.</p> | |
</video> | |
</body> | |
</html> |
This file contains hidden or 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
/* | |
* H264 Substitution | |
* Version 0.1.0 | |
* | |
* Inspired by Windows Media Player HTML5 Extension | |
* | |
* Copyright (c) 2011 Rick Waldron | |
* Dual licensed under the MIT and GPL licenses. | |
* http://code.bocoup.com/license/ | |
*/ | |
(function ( win, doc ) { | |
var H264 = { | |
support: { | |
mime: [ "video/mp4", "video/x-ms-wmv" ], | |
exts: [ ".mp4", ".wmv", ".mp4v", ".m4v" ], | |
hasBaseSupport: ( doc.createElement("video").canPlayType("video/mp4; codecs='avc1.42E01E'") !== "probably" ? false : true ) | |
}, | |
media: { | |
isSupported: function( vos ) { | |
var str = ( vos.type || vos.src ).toLowerCase(), | |
index = vos.type ? str.indexOf( ";" ) : str.lastIndexOf( "." ), | |
accepts = H264.support.mime.concat( H264.support.ext ), | |
idx = 0, | |
test; | |
if ( index === -1 ) { | |
return false; | |
} | |
test = vos.type ? str.slice( 0, index ) : str.slice( index ); | |
return ( accepts.indexOf( test ) >= 0 ) ? true : false ; | |
}, | |
sources: function( video ) { | |
if ( video.src && H264.media.isSupported( video ) ) { | |
return video.src; | |
} | |
var sources = video.getElementsByTagName( "source" ), | |
supported = null, | |
idx = 0; | |
if ( !sources.length ) { | |
return supported; | |
} | |
for ( ; idx < sources.length; idx++ ) { | |
if ( sources[ idx ].src && H264.media.isSupported( sources[ idx ] ) ) { | |
supported = sources[ idx ].src; | |
} | |
} | |
return supported; | |
} | |
}, | |
controls: function( video ) { | |
var isSupported = H264.media.sources( video ); | |
if ( !isSupported ) { | |
return null; | |
} | |
var control = doc.createElement("object"), | |
bounds = { | |
width: "Width", | |
height: "Height" | |
}, | |
pads = { | |
width: [ "Right", "Left" ], | |
height: [ "Top", "Bottom" ] | |
}, | |
dims = { | |
width: 320, | |
height: 240 | |
}, | |
copy = [ "id", "dir", "className", "title", "draggable", "lang", "spellcheck" ], | |
idx = 0, | |
prop, | |
uiControls, param, params; | |
for ( prop in bounds ) { | |
control[ prop ] = ( function ( video ) { | |
var ret = video[ prop ]; | |
if ( ret <= 0 ) { | |
if ( video[ "client" + bounds[ prop ] ] ) { | |
// set the returning bounds dimension | |
ret = video[ "client" + bounds[ prop ] ]; | |
// Adjust dims for padding and radix | |
ret -= parseInt( ( video.style[ "padding" + pads[ prop ][ 0 ] ] || 0 ) + | |
( video.style[ "padding" + pads[ prop ][ 1 ] ] || 0 ), 10 ); | |
} | |
} else { | |
// set the returning bounds dimension | |
ret = dims[ prop ]; | |
} | |
// return the bounding box dimension | |
return ret + "px"; | |
})(video); | |
} | |
// Copy all the props needed as defined | |
for ( ; idx < copy.length; idx++ ) { | |
prop = copy[ idx ]; | |
if ( video[ prop ] ) { | |
control[ prop ] = video[ prop ]; | |
} | |
} | |
// Copy all the styles | |
for ( prop in video.style ) { | |
control.style[ prop ] = video.style[ prop ]; | |
} | |
control.setAttribute( "type", "application/x-ms-wmp" ); | |
// Set uiMode | |
control.setAttribute( "uiMode", video.controls ? "full" : "none" ); | |
// Implicitly set autoplay mode | |
param = doc.createElement("param"); | |
param.name = "autostart"; | |
param.value = video.autoplay || false; | |
control.appendChild( param ); | |
// Implicitly set media url | |
param = doc.createElement("param"); | |
param.name = "url"; | |
param.value = isSupported; | |
control.appendChild( param ); | |
return control; | |
}, | |
convert: function() { | |
var videos = doc.getElementsByTagName("video"), | |
idx = 0, | |
video, controls, replaced; | |
// Return early if there are no videos to play | |
if ( !videos.length ) { | |
return; | |
} | |
for ( ; idx < videos.length; idx++ ) { | |
video = videos[ idx ]; | |
// Remove Mutation Listener - TODO: Replace logic, these are deprecated | |
video.removeEventListener( "DOMSubtreeModified", H264.convert, true ); | |
controls = H264.controls( video ); | |
if ( controls ) { | |
video.parentNode.insertBefore( controls, video ); | |
video.className = "h264_replacement_junk"; | |
} else { | |
// Add Mutation Listener - TODO: Replace logic, these are deprecated | |
video.addEventListener( "DOMSubtreeModified", H264.convert, true) | |
} | |
} | |
// This is the only part i liked | |
while( replaced = doc.querySelector( ".h264_replacement_junk" ) ) { | |
replaced.parentNode.removeChild( replaced ); | |
} | |
} | |
}; | |
win.H264 = H264; | |
})( this, this.document ); | |
document.addEventListener( "DOMContentLoaded", function () { | |
if ( !H264.support.hasBaseSupport ) { | |
H264.convert(); | |
} | |
}, false); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Feel free to offer suggestions for improvement. That's how I roll.