Archive for March, 2009

Published by Rolf on 18 Mar 2009

Fixing Flash CS3 and Java error, on a PC

So I saw this ugly message when trying to compile a SWF from an FLA: “Error initializing Java Runtime Environment

Flash CS3 (and CS4 I’m sure) apparently uses a Java compiler during the publish process, and perhaps other times too.  Unfortunately in CS3 it looks like it is hardcoded to a certain VM version as described here.  That guy’s directions apparently work on a mac, but I’m stuck on a PC, and symlinking isn’t an option there.

I had 1.6 (pretty much the latest version), so tried installing 1.5.0 (i.e., Java SE 5.0) side-by-side and renaming the folder in C:\Program Files\Java.  That had no luck so I uninstalled Flash, uninstalled all JRE’s, reinstalled 1.5.0, and reinstalled Flash CS3.  Still no luck.  Doesn’t appear that CS3 even installs Java after all that!

Very weird.

Published by Rolf on 16 Mar 2009

Gotchas with my reintroduction to the Facebook API

I’m prototyping a Facebook app, with the CakePHP framework as described here, and I hadn’t looked at the API for a few months, and never with my current hosting provider.  A few things I found out:

  1. The “sample code” gzip off Facebook’s SVN server has a much different layout than the one linked off the Quick Creation Guide popup.  Use the latter.
  2. Make sure you choose the right /client directory for your hosting provider.  I’m stuck with PHP4, and the directions assume you are using the PHP5 version.
  3. You may need to download the simplexml classes (as per this link).
  4. To save time you’ll want to run locally, but Facebook doesn’t allow “localhost” URLs for callbacks.  So workaround it with some DNS trickery by editing your hosts file.  However that only works if you’re not using FBML – if you are, then you’ll need an externally-accessible server.  In that case, you’ll have to open a new public port on your router firewall and forward it to your local webserver, then update the Facebook app callback url with your (current) WAN IP address and new public port.  As usual with opening ports, do so with caution!
  5. If you get the “server taking too long to respond error”, try hitting your localhost directly from another PC.  If you get any fatal errors (which for some reason don’t show up from localhost), then that will cause the error you see.  Obviously it’s not really a timeout error but a PHP one in that case; you’d think that Facebook would be able to hint that to the developer…
  6. Regarding CakePHP as a framework, note that vendor() has been deprecated.  Use this instead in app_controller.php:
    App::import('Vendor', 'facebook');
  7. Set CAKE_CORE_INCLUDE_PATH to some central directory so you can share one CakePHP installation among multiple apps.

Facebook folks – update your directions!

Published by Rolf on 05 Mar 2009

Tricks for debugging Vista Media Center plugins, part II

This is a followup to my earlier post about the development experience for MCE plugins.

First, check out the “Media Center Markup Language Preview Tool” page in the CHM help file that’s included with the SDK.  It gives a number of tips, the most helpful of which (and successful, I might add) is to launch McmlPad off to the side, using specific parameters that will force it to refresh when you make changes to any MCML files in a folder.  This allows for essentially real-time debugging of layout issues.  I wasn’t able to get the version hosted in MCE to work; only the standalone one.

I used this command to launch McmlPad, then moved it off to the side and left it open while I played with the MCML files in Visual Studio.  Change the paths and assembly names as needed for your app.

C:\Windows\eHome\McmlPad.exe -load:file://C:/shared/projects/hulu/HuluMCE/Markup/Test.mcml -assemblyredirect:"C:\shared\projects\hulu\HuluMCE\bin\Debug" -markupredirect:"resx://HuluMCE/HuluMCE.Resources/,file://C:\shared\projects\hulu\HuluMCE\Markup\,.mcml" -size:1000,562 -folder:"C:\shared\projects\hulu\HuluMCE\Markup"

Enjoy.

Published by Rolf on 04 Mar 2009

Tips for debugging RTMP traffic

Debugging network traffic is hard enough to start with.  When you’re trying to reverse-engineer a protocol like Adobe’s RTMP, then it becomes a nightmare.  These tips helped me a bit (but it still is painful):

  • A very throrough explation of the protocol is at http://wiki.gnashdev.org/RTMP
  • Use Wireshark for packet-sniffing (don’t bother with Fiddler, since it doesn’t support RTMP).  In the “Options”, make sure “Enable network name resolution” is checked.

Published by Rolf on 04 Mar 2009

Batch script to convert movies for Zune using ffmpeg

I have a first-generation Zune and am fairly happy with it.  Music-wise, it’s much better than an iPod since half my music is in WMA format and I’m not about to transcode it. Video-wise, though, it doesn’t decode anything but WMV.  This wouldn’t be such a big deal if the Zune software at least transcoded movies for you, but I’ve never had luck doing so (I think it chokes on anything using XVID codecs, for example).  And I haven’t found any free 3rd-party apps that work out of the box.

Fortunately, there’s the trusty ffmpeg to the rescue.  There are some Zune-optimized settings here, as well as a link to the latest Win32 binaries.  So, with the following Windows Script Host script I wrote, you can transcode a whole directory at once.

 
// batch_ffmpeg.js - encodes all AVI files in input directory to Zune-compatible WMV files
// Note, this doesn't do full recursion; only top-level.  Also overwrites existing files.
 
// syntax:   cscript batch_ffmpeg.js full_path_to_inputdir full_path_to_outputdir
// e.g.,     cscript batch_ffmpeg.js C:\videos\ C:\videos_for_zune
 
// edit this for your system
var ffmpeg_path = "C:\\shared\\ffmpeg\\bin\\ffmpeg.exe";
 
dirArgs = WScript.Arguments;
if (dirArgs.length != 2) {
    WScript.echo("Error: specify absolute paths to input and ouput directories.\n" +
        "e.g., cscript batch_ffmpeg.js C:\\videos\ C:\\videos_for_zune ");
    WScript.Quit();
}
 
var inputdir = dirArgs(0);
var outputdir = dirArgs(1);
 
WshShell = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");
 
log("Starting...");
 
var fileArr = new Array();
 
// push into an array, since Enumerators know their length...
var fc = new Enumerator(fso.GetFolder(inputdir).files);
for (; !fc.atEnd(); fc.moveNext()) {
    var file = fc.item();
    if (file.name.match("\.avi$") != null)
        fileArr.push(file);
}
 
for (var i=0; i<fileArr.length; i++)
{
    var file = fileArr[i];
    log("Processing " + (i+1) + "/" + fileArr.length + " - " + file.name + "\n");
    outputfile = file.name + ".wmv";
    cmd = ffmpeg_path + " -i \"" + inputdir + "\\" + file.name + "\" -y -vcodec wmv2 " +
        "-acodec wmav2 -s 320x240 -b 640000 " +
        "-maxrate 1350000 -bufsize 2048000 -ab 128000 -ac 2 " +
        "\"" +outputdir + "\\" + outputfile + "\"";
 
    log("Done processing.  Return status=" + WshShell.Run(cmd, 1, true));
}
 
log("Done.");
 
function log(str) {
    WScript.StdOut.Write("[" + getTimestamp() + "] " + str + "\n");
}
function getTimestamp() {
    var date = new Date();
    var nowString = date.getFullYear() + "-";
    var month = (date.getUTCMonth() + 1);
    if (month < 10) {
        nowString += "0";
    }
    nowString += month + "-";
    dayOfMonth = date.getDate();
    if (dayOfMonth < 10) {
        nowString += "0";
    }
    nowString += dayOfMonth + " ";
    hours = date.getHours();
    if (hours < 10) {
        nowString += "0";
    }
    nowString += hours + ":";
    mins = date.getMinutes();
    if (mins < 10) {
        nowString += "0";
    }
    nowString += "" + mins;
 
    return nowString;
}

« Prev - Next »