Archive for October, 2009
How to Batch Convert with FFmpeg in Windows
by Bruce on Oct.21, 2009, under Software
I have really gotten to love FFMpeg and the capabilities it can bring. It is very frustrating for me that it’s not really distributed with some GUI attached, or with some way of compiling it that doesn’t require a computer scientist. I think that most people that could benefit the most from it are media producers, editors, etc. Many of those folks just don’t have the programming background to sort through source files and binaries and understand really what to do. But, if you get it up and running, it’s really a treat.
I have a project that has a bunch of (about 100 so far) video files that I want to make screen captures of and use as thumbnails in my interface. I could go through one by one, but that’s a real pain and not necessary. So, I created a couple batch scripts that would do the conversion for me. The first script just cycles through a directory and feeds each file that fits certain requirements to my second script for processing. In my case, I have a bunch of .mov files that I want to pull frames from. So, the first script is named “startConvert.bat” and is only a few lines long and looks like this:
for %%i IN (*.mov) DO (doConvert.bat “%%i”)
pause
That basically says that I should feed any file that has an extension of .mov to my second batch script, which is named “doConvert.bat” and looks like this:
IF EXIST “%~d1%~p1%~n1.jpg” GOTO exit
@echo ————————— >> “%~d1%~p1%convert.log”
@echo Conversion for %1 started on %DATE% %TIME% >> “%~d1%~p1%convert.log”
ffmpeg -i “%~d1%~p1%~n1.mov” -r 29.97 -ss 10.000 -an -vframes 1 -qscale 1 -f mjpeg -y “%~d1%~p1%~n1.jpg”
@echo ————– DONE – SUCCESS ———————- >> “%~d1%~p1%convert.log”
:exit
@echo ——————————– >> “%~d1%~p1%convert.log”
@echo “%~d1%~p1%~n1.jpg” already exists >> “%~d1%~p1%convert.log”
This does a few things. It checks to see if the file already exists, and if so, it skips it. It also writes the results of each conversion to a text file so you can see what happened. There isn’t really much error checking in this, but if you’re familiar with batch scripts, you could probably add some to figure out if there were errors or look for other problems. I am creating deinterlaced .jpg files of freeze frames from 10 seconds into my clip. If you see where the file name gets inserted, you can modify the command line with options from here to do whatever you want and copy/name the files whatever you need. You put both of the files above in the directory with your movies and then double click the first one “startConvert.bat” to rip through them all.
I wanted to put a simple script up though that people could quickly grab and use, without trying to sort through bits of forum posts and other nonsense.
Delete an XML Node in Flash and other XML tips for Adobe Flash/Air
by Bruce on Oct.16, 2009, under Software
I am not going to make this a huge run-down of how to use XML in Flash, but instead share a few tips I’ve come across while incorporating it into my applications. If you’re looking for a place to start from the beginning and get the basics of using XML with Flash, then I’d go here to kirupa.com
Use a Configuration File
Since we mostly develop stand-alone exhibits for public spaces, there is some basic configuration information that we want in all of our programs and so each application has its own config XML with some standard parameters, and some that are specific to the application. The file we load at the start of each program has a config node, which will hold much of the items we use for every application. It might look like this …
<config>
<timeout>90</timeout>
<attractScreen>attract.swf</attractScreen>
<showMouse>0</showMouse>
</config>
It loads values that the application will use to determine the time the program waits to go to the attract loop, the location of the attract loop file, and whether or not the mouse should be shown at program startup. Another common thing that is done with our config XML is loading any dynamic text into the program, so it’s easy to change this text and it won’t have to be done by a programmer. There’s a text node and it holds a few different items that we may use.
<text>
<intro>Please Choose a category</intro>
<menuInstructions>Now, select a submenu below to start exploring.</menuInstructions>
<outro>Thanks for visiting, we hope you enjoy the rest of your day!</outro>
</text>
It’s important to pull that stuff out of the code and into easily configurable external files. It’s very common to have a client call and let you know that they think wording should be changed, or that the timeout happens too fast on a particular exhibit, and the ability for that change to be made by them is valuable.
Deleting an XML Node
So, to add a node to an existing XML instance in Flash, the most basic function is appendChild(). If you have two variables holding XML, and want to add one to the other, it could be as simple as …
myXML.appendChild(myXML2.copy());
This will vary depending on what you want to do specifically, but that’s the basic idea. So, if you want to delete a child from XML, you’d think you would just use a function like removeChild() or deleteChild(). Sorry, that’s not how it works. You actually have to use the fairly odd delete command. And, it doesn’t even get values fed like a regular function. If you had your XML that held photo nodes and wanted to delete the second item, it would look like …
delete myXML.photo[1];
It is not intuitive at all, and I am sure there is some reason it’s done that way based on the object model and available functions in the different classes, but it’s still a bit difficult to figure out.
Creating XML in Flash
For some applications, you may want to create a variable that holds XML for whatever reason. Now, if you’re just making a copy of or adding to some existing XML, it’s pretty straightforward. But, if you create the XML from scratch, there’s one important step that if you skip, will cause your XML not to work properly. You have to create a top level <data> node in it to hold your child nodes. If you don’t do that, it may not act as it should. So, if I am doing some sort of searching or sorting, and want to create a brand new XML that holds photo nodes from another XML document that fit certain search criteria, I can’t just say …
var newXML:XML = new XML();
newXML.appendChild(photoXML.photo[2]);
newXML.appendChild(photoXML.photo[5]);
//try to trace out the new XML, but you’ll see nothing
trace(newXML);
What you have to do is create a <data> tag when you make that new XML, so that it will have a node to append the children to. So, instead try …
var newXML:XML = <data></data>
newXML.appendChild(photoXML.photo[2]);
newXML.appendChild(photoXML.photo[5]);
//Now you’ll see the new XML nodes reflected
trace(newXML);
So, make sure you create that top level to allow items to be manipulated with code.