<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <title>Tag: screencast :: phly, boy, phly</title>
    <description>Tag: screencast :: phly, boy, phly</description>
    <pubDate>Thu, 20 Sep 2012 22:30:00 +0000</pubDate>
    <generator>Zend_Feed_Writer 2.1.4dev (http://framework.zend.com)</generator>
    <link>http://mwop.net/blog/tag/screencast.html</link>
    <atom:link rel="self" type="application/rss+xml" href="http://mwop.net/blog/tag/screencast-rss.xml"/>
    <item>
      <title>Screencasting on Linux</title>
      <pubDate>Thu, 20 Sep 2012 22:30:00 +0000</pubDate>
      <link>http://mwop.net/blog/2012-09-20-screencasting-on-linux.html</link>
      <guid>http://mwop.net/blog/2012-09-20-screencasting-on-linux.html</guid>
      <author>me@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>
    I've been wanting to do screencasts on Linux for some time now, and my big
    stumbling block has been determining what tools to use.
</p>

<p>
    The <strong>tl;dr</strong>:
</p>

<ul>
    <li>
        Use <code>recordMyDesktop</code> to record video clips, but afterwards, re-encode them
        to AVI (<a href="#script">see the script I used</a>)
    </li>

    <li>
        Record audio to WAV, or convert compressed audio to WAV format afterwards.
    </li>

    <li>
        Use OpenShot to stitch clips together and layer audio and video tracks.
    </li>

    <li>
        Remember to reset the video length if you change the playback rate.
    </li>

    <li>
        Export to a Web + Vimeo profile for best results.
    </li>
</ul><h2 id="toc_1.1">Stumbling Blocks</h2>

<p>
<code>recordMyDesktop</code> is a fairly simple tool, and allows you to
record actions you're taking, and simultaneously capture audio. However, it
creates an ".ogv" (Ogg Vorbis video file) -- which is basically useless for
anybody not on Linux or FreeBSD. Additionally, I often like to record in
segments; this makes it less likely that I'll make mistakes, and, if I do, I
only need to record a small segment again, not the entire thing. <code>recordMyDesktop</code>
is only for creating screencasts, not merging them.
</p>

<p>
So, <code>recordMyDesktop</code> went into my toolbox for the purpose of recording the video
portion of my screencasts.
</p>

<p>
Which brings me to the next point: I also prefer to record the audio separately
from the screencast portion itself; this way I don't get typing sounds in the
recording, and I'm less likely to lose my train of thought as I'm speaking. 
To this end, I ended up using quite simply the "Sound Recorder" utility
(<code>gnome-sound-recorder</code>). It's not great, but with a reasonable microphone, it
gets the job done. I chose to record the audio as MP3 files.
</p>

<p>
However, this means that I now have video and audio tracks. So my toolbox needed
a utility for overlaying tracks and laying them out on a timeline independently.
</p>

<p>
I looked at a few different free tools for Linux, including <code>Avidemux</code>, <code>Cinelerra</code>,
and <code>PiTiVi</code>. <code>Avidemux</code> was not featurful enough, <code>Cinelerra</code> was too difficult to
learn (it's more of an advanced user's tool), and <code>PiTiVi</code> kept crashing on me.
So, I used the lazyweb, and tweeted a question asking what others were using --
and the unanimous response was <code>OpenShot</code> (<a href="http://www.openshotvideo.com/">http://www.openshotvideo.com/</a>).
</p>

<p>
<code>OpenShot</code> hit the sweet spot for me -- it was easy to pick up, and didn't crash.
However, I discovered problems when I exported my project to a video file. My
video, regardless of whether or not I changed the playback rate, always played
at about 2X normal speed. The audio always truncated 1 to 2 seconds before
completion.
</p>

<p>
In doing some research, I discovered:
</p>

<ul>
<li>
There are known issues with Ogg Vorbis video files. Evidently, the
   compression creates issues when re-encoding the video to another format.
</li>
<li>
Similarly, compressed audio can lead to issues such as truncation.
</li>
</ul>

<p>
Since <code>recordMyDesktop</code> doesn't allow you to select an alternate video codec, I
had to use <code>mencoder</code> to transcode it to another format. I chose AVI (Audio
Video Interleave, a video container format developed by Microsoft), as I knew it
had widespread support, using an mpeg4 codec (also widely supported). I used the
following script, found at
<a href="http://askubuntu.com/questions/17309/video-converter-ogv-to-avi-or-another-more-common-format">http://askubuntu.com/questions/17309/video-converter-ogv-to-avi-or-another-more-common-format</a>,
in order to encode my files:
</p>

<div id="script" class="example"><pre><code language="bash">
for f in *.ogv;do
newFile=${f%.*}
mencoder "$f" -o "$newFile.avi" -oac mp3lame -lameopts fast:preset=standard -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=4000
done
</code></pre></div>

<p>
That solved the video issue, but I still had to solve the audio issues. I
quickly re-recorded one audio segment in Sound Recorder, and told it to use the
"Voice,Lossless (.wav type)". When I used this version of the audio, I had no
issues, other than the audio length being mis-reported within <code>OpenShot</code>. Instead
of re-recording all segments, I installed the "Sound Converter" utility (`sudo
aptitude isntall soundconverter`), and used that to convert all my MP3 files to 
WAV. Interestingly, <code>OpenShot</code> reported the audio lengths correctly this time; go
figure.
</p>

<p>
Once that was done, I was able to start stitching everything together. A few
notes, in the hopes others learn from my mistakes:
</p>

<ul>
<li>
Several times, I wanted my video to playback slower. This is very easy to do:
   right click on the clip, select "Properties", and select the "Speed" tab, and
   adjust as necessary. However, that's not all you need to do; you need to also
   re-adjust the <em>length</em> of the clip. Simply take the existing length, and
   divide it by the rate of play. As an example, if the length is 44 seconds,
   and you specify a 1/2 rate (0.5), you'd do 44 / 0.5 = 88, and set the length
   of the clip to 88s.
</li>
<li>
If you find that <code>OpenShot</code> is reporting your audio clip lengths incorrectly,
   use another tool to find the accurate length, and then set the length to
   that. I typically rounded up to the next second, as most tools were giving
   the floor value from rounding.
</li>
<li>
I chose to export using the Web + Vimeo HD profile. This worked perfectly for
   me. It created an mpeg4 file that I could preview in a browser, and then
   upload without issues. Your mileage may vary.
</li>
</ul>

<p>
Hopefully, this will serve as a reasonable guide for others foraying into
screencasts on Linux!
</p>]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>ZF2 Modules Quickstart (Screencast)</title>
      <pubDate>Wed, 19 Sep 2012 18:10:00 +0000</pubDate>
      <link>http://mwop.net/blog/2012-09-19-zf2-module-screencast.html</link>
      <guid>http://mwop.net/blog/2012-09-19-zf2-module-screencast.html</guid>
      <author>me@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>
One of the exciting features of the newly released Zend Framework 2 is the new
module system.
</p>

<p>
While ZF1 had modules, they were difficult to manage. All resources for all
modules were initialized on each request, and bootstrapping modules was an
onerous task. Due to the difficulties, modules were never truly "plug-and-play",
and thus no ecosystem ever evolved for sharing modules.
</p>

<p>
In Zend Framework 2, we've architected the MVC from the ground up to make
modular applications as easy as possible. Within ZF2, the MVC simply cares about
events and services — and controllers are simply one kind of service. As such,
modules are primarily about telling the MVC about services and wiring event
listeners.
</p>

<p>
To give you an example, in this tutorial, I'll show you how to install the Zend
Framework 2 skeleton application, and we'll then install a module and see how
easy it is to add it to the application and then configure it.
</p><p>
To keep things simple, I'm using a unix-like environment. As such, if you are on
Windows, you may not have the same command-line tools available. If you are in
such a situation, perhaps try this inside a Linux virtual machine.
</p>

<iframe src="http://player.vimeo.com/video/49775540" 
width="500" height="281" frameborder="0" 
webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
<p><a href="http://vimeo.com/49775540">Zend Framework 2 Module Quickstart</a></p>

<p>
Let's start by creating a new project. We'll execute a few commands to download
a skeleton application archive and extract it.
</p>

<div class="example"><pre><code language="bash">
% mkdir newproject
% cd newproject
% wget https://github.com/zendframework/ZendSkeletonApplication/tarball/master \
    -O ZendSkeletonApplication.tgz
% tar xzf ZendSkeletonApplication.tgz --strip-components=1
</code></pre></div>

<p>
    The Zend Framework skeleton application can be downloaded directly off of
    <a href="https://github.com">GitHub</a>. I'm showing using the download 
    from master, but you can also download a tarball or zipball for individual 
    tags as well. Because the download URL does not include an extension, I use 
    the <code>-O</code> switch to tell <code>wget</code> what filename to save to.
</p>

<p>
    <code>tar</code> has a nice option, `<code>--strip-components</code>`, which allows you to tell it to
    descend a certain number of levels deep into the archive when deflating. Since I
    know the tarball has a top-level directory named after the repository and a
    sha1, I'm simply telling <code>tar</code> to skip that and give me the contents of its
    child directory.
</p>

<p>
    At this point you have the skeleton application, but it has no dependencies 
    — not even Zend Framework itself! Let's rectify that situation. We'll use the
    dependency management tool <a href="https://getcomposer.org/">Composer</a> 
    to do this. We include the Composer phar file within the skeleton 
    application to make this fairly easy. Simply execute the following:
</p>

<div class="example"><pre><code language="bash">
% php composer.phar install
</code></pre></div>

<p>
    You may get a notice indicating that the composer version is older, and to 
    run "self-update"; you can ignore that for now.
</p>

<p>
    If all goes well, you should now have Zend Framework installed. Let's test 
    it out. I'm going to use the built-in web server in PHP 5.4 to demonstrate.
</p>

<div class="example"><pre><code language="bash">
% cd public
% php -S localhost:8080
</code></pre></div>

<p>
    If I browse to <code>http://localhost:8080</code> I should now see the 
    landing page for the skeleton application.
</p>

<img src="/images/screencasts/2012-09-19-zf2-module-screencast-01-zsa.png" style="width: 100%; height: 100%;" />

<p>
    Let's add a module to the application. Many sites require a contact form. 
    I've written one as a module some time ago, and called it <a 
    href="https://github.com/weierophinney/PhlyContact">PhlyContact</a>. To install
    it, I'll edit my project's <code>composer.json</code> and tell it about that 
    dependency:
</p>

<div class="example"><pre><code language="json">
{
    "require": {
        "php": "&gt;=5.3.3",
        "zendframework/zendframework": "dev-master",
        "phly/phly-contact": "dev-master"
    }
}
</code></pre></div>
    
<p>
    I know the name of the component from <a 
    href="http://packagist.org/">http://packagist.org/</a>, and I'm telling
    Composer that I want to use whatever the latest version is on its master 
    branch on GitHub. I happen to also know that PhlyContact requires a dev-master 
    version of Zend Framework, so I'll alter that dependency for now.
</p>

<p>
    Now, we need to tell composer to update our dependencies.
</p>

<div class="example"><pre><code language="bash">
% php composer.phar update
</code></pre></div>
    
<p>
    After executing the command, we should now see that it has installed; this 
    may take a little while.
</p>

<p>
    You need to inform the application about the module. This is so that we don't
    have to perform expensive file-system scanning operations, but also to make it
    explicit in your code what modules you're actually using. Enabling a module is
    usually as easy as adding an entry to <code>config\application.config.php</code>:
</p>

<div class="example"><pre><code language="php">
'modules' => array(
    'Application',
    'PhlyContact',
),
</code></pre></div>

<p>
    This particular module provides some reasonable defaults. In particular, it uses
    a CAPTCHA adapter that doesn't require additional configuration, and assumes
    that you will want to use the default <code>Sendmail</code> mail transport. As such, we can
    simply browse to it now. I happen to know that the module defines a <code>/contact</code>
    end point. Let's fire up our PHP web server again, and browse to that URL.
</p>

<div class="example"><pre><code language="bash">
% cd public
% php -S localhost:8080
</code></pre></div>

<img src="/images/screencasts/2012-09-19-zf2-module-screencast-02-contact.png" style="width: 100%; height: 100%;" />

<p>
    It just works!
</p>

<p>
    One philosophy we have for distributable modules in Zend Framework 2 is 
    that you should not need to touch the code in modules you install in your application.
    Instead, you should be able to configure and override behavior within the
    application configuration or in your application's site-specific modules. Let's
    alter the contact module to:
</p>

<ul>
    <li>first, change the URL it responds to, and</li>
    <li>second, use the "file" mail transport.</li>
</ul>

<p>
    Let's look at the default configuration. I'll browse to
    <code>vendor/phly/phly-contact/config/</code> and look at the <code>module.config.php</code> file.
</p>

<div class="example"><pre><code language="php">
return array(
    'phly_contact' => array(
        'captcha' => array(
            'class' => 'dumb',
        ),
        'form' => array(
            'name' => 'contact',
        ),
        'mail_transport' => array(
            'class' => 'Zend\Mail\Transport\Sendmail',
            'options' => array(
            )
        ),
        'message' => array(
            /*
            'to' => array(
                'EMAIL HERE' => 'NAME HERE',
            ),
            'sender' => array(
                'address' => 'EMAIL HERE',
                'name'    => 'NAME HERE',
            ),
            'from' => array(
                'EMAIL HERE' => 'NAME HERE',
            ),
             */
        ),
    ),

    /* ... */

    'router' => array(
        'routes' => array(
            'contact' => array(
                'type' => 'Literal',
                'options' => array(
                    'route' => '/contact',
                    'defaults' => array(
                        '__NAMESPACE__' => 'PhlyContact\Controller',
                        'controller'    => 'Contact',
                        'action'        => 'index',
                    ),
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'process' => array(
                        'type' => 'Literal',
                        'options' => array(
                            'route' => '/process',
                            'defaults' => array(
                                'action' => 'process',
                            ),
                        ),
                    ),
                    'thank-you' => array(
                        'type' => 'Literal',
                        'options' => array(
                            'route' => '/thank-you',
                            'defaults' => array(
                                'action' => 'thank-you',
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
    /* ... */
);
</code></pre></div>

<p>
    Okay, that's interesting. I can define the captcha and options to use, the 
    name of the contact form, the mail transport I want to use, and even who the email 
    is sent from and who it goes to. In addition, it defines some routes.
</p>

<p>
    I'll create a new file, <code>config/autoload/phly-contact.local.php</code>. This is a
    local configuration file that will not be checked into my version control
    system. Now, let's add some configuration. First, I'll configure my mail
    transport.
</p>

<div class="example"><pre><code language="php">
return array(
    'phly_contact' => array(
        'mail_transport' => array(
            'class'   => 'Zend\Mail\Transport\File',
            'options' => array(
                'path' => 'data/mail/',
            ),
        ),
    ),
);
</code></pre></div>

<p>
    I'm telling the module to use the <code>File</code> mail transport, and telling the transport
    where I want messages written. By default, Zend Framework calls <code>chdir()</code> to
    change directory to the project root, so I can reference a directory relative to
    that. I'm simply going to write to a <code>data/mail/</code> directory. Let's create that,
    and make it world-writable for now to ensure the web server can write to it. (In
    production, you'd only want it writable by the web server user.)
</p>

<div class="example"><pre><code language="bash">
% mkdir -p data/mail
% chmod a+rwX data/mail
</code></pre></div>

<p>
    Now, let's change the base URL the contact form responds to; I want it to
    respond to <code>/contact-us</code>. Another principle of re-usable modules in ZF2 is that
    we recommend creating tree routes for each module, with the root of the tree
    being a literal route. This makes it easy to alter the base for routing, without
    needing to redefine all the routes in the module.
</p>

<p>
    I'll add the following to my local configuration, then. I'll simply override the
    parent route for my module, named "contact", and point it at a different URL.
</p>

<div class="example"><pre><code language="php">
'router' => array(
    'routes' => array(
        'contact' => array(
            'options' => array(
                'route' => '/contact-us',
            ),
        ),
    ),
),
</code></pre></div>

<p>
    Let's see if all this worked! Once again, I'll fire up PHP's built-in web
    server.
</p>

<div class="example"><pre><code language="bash">
% cd public
% php -S localhost:8080
</code></pre></div>

<p>
    Now, let's browse to <code>http://localhost:8080/contact-us</code> -- looks good! Just as an
    experiment, let's try the previously configured URL,
    <code>http://localhost:8080/contact</code>. We get a 404 now!
</p>

<img src="/images/screencasts/2012-09-19-zf2-module-screencast-03-config.png" style="width: 100%; height: 100%;" />
<img src="/images/screencasts/2012-09-19-zf2-module-screencast-04-404.png" style="width: 100%; height: 100%;" />

<p>
    Now, let's submit the form. I'll fill in some information; it's asking for my
    email address, a subject line, and a message, as well as for me to solve a
    simple CAPTCHA. Once I've done all that, I can send it.
</p>

<p>
    If all is well, we should now have a mail file in our data directory. Let's
    check.
</p>

<div class="example"><pre><code language="bash">
% ls -l data/mail/
</code></pre></div>

<p>
    And now let's look at it.
</p>

<div class="example"><pre><code language="bash">
% cat data/mail/ZendMail_1347989389_1009740165.tmp
Date: Tue, 18 Sep 2012 12:29:49 -0500
From: me@mwop.net
Reply-To: me@mwop.net
Subject: [Contact Form] Suspense!

Suspenseful, isn't it?
</code></pre></div>
    
<p>
    Looks good!
</p>

<p>
    Zend Framework 2 provides a wonderful modular architecture that will enable an
    ecosystem of 3rd party modules that should save you time and energy when
    developing your applications. I've demonstrated a simple one, a contact form,
    but many, many more already exist, and with a stable release now available, you
    should see that number grow. This is truly a wonderful step forward for
    developers, and I hope you find it as exciting as I do.
</p>]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
  </channel>
</rss>
