<?xml version='1.0' encoding='UTF-8'?>

<?xml-stylesheet href="./_c74_tut.xsl" type="text/xsl"?>
<chapter name="Tutorial 19: Recording movies">
<setdocpatch name="19jRecording" patch="19jRecording.maxpat"/>

<previous name="jitterchapter18">Iterative Processes and Matrix Re-Sampling</previous>
<next name="jitterchapter20">Importing and Exporting Single Matrices</next>
<parent name="jitindex">Jitter Tutorials</parent>



<h1>Tutorial 19: Recording movies</h1>

<p>This tutorial shows how you can record a single matrix or a sequence of matrices to disk as a movie. We'll demonstrate the use of the <o>jit.record</o> object for recording in real time and non-real time. Along the way, we'll also show you how to adjust some of the settings of the output movie.</p>

<p>Like most Jitter objects, the <o>jit.record</o> object operates according to an event-driven model rather than a time-driven one -- frames sent to a record-enabled <o>jit.record</o> object are appended to the movie in progress as "the next frame" based on the timing characteristics of the output movie, without regard for the relative time between the arriving frames. This results in very smooth movies with consistent timing between frames, but it requires some preparation before recording.</p>

<div>
<techdetail>The <o>jit.record</o> object also offers a time-driven (realtime) method of recording in addition to the default mode described in this tutorial. Although the realtime mode might seem simpler to use, the recorded output won't be as smooth because frames of the incoming movie will usually be dropped fairly regularly during recording. You can set the time-driven mode for the <o>jit.record</o> object by using the <m>realtime</m> message, but it is quite different from the realtime operation described in this tutorial.</techdetail>
</div>

<h2>Your mileage may vary</h2>
<p>Each and every matrix that arrives at a recording <o>jit.record</o> object must be compressed before becoming part of your output movie. The speed of this compression depends on several factors: the speed of your processor and your disk drive, and -- most importantly -- the type of compression used (referred to as the <i>codec</i>, short for <i>co</i>mpression/<i>dec</i>ompression). The examples in this tutorial will use the Photo-JPEG codec. It should yield fairly consistent results from machine to machine without a lot of high CPU usage and disk access. On older or slower systems, it's possible that you'll notice some timing inaccuracy with the first set of examples for this tutorial. If you do, don't worry; the second part of this tutorial will show you how to achieve excellent results on even the most modest system by working in non-realtime mode. </p>

<techdetail>
	<i>Note:</i> The codec and dimension recommendations in this tutorial are outdated. A good codec to balance file size, image quality, and cpu requirements is <b>h264</b>. For lossless recording, or to record an alpha channel use <b>prores4444</b> on the Mac and <b>animation</b> on Windows.
</techdetail>

<h2>On the clock</h2>
<bullet>Open the <m>Basic_recording</m> subpatch.</bullet>
<p>The first example shows a very basic recording setup. Notice that the <o>jit.record</o> object takes two arguments (<m>320</m> and <m>240</m>) that specify the width and height of any movies we record with this object.</p>

<illustration><img src="images/jitterchapter19a.png"/>A simple recording patch</illustration>

<bullet>Click the <o>message</o> box that says <m>read countdown15.mov</m> to load a movie into the <o>jit.movie</o> object, and start the <o>metro</o> object by clicking on the <o>toggle</o> box connected to its inlet. If the <m>preview</m> attribute is set to 1, you will see the movie's image appear in the jit.pwindow object, since the jit.record object will then pass any matrices it receives out its left outlet. (The <o>jit.robcross</o> object in this patch is a simple edge detector that we're using to process the matrices passing through it).</bullet>

<bullet>Click the <o>message</o> box that says <m>write 15. jpeg</m> to start writing the movie (we'll look at the contents of the <o>message</o> box in more detail in a moment). A file Dialog Box will appear, prompting you for a file name. When you enter a valid name and click the Save button, recording begins to the filename  you've chosen (For the purposes of example, let's assume you've named your movie <i>myfilename.mov</i>.). Click the <m>stop</m> <o>message</o> box to stop recording.</bullet>

<p>The <o>jit.record</o> object sends a message out its right outlet after a write operation to confirm that the movie was successfully written. Since we've connected that outlet to a <o>print</o> object in our patch , we can see the results by looking at the Max Console. If everything went as expected, you should see <m>print:</m> <m>write myfilename.mov 1</m><m/> in the Max Console. If there was a problem, the number after the filename will not be a <m>1</m>.</p>

<bullet>Click the <m>read</m> message box in the main patch and read in the movie you just recorded. How does it look?</bullet>

<p>Let's examine the <m>write</m> message to the <o>jit.record</o> object for a moment. The <m>write</m> message puts <o>jit.record</o> into a record-enabled mode. The actual recording doesn't begin until the object receives a matrix in its inlet. The <m>write</m> message can take several optional arguments to specify a file name, frame rate, the codec type, the codec quality and the timescale for the output movie. In this example we're only using two arguments (<m>15.</m> and <m>jpeg</m>) to specify the frame rate (<m>15.</m> indicates 15 frames per second) and the codec type (<m>jpeg</m> indicates Photo-JPEG) of the output movie. For a full description of all the arguments for the <m>write</m> message, see the Object Reference entry for the <o>jit.record</o> object.</p>

<p>Note that we have the <o>metro</o> object set to send a <m>bang</m> message every 66.67 milliseconds. This is done to match the input movie's frame rate. If you change the <o>metro</o> object's rate and record a few more movies, you will see that a faster  <o>metro</o> rate causes the movie to be longer and slower, while a slower <o>metro</o> rate results in a shorter, faster movie. This happens because of the event-driven model being used by <o>jit.record</o>.</p>

<h2>More muscle</h2>
<bullet> Open the <m>Advanced_recording</m> subpatch.</bullet>
<p>The second example patch is a little more complicated, but it has  two important additions (and several minor ones). </p>

<illustration><img src="images/jitterchapter19b.png"/>Same idea, different patch</illustration>

<p>First, we're automatically detecting the frame rate of the original movie (using the <m>getfps</m> message), and using it to set both the rate of the <o>metro</o> object driving <o>jit.record</o> and the output movie's frame rate, as well. Let's look at that portion of the patch in detail:</p>

<ul>
<li>When a movie is successfully loaded into <o>jit.movie</o>, the object sends the message <m>read filename.mov 1</m> out its right outlet. (If the <m>read</m> operation is unsuccessful, the number will not be 1.) We're using the <o>route</o> object to retrieve this message.</li>
<li>The <o>unpack</o> <m>s 0</m> object breaks up the remaining elements of the message. We're not interested in the file name, only in the success or failure of the read operation, so we've attached nothing to the left outlet of <o>unpack</o>, and attached a <o>select</o> object, which tests for the integer 1, to the right outlet. If our <m>read</m> operation was successful, the <o>select</o> object will output a <m>bang</m>.</li>
<li>The <m>bang</m> is used to send the message <m>getfps</m> to <o>jit.movie</o>, which will respond by sending the message <m>fps [fps]</m> out its right outlet. The <m>[fps]</m> message element is a floating-point number representing the movie's frame rate. This value is sent from the <o>route</o> object's middle outlet, and used to set the <o>metro</o> object's speed and the output movie's frame rate.</li>
</ul>
<p>This patch includes a second improvement. Rather than locking the entire patch to the frame rate of the original movie, we've added a <o>jit.matrix</o> object with <m>thru</m> turned off to collect the output of the patch, and we're using a second <o>metro</o> to send it <m>bang</m> messages at the correct frame rate for <o>jit.record</o>. This permits the rest of our patch to operate independently, at as fast or slow a rate as we want, with only the very last part of the patch specifically timed to the recording process.</p>

<p>Finally, we've added a neat crosshatching filter (the <o>jit.hatch</o> object) with its own editing control (the <o>number</o> box and the <m>grid $1</m> <o>message</o> box). You can use this to modify your movie while you're recording it and watch the effects on playback. You can substitute any kind of Jitter object or patch you want at this point in the recording patch and modify what you record in real time. </p>

<h2>Off the clock</h2>
<bullet>Open the <m>Off-line_recording</m> subpatch.</bullet>
<p>Both of the previous patches have a problem: under high processor loads, these patches will drop frames. In many cases, this is not a problem, and the patches we've looked at are well suited to recording in any context, including live performance.</p>

<p>But how can we record a sequence in which <i>every</i> frame in an original movie has a corresponding frame in the output movie?  How do you render movies in Jitter so that, even under heavy processor or disk load, every processed frame is captured?</p>

<p>There is a way. The <o>jit.movie</o> object's <m>framedump</m> message offers a non-realtime playback mode that works perfectly with <o>jit.record</o>.</p>

<bullet>Scroll all the way down in the Patcher window to see the third example.</bullet>

<illustration><img src="images/jitterchapter19c.png"/>Non-realtime recording with <m>framedump</m></illustration>

<p>On first inspection, the third example patch may not seem a lot more complicated than the previous one. But don't be fooled -- this unassuming patch will bring even the speediest computer to its knees. </p>

<bullet>Click the <o>message</o> box <m>countdown.mov</m> to load a movie into the <o>jit.movie</o> object, start the <o>metro</o> object by clicking on the <o>toggle</o> box connected to its inlet and watch the <o>jit.fpsgui</o> object's framerate output display located at the bottom of the patch. If you get more than 10 fps, you have a much nicer computer than we do.</bullet>
<p>While this patch runs slowly in real time, it does a great job of creating a movie in non-realtime. Using the <o>jit.movie</o> object's <m>framedump</m> message and the  <o>jit.record</o> object, the patch will capture every frame of  the original movie, process it, and produce an output movie of identical length. </p>

<p>Here's how it works: the <m>framedump</m> message tells the <o>jit.movie</o> object to stop playing its movie, and then sends each frame out, one at a time. (N.B. You don't need to send a <m>bang</m> or <m>outputmatrix</m> message to the <o>jit.movie</o> object for the frames to be sent.) Because of the way the Max scheduler works, a new frame will not be sent until the previous frame has been fully processed and recorded. Let's try it out. </p>

<bullet>Click on the <o>toggle</o> box connected to the inlet of the <o>metro</o> object to turn it off. (Sending a <m>bang</m> to <o>jit.movie</o> during the framedump operation will cause an extra frame to be sent, which is not what we want.)  We've connected the <o>button</o> on the top left corner of the patch to both the <o>pack</o> object that sends the <m>write</m> message, and the <m>framedump</m> message. Press the <o>button</o>, enter a file name when the File Dialog appears, and wait for the movie to render. When the framedump is finished, the <o>jit.movie</o> object sends the message <m>framedump done</m> from its right outlet. The example patch uses that message to trigger a <m>stop</m> message to <o>jit.record</o>.</bullet>
<p>The example patch also takes advantage of the fact that the <o>jit.record</o> object sends a matrix out its left outlet after recording a frame. We're using that frame to trigger a <m>bang</m> message to a <o>counter</o> object that is driving the <m>grid</m> attribute of the  <o>jit.hatch</o> filter. This creates a repeatable sequence of processing changes that happen as the movie is captured.</p>

<bullet>Click on the "<m>read</m>" <o>message</o> box to open the movie you've just created. Turn on the <o>metro</o> to display the movie. Click on the <o>toggle</o> box connected to the <o>gate</o> object to see your new movie. This switches the <o>jit.movie</o> object's output directly to the <o>jit.pwindow</o>, instead of through the processing objects.</bullet>

<techdetail>
	<i>Technical Detail:</i> This tutorial was written in the days of antiquity, when computers (and Max) were less efficient. Chances are, your computer will just shrug off the demands in the heavy_processing subpatch with out breaking a sweat. The point is, when you do reach that level of processing (and we all do eventually), the framedump message will get the job done.
</techdetail>

<h2>Summary</h2>
<p>The <o>jit.record</o> object provides event-driven ways to record Jitter matrices as movies. You can record the output of a Jitter patch in real time as you manipulate your patch, or out of real time, in render-like operation. You can use  the <o>jit.movie</o> object's <m>framedump</m> message to process an entire movie file without dropping any frames. This method lets you record high quality movies regardless of the load being placed on your computer's processor.<i> </i></p>

	<seealsolist>
		<seealso display="Video Engines" module="core" name="jitter_video_engines" type="vignette" />
		<seealso name="jit.fastblur">Optimized blur/sharpen</seealso>
		<seealso name="jit.hatch">Crosshatch filter</seealso>
		<seealso name="jit.matrix">The Jitter Matrix!</seealso>
		<seealso name="jit.pwindow">In-Patcher Window</seealso>
		<seealso name="jit.movie">Play or edit a movie</seealso>
		<seealso name="jit.record">Record a movie</seealso>
		<seealso name="jit.robcross">Robert's Cross edge detection</seealso>
		<seealso name="jit.wake">Feedback with convolution stage </seealso>
	</seealsolist>
</chapter>
