Embed HTML5 Video Seamlessly

Posted by tigerhawkvok on January 18, 2010 23:02 in programming , internet

Designing for some sites this weekend, I finished up a PHP wrapper that enables HTML5 <video> playback seamlessly on sites. The whole process is broken into very few steps:

One-Time Steps

  • Download LongTailVideo's JW Player, extract it, and put player.swf into a directory named "modular".
  • Into the same directory, save this fallback, explanatory image.
  • Create a folder named "videos".
  • Place the following code in an included PHP file, or somewhere else in your PHP document:
function embedVideo($file, $width=NULL,$height=NULL,$title=NULL,$poster=NULL,$force_mime=NULL)
  // code based on http://camendesign.com/code/video_for_everybody
  // encode video used by this as Ogg and h.264 / mp4
  // Make sure the $file provided is the FULL URL to the files, with no extension
  if($width==NULL) $width=640;
  if($width==NULL) $height=360;
  if($poster!=NULL) {
    $flashposter = "&image=$poster";
    $poster = "poster='" . $poster . "'";
  else $flashposter="";
  $objheight = $height + 15;
  $swfheight = $height + 20;
echo "<div class='video'>
       <video width='$width' height='$height' $poster controls='controls'>";
if ($force_mime) {
  //Mimetype fix for certain server configurations
  $location[$len-1]="?name=" . $location[$len-1];
echo "
	<source src='$file.ogv' type='video/ogg' />"; 
if ($force_mime) $file=$fileold;
echo "
	<source src='$file.mp4' type='video/mp4' /><!--[if gt IE 6]>
	<object width='$height' height='$objheight' classid='clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B'><!
	[endif]--><!--[if !IE]><!-->
	<object width='$width' height='$objheight' type='video/quicktime' data='$file.mp4'>
	<param name='src' value='$file.mp4' />
	<param name='showlogo' value='false' />
	<object width='$width' height='$swfheight' type='application/x-shockwave-flash'
		data='modular/player.swf?file=$file.mp4" . $flashposter . "'>
		<param name='movie' value='modular/player.swf?file=$file.mp4" . $flashposter . "' />
		<img src='modular/no_vid.png' width='$width' height='$height' alt='$title'
		     title='No video playback capabilities, please download the video below' />
	</object><!--[if gt IE 6]><!--></object><!--<![endif]-->
       <p>Download Video: <a href='$file.mp4'>'MP4' (h.264)</a> | <a href='$file.ogv'>'OGG' (theora)</a></p>

Now, go into the "videos" folder. Create a file named ".htaccess" and add the following:

AddType video/ogg .ogv
AddType application/ogg .ogg

That will work on many server configurations, but not all. In case your server is stupid (ie, will not honor the .htaccess file), also create a file "index.php" and insert the following:

$video = basename($_GET['name']);
if (file_exists($video)) {
  $fp = fopen($video, 'rb');
  header('Access-Control-Allow-Origin: *');
  header('Content-Type: video/ogg');
  header('Content-Length: ' . filesize($video));
} else {
  echo "404 - video not found";

OK, your server-side stuff is done. You only need to do all that stuff once.

Each Time

Now, you can make your video. Make your video however you want, but when you're done, head over to firefogg.org in Firefox 3.5+ and convert your video. Essentially any settings available there will work (as the point of the extension is to leave it playable in a browser). You can use other programs, but this one is more-or-less foolproof. Then, use Handbrake to convert your video into H.264. Make sure your video is saved as *.mp4, and has the same name as the *.ogv file. You should now have two versions of your video. Dump both of them in your videos folder.

Now, embedding your video? It's easy. Just stick in the following code when you want to spit out your video:


The first argument is a string with a path to your encoded videos. Don't include the file extension; the code takes care of that. All subsequent values are optional. The first one is video width, second video height, third video title, fourth a thumbnail for the video (I use the method suggested by the Theora Cookbook), if you made one. The final value only does anything if it's TRUE. Stick in "TRUE" if the video isn't playing in FireFox, and it'll feed the video through the index.php in your video's directory and it'll work automagically.

The code is XHTML5 compliant, and has no rendering errors when submitted to the browser with the XML mimetype. I've tested it in IE6, IE8, Chrome 4, Firefox 3.6, Opera 10.5, and Safari 3 for Windows.

Enjoy! I need to update LifeType to get it working on the blog, but you can see the code in action on one of Velociraptor Systems's sample pages. This code is free to use, and released under Creative Commons/GNU Lesser General Public License 2.1.. Let me know if there are any problems implementing it!

Emacs, ruler of the world

Posted by tigerhawkvok on December 08, 2009 19:13 in programming

Ignore this for the moment. This is just a test post using Emacs and XML-RPC to post to the blog.

Seems that this may not work with categories. Hm.

Perils of Non-FOSS

Posted by tigerhawkvok on December 08, 2009 18:41 in research , programming

Poking around my archives, I find that I've somehow managed to lose my IDL installation backups, while keeping my carefully configured startups and such. Of course.

Seeing as I had a bout of inspiration to do work on my research and, well, finally re-submit it (It's been nine months!), I suddenly find that my customized scripts to churn out quick calculations and the nice eps plots are useless, as I can run IDL for all of 15 minutes.

Damn. I need to see what Python's plotting options look like. Look for a tetrapod post later tonight.

SVGs and Browsers

Posted by tigerhawkvok on November 05, 2009 20:15 in computers , programming , websites , internet

First, I realize I missed this week's Tuesday Tetrapod. I'll put up a double-feature next week — but I've been trying to meet a personal deadline and didn't quite have time to give the TT the attention it deserved. So, let me touch a little bit on SVGs and, thus, in a roundabout way, what's been occupying my time.

First, "SVG" stand for "Scalable Vector Graphic". As the image at the right demonstrates, zooming in on raster graphics such as bitmaps, PNGs, or JPGs introduces artifacts. Further, if you want to reuse the image, you cannot scale it beyond a certain resolution. Vector graphics, on the other hand, are very much like text in that their descriptions are essentially plaintext describing how lines arc. The lines arc the same way no matter how zoomed in you are, so they are rendered on the fly by computers. This means that they are infinitely resizeable, and retain fidelity limited only by the physical pixel sizes on your monitor.

Now, the problem is, of course, Internet Explorer. It's not the only problem, but the main one. See, IE doesn't support SVGs at all. Just can't do a thing with them. While Firefox has finally passed IE6 in market share, IE still holds ~65% of the global market (though on technical sites, its market share is closer to 20%). So this was a game-stopper to SVG adoption.

However, in October Google released the SVGWeb library, which is a simple Javascript library that renders SVGs on IE in Flash, and displays them as a Flash document. Suddenly, in one blow, SVG has a nearly universal level of application. If NetApplications is right, a combined implementation has a 98.88% market share penetration. Now, this isn't quite right, as Flash still doesn't support 64-bit browsers, so users of Internet Explorer 64-bit are out in the cold — but most users of 64-bit operating systems, even those that use IE, use the 32-bit version, so that's pretty negligible.

Now, with that hurdle done with, we have a few other hoops to jump through. First, of Gecko, Webkit, and Presto-based browsers (read: Firefox, Safari + Chrome, and Opera), Gecko and Webkit each incompletely support external SVG resources with the two tags that should work, <object> and <img> (Presto properly supports both). Gecko does not support <img> at all, and instead displays the alt-text; Webkit supports <object> but manipulating sizes and such does not work.

Now, I wanted to use an SVG-based logo on my site, and I was fed up with this implementation problem, so I wrote up a simple PHP library to get SVG working conveniently on multiple browsers. Now, to use an SVG, all you have to do is


Where everything in the square brackets is optional (do note, however, that if no height or width is specified IE will default to 100px by 100px). So, for example, on this implementation test page, the logo with the yellow background is just in:

	    <div style='background:yellow;width:500px;height:600px;'>
	      <?php dispSVG('assets/logo.svg','logo',450); ?>

That's it. Nice, simple, clean and cross-browser. All you have to do is extract the library to your server in a location, edit the $relative variable in svg.inc if it's not in the root directory, and paste the following into the head of your (X)HTML document:

require('PATH/TO/svg.inc'); // edit this path
if(browser_detection('browser')=='ie') echo ""; 

Once you've done that, you're done! Just call dispSVG whenever you want to display an SVG. By giving the ID or class calls a value, you can address your SVG as normal in you CSS. Nice and easy! It's not quite perfect, as CSS background only works with Presto (of course. Go Opera!), but it works for most uses.

Now, all that is because I'm working on creating a site to advertise my website creation and deliver built-to-order computers for customers. The computer building system is almost done, requiring some modification on the last four system types to give configuration options. Then I just need to generate some content for the other pages, and it'll go live!

So, I ask (what readers I have) a favor: Can you please check out the site, and give me any stylistic, functional, or content critiques, reccommendations, or comments you may have? With luck, soon it should have the proper domain http://www.velociraptorsystems.com/!

Evolving AI 2: A Programmatic Brain

Posted by tigerhawkvok on September 24, 2009 18:11 in computers , evolution , programming

OK, I lied. Programming the brain first, even though I wrote it as if I wrote about the body already, it should still mostly make sense.

The core fact to realize about our own conciousness, etc, is the fact that we are not programmed with it. Trying to program self-awareness into a computer simulation has problems because there is no place to start from. Our behaviour is an emergent behaviour, so we need to duplicate this in an simulated fashion.

Given that we've already talked about the modularity of the body plan, how is this body controlled? We assign a virtual neuron cluster to each point of freedom, with each virtual cluster having members equal to the granularity we want to start with. Thus, consider the human elbow. It would be one virtual neuron cluster to control its up-and-down motion (like you're flexing your arms). The number of virtual neurons in this cluster is determined by:

  • 1 per degree of rotation. About 160 for the human elbow.
  • Each virtual neuron can have an arbitrary number of connections within the cluster, but regardless of input signals recieved only outputs one unit of amplitude. We then have 160 control neurons with one "lead" outside the cluster. Control neuron 2 fires two movement neurons, instigating a 2o rotation. Control neuron 139 fires 139 movement neurons, for a 139 degree rotation. Thus, "basic" members in the available movement pool have more connections (more control neuron connections) than more extreme members (ie, movement neuron 160 is only connected to one control neuron)

These virtual neuron clusters are then batched into virtual superclusters, controlling the larger body segment. So, a human shoulder would have one cluster for swinging rotation, one for "flapping" rotation (like jumping jacks). The supercluster has a set of control neurons, broken into a few classes:


Evolving AI 1: Evolutionary Trajectory

Posted by tigerhawkvok on September 24, 2009 16:05 in computers , evolution , programming

I was thinking about AI, and I came to the conclusion that, well, computer scientists are doing it wrong. This is a problem with computer scientists trying to do something incredibly improbable, and incredibly difficult, in one giant step.

Instead, I posit, we need to take the route that evolution took, and evolve our way to an artificial intelligence. Much of our behaviour (and after all, we want to get something basically human) is baed on our evolutionary history. We don't think about being happy — we don't go "oh hey, my brain is telling me that for social reasons it's a great idea to smile right now, because I happen to be happy", either. We just do it — that's the essence if instinct, and much of it is vital to the way an AI would need to behave.

Along with my much delayed series on web design, I'm going to write a brief series on how I believe one could evolve their way to AI, but by doing so at a vastly different level than has been done before. This will focus on 4 things:

  • Directed evolutionary paths — how to drive a model organism to intelligent behaviour
  • Modelling parameters and sensory analogs inside a virtual world
  • Controlling behaviour in a virtual environment
  • Population sizes and sexual vs. highest-fitness reproduction
  • CS and engineering implications of this approach

The crux to this whole thing is that, ironically, we'd need to bastardize evolution a shade to pull this off, as we'd play the dubious role of a "guided intelligent designer". Since the model computer world would, necessarily, have less than 5 x 1014 m of surface area, and run what I term "sequence events" at slower than real time, without the vast variation of the Earth's surface, we can't hope to ever run a full simulation of 350 MY or so.

Instead, we would run small sequence events that build on each other, eliciting certain classes of behaviours in medium populations (say, 50 individuals). After their rate of change has stabalized for, say, 1,000 generations, modify the conditions of their environment and pick the top 50% of individuals to expand their behavioral repretoire. Every 100 generations or so, a population snapshot can be made for research, fallback, and archival purposes. Only the top 50% of individuals (of each sex) are always allowed to breed, randomly, with each other, at exactly replacement rate. The only things modified by the programmer (after initial set-up) are the environment, a "fitness bonus" for certain goals, and a "fitness function" that assigns a fitness value to each individual for a given point on the evolutionary trajectory.

I propose an evolutionary trajectory as follows:


Phylogenies Everywhere

Posted by tigerhawkvok on September 14, 2009 14:36 in computers , evolution , biology , programming , websites , internet

A surprising amount of this weekend was dedicated to working on phylogenies. I updated non-eusuchian crocodylomorphs, avialae through neoaves to at least extant order; minor updates to sauropoda, and an update on sauropterygia.

The site also finally got a long-needed search engine. It's not the most efficient thing in the world, but doing a binary search is essentially useless. I made it modular, so I may still end up seeing how a sort + binary search with preserved keys turns out, or cut out the cruft (change the amount of the document searched).

I finally also added a dirty implementation of tagging. I used the <tt> (teletype) tag and changed its contents to not display (CSS display:none). Thus, tags for an entry can be hidden in this element, and will be read by the search engine, but not displayed.

I also noticed that it was hard to find some of the sources I cited with just name and year — so I've started adding linkouts, DOIs, or ISBNs too all sources provided, to make it easier in the future.

Kind of looks less in writing than it felt like ... but I'm happy with the way it's going.

Is it a weasel? Methinks it is.

Posted by tigerhawkvok on August 30, 2009 23:11 in computers , biology , programming , misc science , internet

Since I've wasted most of today on this (oh feature creep. And an extra "-1".), I thought I'd share. Reading around on Pharyngula, I found myself wanting to make a more customizable, even-less-preprogrammed version of Richard Dawkin's WEASEL program. So, I present you with a Python 3.0+ version of Dawkin's "Methinks it is a weasel" program. It will take any nonzero length starting string, has a maximum generational cap for local maxima, with customizable rates for single-bit errors (like SNPs), duplication errors, number of offspring, weighting for approaching the target sequence, and accepted variability, and whether bad mutations are penalized or not.

Sample output. Click for larger / more lines.

The point of the program, as published in The Blind Watchmaker, is to show that with random mutations over time you can expect to see something like order pop out of a random test string. The version I have below takes the genetic modelling a bit further, starting with any string, regardless of length, and duplication / omission errors will trim down to the right solution. In debug mode, there's an additional completely random selection every 500 generations to help pull the program out of local maxima, but it is not in the primary program.

Click the fold to read the source, or download it here


Javascript - Definitely written in the 90s

Posted by tigerhawkvok on March 15, 2009 17:56 in computers , programming

Higgs is still coming, but I wanted to comment on the absurdity of Javascript. It lacks an elementary function — the ability to import code from an existing external file (within an existing javascript script). Even the obvious hack doesn't work:

<script type='text/javascript'>
document.write("<script type='text/javascript' src='code.js'></script>");

So, there, I'm trying to import "code.js" to execute within a greater block of Javascript. The practical upshot of this is that you can, for example, conditionally run a block of code (say, with this only executing when an IF statement evaluates). So, what's wrong with this little code block? I mean, its a bit hack-y, but really, what's wrong? Well that code outputs:


The answer? You can't have a script closing tag in the document.write function, and to the best of my knowledge, you can't self-close a script tag. Thus, you need to hack it like so:

<script type='text/javascript'>
document.write("<script type='text/javascript' src='code.js'></scr"+"ipt>");

Small change, but amazingly nonobvious. Took me a long time to figure it out. And thus ends this rant.

Moral of the story? Stick with PHP and CSS. They're more standards-compliant, and way more intuitive. For example, they'd just use:

include("code.php"); // code.inc in some contexts ?>


<style type='text/css'>
@import "css_sheet.css"; /* This has different uses from <link> */

Much better, and much more intuitive!

Lets close this with something a bit less "ranty". It turns out that, finally, you can customize your logon background in Windows 7 without third party hackery — though you still need to do a few reg changes to pull it off.