Archive for the ‘Software’ Category

An automated and rock-solid encoding engine solution for your youtube-like site.

Tuesday, August 5th, 2008

It was some days ago when i was contacted by one of the visitors of this blog in order to create a "black box" solution to solve the video encoding part of a video sharing website similar to youtube.com.

As you maybe know, i have posted some months ago a really basic script to automate some of the tasks, but, what about integration with your actual website framework ? what about queue management, what about multi-server encoding environment ?

Those are all the usual questions when a potential customer calls, so i spent some days developing a complete black-box solution for this issue, using all open-source software, with the following features.

  • Fully automatic video encoding queue management.
  • Support for 1 to n encoding nodes with fully automatic transaction control (still in beta-testing).
  • Support for the following video formats: Windows Media, Quicktime, DV, Avid DV, DivX, xVid and almost any imaginable format (any format supported by mplayer is actually 100% supported)
  • Support for HE-AAC audio (Stereo near-CD quality sound at 48kbps).
  • Fully automatic thumbnail generation in 3 different positions of the video stream, supported output formats are JPG, PNG and GIF.
  • Fully automatic metadata injection, including all the popular "iTunes like" tags.
  • Fully automatic iPod Touch / iPhone compatible stream generation.
  • Support for more than 1 output format (managed from a presets file).
  • Fully automatic Pixel and Display aspect ratio correction for proper video resizing and scaling.
  • Possibility to select how many CPU cores to use for the encoding process (only on multicore cpu's)

There are a several more features that I'm still developing. If you are interested and you want more details, you can contact me at: diego (at sign here) massanti.com. I don't bite ;)

Keeping track of your users hardware / Software with Sparkle and PHP.

Tuesday, April 15th, 2008

Some months ago I started using the amazing Sparkle framework to manage the auto-update features on my MediaInfo Mac application, and it wasn't until today that I decided to update my Sparkle version to the latest one from the SVN and give it a try, mostly because I'm planning to release upcoming MediaInfo Mac builds as 32 and 64bit Universal Binaries, but that's a different story.

I have found that with the new Sparkle version, you can kindly ask the user if he/she wants to send anonymous information about the system they are using to run your application, like the MacOS version, amount of RAM, number of processors, language, etc. This is specially useful for many reasons (at least for me), first, I'm starting the process of localizing my application, so that gives me a pretty good idea of what languages are the most used so far, and, finally, it will let me now when I could stop caring about Tiger and start a Leopard only version of my Software.

The idea is pretty simple, you have a PHP script that generates the whole AppCast compatible feed, and all the hardware / software information is passed as url parameters, as in feed.php?osVersion=10.2.5&lang=en ... etc.

So, by using good old Google, i found a really good script to generate the AppCast feed, but, i also needed a way to store the tracking data into a DB for later usage, and, i came up with this (really barebones, but working) prototype.

So, i did some minor modifications to the original PHP code; first, i changed the way to parse the version number from the file names, so as long as you use the application_name_1.5.zip pattern it will work, please note that you can put as much revision or subversion numbers as you wish: application_name_1.2.3.4.5.zip should also work.

This is the code snippet as i have it working now on my development server:

<?php
// ----------------------------------------------------------- //
// Script to generate an RSS appcast from folder contents
// Version 1.0.1
//
// (cc) Random Sequence 2007, Some Rights Reserved
//
// Licenced under a creative commons Attribution ShareAlike licence
// http://creativecommons.org/licenses/by-sa/3.0/
// ----------------------------------------------------------- //   
 
// REQUIRES PHP 5 or greater
// Tested with APACHE 1 & 2 on Mac OS X, Debian Linux   
 
// -------------------- BEGIN CONFIG ------------------------- //
 
$title = "Downloads";           // Used as feed title in feed readers
$description = "File List";     // Used as feed description in feed readers
 
// these are the types of files to list in the appcast & their MIME Types. Use lower case.
$fileTypes = array( "zip"=>"application/zip",
                    "tgz"=>"application/x-gtar",
                    "tar"=>"application/x-tar",
                    "dmg"=>"application/octet-stream"
                    );
 
// -------------------- END OF CONFIG ------------------------ //
 
$appcastHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<rss version=\"2.0\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:sparkle=\"http://www.andymatuschak.org/xml-namespaces/sparkle\">
<channel>
    <title>*title*</title>
<link>*link*</link>
    <description>*description*</description>
    <language>en</language>
";
$appcastTemplate = "
        <item>
            <guid  isPermaLink=\"false\">*guid*</guid>
            <title>*title*</title>
            <description>*description*</description>
<pubDate>*pubdate*</pubDate>
            <enclosure
                sparkle:version=\"*version*\"
                type=\"*type*\"
                url=\"*url*\"
                length=\"*length*\" />
        </item>";
 
$appcastFooter = "
</channel>
</rss>";
 
$files = scandir(getcwd());
$etag = sha1(implode("/",$files));
 
// support for conditional fetch
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) {
    header('HTTP/1.1 304 Not Modified');
    exit;
}
 
$appcast = $appcastHeader;
 
$link = "http://".$_SERVER["HTTP_HOST"].$_SERVER["PHP_SELF"];
 
$appcast = str_replace("*link*",$link,$appcast);
$appcast = str_replace("*title*",$title,$appcast);
$appcast = str_replace("*description*",$description,$appcast);
 
foreach ($files as $file) {
    preg_match("/.*\.([a-z09]{1,3})$/i",$file,$matches);
    if (isset($matches[1]) && isset($fileTypes[strtolower($matches[1])]) !== false) {
        $appcastFile = $appcastTemplate;
 
        $folderUrl = "http://".$_SERVER["HTTP_HOST"].substr($_SERVER["PHP_SELF"],0,strrpos($_SERVER["PHP_SELF"],"/"))."/";
 
        $guid = $folderUrl.sha1($file);
        $title = $file;
        $description = preg_replace("/^(.*?)([0-9]+[a-z])\.([a-z09]{1,3})$/i","$1",$file);
        $pubdate = date("D, d M Y H:i:s",filectime($file));
        $type = $fileTypes[strtolower($matches[1])];
        $url = $folderUrl.$file;
        $length = filesize($file);      
 
        // Modified by Diego Massanti
 
        preg_match("/(\d+\.)+\d+/", $file, $m_version);
		$version = $m_version[0];
 
		// End of Mod.
 
		// $version = preg_replace("/^(.*?)([0-9]+[a-z])\.([a-z09]{1,3})$/i","$2",$file);
 
        $appcastFile = str_replace("*guid*",$guid,$appcastFile);
        $appcastFile = str_replace("*title*",$title,$appcastFile);
        $appcastFile = str_replace("*description*",$description,$appcastFile);
        $appcastFile = str_replace("*version*",$version,$appcastFile);
        $appcastFile = str_replace("*pubdate*",$pubdate,$appcastFile);
        $appcastFile = str_replace("*type*",$type,$appcastFile);
        $appcastFile = str_replace("*url*",$url,$appcastFile);
        $appcastFile = str_replace("*length*",$length,$appcastFile);                                    
 
        $appcast .= $appcastFile;
    }
}
 
$appcast .= $appcastFooter; 
 
// Database Functions
 
// Fill an array with the options we care about
$vars = array('osVersion' , 'cputype', 'cpusubtype', 'model', 'ncpu', 'lang', 'appName', 'appVersion', 'cpuFreqMHz', 'ramMB');
 
// Initialize an empty array to store results
$values = array();
 
// We start assuming that we are getting all the values we want
$shouldInsert = true;
 
// If any of the values is not sent, then we dont want incomplete info, right ?
foreach ($vars as $item) {
	if (isset($_GET[$item])) {
		$values[$item] = html_entity_decode($_GET[$item]);
	} else {
		$shouldInsert = false;
	}
}
 
// If we have all the data, then let's store it in our DB.
if ($shouldInsert == true) {
	$mysqli = new mysqli("localhost", "yourDBuser", "yourDBpass", "yourDBname");
 
	// If you want your feed to be reachable EVEN if something is REALLY wrong with your DB, then comment the following block
	if (mysqli_connect_errno()) {
	    printf("Connect failed: %s\n", mysqli_connect_error());
	    exit();
	}
 
	// Prepare the query
	$stmt = $mysqli->prepare("INSERT INTO stats (osVersion, cputype, cpusubtype, model, ncpu, lang, appName, appVersion, cpuFreqMHz, ramMB) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
	// Bind the parameters
	$stmt->bind_param('sississsii', $values['osVersion'], $values['cputype'], $values['cpusubtype'], $values['model'], $values['ncpu'], $values['lang'], $values['appName'], $values['appVersion'], $values['cpuFreqMHz'], $values['ramMB']);
	// Execute the query
	$stmt->execute();
	// Bingo!
	$stmt->close();
 
}
 
// Send the feed.
 
header("Content-type: application/xml; charset=UTF-8");
header("ETag: $etag");
 
echo $appcast;
exit;
?>

As usual, suggestions or improvements are welcome ;)

MediaInfo Mac 0.7.6.30 update released

Sunday, April 13th, 2008

Hi there, just a quick note to let you know that a new version of MediaInfo Mac (0.7.6.30) has been released, not only it includes several bugfixes and improvements in the Cocoa arena, but also a new build of the MediaInfo engine which features the following improvements:

  • AVC: Count of reference frames.
  • AU: Comments.
  • Some global speed improvement.
  • Id3v2: Unsynchronized frames support (v2.3 & v2.4).
  • MKV: handling of files created for streaming.
  • MPEG-4: Handling of corrupted stream size info with some PCM streams.
  • DVD video: Hebrew patch ("iw" code is mapped to Hebrew).
  • MPEG-4: better handling of bitrate mode (VBR or CBR).
  • AVI: MediaInfo reads now the framerate value from the container rather than the stream value.
  • AC3: TrueHD detection.
  • MPEG-TS (or Bluray): VC-1, AC3+ and AC3 TrueHD detection.
  • AVC in MKV: all SEI userdata infos from x264/eavc in Writing library settings.
  • EVO: Better detection of duration.
  • Dirac: raw files parsing.
  • MPEG-TS: Dirac management.
  • MPEG-TS: DVB subtitles/Teletext management.
  • MPEG-4 Visual (DivX/XviD): writing library name was missing.
  • MPEG-Video: some DTS files with wrong extension were detected as MPEG-Video.
  • SWF: Compressed SWF files support is back.

If you are an actual user, just launch the application and use the auto update feature, or you can get the latest version by visiting the official MediaInfo Mac website.

As usual, feel free to leave any comment or suggestion in here.

Enjoy :)

iPhone’s “Code Signing”: Is there any limit for the ridiculous ?

Sunday, March 9th, 2008

Some hours ago i was pointed to an interesting post about the new "code signing" features that Apple is going to implement for the iPhone software developers, and honestly, I am speechless...
There was a time when i used to believe that there was a good reason for Apple to be so closed in some aspects: To keep the user experience as clean and smooth as possible.
That could explain several behaviors in the iTunes Music Store, in the iPod and of course in the whole Mac platform, but after reading several times this great article at Rogue Amoeba's blog, just one thing comes to my mind... "is there any limit ?".

I still can't believe the fact that it is just NOT possible to load an application inside an iPhone unless it's blessed (read: digitally signed) by Apple, and yes, you read it right, not even for testing purposes, which means that if you want to start writing some code for the iPhone, you have to a) buy a $99 testing certificate, and b) buy an extra iPhone compatible with that extra certificate.
But the story continues....

Apple seems to have a list of things that they are not going to bless, like for example Porn, or "Bandwidth Hog" applications, and there is also the "unforeseen" category, which translated to plain English means "anything that we don't like at all or we consider bad for our business model".

I happen to believe that protecting the user experience as much as you can is a good thing, and that is mainly the reason because Mac OS is more enjoyable than any other OS out there, no discussion there, but when a company starts telling me what I am allowed to run (or not) on a device that i OWN, I think that something is really wrong. In my particular case, I don't own an iPhone (and not even planning to own one, mostly because I use Nextel, and I wouldn't change it for anything), for the contrary i own a Motorola headset, and i can load any application on it, or even write my own if I feel like.

No matter how much I love Apple and their products, I think that freedom of choice is one of the most valuable things that our society must protect, and while I read a lot of forum / blog posts by the so called "Apple fanboys" saying things like "if you don't like it, don't buy it" I just don't want to believe what could happen if a company with this way of thinking becomes the market leader.

I have yet to see the evolution of this whole thing, but right now this just makes me re-think if some other eternally blamed companies are really sooooo evil after all...

MediaInfo for Mac: Know everything about your media files.

Wednesday, January 30th, 2008

You should consider this piece of software my "hello world" project in the Mac development arena, because, even the fact that i have pretty good skills when it comes to OO development, I'm totally new when it comes to the Mac, and I'm using this project mainly as a learning experience.

Attention: download links were moved

In order to keep things organized, the download links and general information for MediaInfo Mac were moved into this new website.

MediaInfo Mac ScreenshotIn the past few days i have been working in a full Aqua version of a linux tool called "Mediainfo", so this is the result.
Let me introduce you to "MediaInfo Mac".

MediaInfo Mac does just one thing: it gives you a lot of information about multimedia files, even files that QuickTime can't read, and it does that by using a custom Universal Binary build of the linux library "libmediainfo" by Jerome Martinez as its core.
This application is obviously OpenSource and i will make all the sources available as soon as i finish cleaning the code and configuring an SVN repository on this server.
MediaInfo Mac requires any PowerPC or Intel Macintosh computer running MacOS X 10.4 "Tiger" or newer.
If you have any question or suggestion, feel free to leave your comment below :).

A BIG thank you goes to Rainer Brockerhoff, (who is a true monster in the Macintosh development area), for having the patience to answer a lot of my questions, and also, to the guys at #macdev on freenode for helping me to understand a lot of things in the "Cocoa Arena". Thank you, i really appreciate your time.

In order to keep things in organized, anything in relation with MediaInfo Mac is going to be on this new website.

IF you are any kind of software tracker, there is a feed with MediaInfo updates, and it is compatible with the AppCast definition.