Skip to content

Instantly share code, notes, and snippets.

@rwaldron
Created February 3, 2011 00:06
Show Gist options
  • Save rwaldron/808791 to your computer and use it in GitHub Desktop.
Save rwaldron/808791 to your computer and use it in GitHub Desktop.
H264 Support Revision
<!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>
/*
* 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);
@rwaldron
Copy link
Author

rwaldron commented Feb 3, 2011

Feel free to offer suggestions for improvement. That's how I roll.

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