<?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>Brett Terpstrashell page  - Brett Terpstra</title>
	<atom:link href="http://brettterpstra.com/tag/shell/feed/" rel="self" type="application/rss+xml" />
	<link>http://brettterpstra.com</link>
	<description>Elegant solutions to complex problems.</description>
	<lastBuildDate>Tue, 22 May 2012 02:49:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Quick Tip: Quickly clear stuck Growl notifications</title>
		<link>http://brettterpstra.com/quick-tip-quickly-clear-stuck-growl-notifications/</link>
		<comments>http://brettterpstra.com/quick-tip-quickly-clear-stuck-growl-notifications/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 23:00:56 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[growl]]></category>
		<category><![CDATA[launchbar]]></category>
		<category><![CDATA[quicktip]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3111</guid>
		<description><![CDATA[<p>Quick tips are random posts regarding something I discovered on my way to something bigger. They usually get longer than “quick” would imply, for which I refuse to apologize. I’ve been having an issue with the latest version of Growl (1.3.1) where notifications randomly get “stuck.” No amount of clicking and option-clicking will make them go away. Until there’s a&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/quick-tip-quickly-clear-stuck-growl-notifications/">Quick Tip: Quickly clear stuck Growl notifications</a></p>]]></description>
			<content:encoded><![CDATA[<p><em><a href="http://brettterpstra.com/tag/quicktip/">Quick tips</a> are random posts regarding something I discovered on my way to something bigger. They usually get longer than “quick” would imply, for which I refuse to apologize.</em></p>

<p>I’ve been having an issue with the latest version of Growl (1.3.1) where notifications randomly get “stuck.” No amount of clicking and option-clicking will make them go away. Until there’s a fix for this, I’m using a brute force restart to clear them<sup id="fnref:prev"><a href="#fn:prev" rel="footnote">1</a></sup>. I have it set up as an alias (<code>killgrowl</code>) in my <code>.bash_profile</code> and as a LaunchBar action (Restart Growl.scpt). It’s a really simple command:</p>

<pre><code>killall Growl &amp;&amp; open -a Growl
</code></pre>

<p>And in an AppleScript in <code>~/Library/Application Support/LaunchBar/Actions/Relaunch Growl.scpt</code></p>

<pre><code>do shell script "killall Growl &amp;&amp; open -a Growl"
</code></pre>

<p>Easy enough, right? You could run the AppleScript from any launcher (e.g. <a href="http://www.red-sweater.com/fastscripts/">FastScripts</a>), too. Like I said, brute force and lacking in any elegance, but it’ll get me through until a fix comes out.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:prev">
<p>This is essentially the same process as my <a href="http://brettterpstra.com/clear-sticky-growl-notifications-with-a-keyboard-shortcut/">previous foray</a>, but that one doesn’t work with the Mac App Store version of Growl. Consider this an update. <a href="#fnref:prev" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/clear-sticky-growl-notifications-with-a-keyboard-shortcut/' rel='bookmark' title='Clear sticky Growl notifications with a keyboard shortcut'>Clear sticky Growl notifications with a keyboard shortcut</a></li>
<li><a href='http://brettterpstra.com/multimarkdown-quick-look-with-style/' rel='bookmark' title='MultiMarkdown Quick Look with Style'>MultiMarkdown Quick Look with Style</a></li>
<li><a href='http://brettterpstra.com/nvalt-1-0-5-quick-fixes/' rel='bookmark' title='nvALT 1.0.5 (quick fixes)'>nvALT 1.0.5 (quick fixes)</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/quick-tip-quickly-clear-stuck-growl-notifications/">Quick Tip: Quickly clear stuck Growl notifications</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/quick-tip-quickly-clear-stuck-growl-notifications/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Automated HTML5 video encoding revisited</title>
		<link>http://brettterpstra.com/automated-html5-video-encoding-revisited/</link>
		<comments>http://brettterpstra.com/automated-html5-video-encoding-revisited/#comments</comments>
		<pubDate>Sun, 01 May 2011 15:21:51 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=2285</guid>
		<description><![CDATA[<p>A little while ago I approached the subject of scripting automated encoding for HTML5 video formats. I started using the process regularly as I built the Blogsmith Bundle video site. Pretty soon I got some help from friend and TUAW editor Mike Rose, and working together we refined the script and improved the speed tremendously. It was built for use&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/automated-html5-video-encoding-revisited/">Automated HTML5 video encoding revisited</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2011/05/html5automatorTV-small.jpg?9d7bd4" alt="HTML5 Automator" title="HTML5 Automator" width="328" height="257" class="alignright size-full wp-image-2296" />A little while ago I approached the subject of scripting <a href="http://brettterpstra.com/automating-html5-video-encodes/">automated encoding for HTML5 video formats</a>. I started using the process regularly as I built the <a href="http://bundle.weblogzinc.com/video/">Blogsmith Bundle video site</a>. Pretty soon I got some help from friend and TUAW editor <a href="http://www.tuaw.com/bloggers/michael-rose">Mike Rose</a>, and working together we refined the script and improved the speed tremendously. It was built for use on Mac OS X, but with just a few lines modified, it should work on any *NIX system.
<span id="more-2285"></span></p>

<h3>What it does</h3>

<p>The script is specifically designed to take an MPEG-4, H.264 file, move it to a new folder based on the filename, create WEBM and OGV versions of it in the new folder, and upload the whole folder to a server using <code>rsync</code>. SSH information and target directories are specified in the config at the top of the script. At the end, it takes what it knows about the files and filenames and creates a TextMate Markdown blog template, inserts the video shortcode for the <a href="http://wordpress.org/extend/plugins/videojs-html5-video-player-for-wordpress/">VideoJS WordPress plugin</a> (which is common syntax for other plugins as well) and opens it for editing in TextMate. The <code>rsync</code> command really needs <a href="http://www.rootsilver.com/2007/10/keyless-ssh-sshkeygen-setup-an">keyless SSH login</a> for this to be considered fully-automated.</p>

<p>If you run this script with <a href="http://www.noodlesoft.com/hazel.php">Hazel</a>, you can just render an <a href="http://en.wikipedia.org/wiki/H.264">H.264</a> video (<code>.mov</code> files that pass the H.264 test<sup id="fnref:fnh264"><a href="#fn:fnh264" rel="footnote">1</a></sup> will automatically be renamed to <code>.mp4</code>) to that folder from your screen-recording application of choice, sit back for a few minutes (or start writing the post) and wait for the pre-populated TextMate blog post to pop open. Then type or paste your text in, hit Control-Command-P (assuming you’re set up for TextMate-&gt;WordPress blogging) and your video is posted.</p>

<h3>Improvements</h3>

<p>The first thing that happened in this rewrite was a major simplification of the WEBM encoding process, which now only takes a third of the time it did before and the files are not significantly larger in most cases. They may even look better. The old command involved two passes, one of them turning out to be unnecessary; <code>ffmpeg</code> is smarter than I thought. The new command (using the variables from the script) is just <code>/usr/local/bin/ffmpeg -i "$FILENAME" -b 614400 -s $MAXSIZE -aspect 16:9 "$BASENAME".webm</code>.</p>

<p>I also added better logging, optional progress reports with <a href="http://growl.info/">Growl</a>, batch file handling and a few other refinements. The logging, if enabled in the config at the top, will output information including processing time for each file and total processing time to STDOUT (command line) and to the system log where you can watch it from Console. If you enable growl notifications, the messages at the beginning and end of each conversion will be “growled” on your screen.</p>

<h3>Using the script</h3>

<p>You’ll need a couple of additional utilities to do the conversions.</p>

<h4>Requirements</h4>

<p>To run the script and do the encoding, you’ll need <code>ffmpeg</code> and <code>ffmpeg2theora</code>. You can install <code>ffmpeg</code> from <a href="https://github.com/mxcl/homebrew">Homebrew</a> (<code>brew install ffmpeg</code>) quite easily, if you’re set up for that. You can also pull the binary out of <a href="http://www.ffmpegx.com/">ffmpegX</a> with a <a href="http://hints.macworld.com/article.php?story=20061220082125312">few simple steps</a>. You can, of course, <a href="http://troykelly.com/2007/01/18/building-ffmpeg-on-os-x/">build your own</a> if you have the developer tools installed.</p>

<p>ffmpeg2theora (needed for OGV conversion) no longer appears to be available from <code>brew</code>, but there are OS X binaries (and source) <a href="http://v2v.cc/~j/ffmpeg2theora/download.html">available for download</a>.</p>

<p>The <a href="#thescript">script is below</a>. You’ll want to modify the information in the configuration section at the top, and modify the template output at the bottom to suit your needs. Anything between <code>&lt;&lt;-POSTTEMPLATE</code> and <code>POSTTEMPLATE</code> is freeform text that you can edit in any way you like, including the use of $variables. If you’d rather do something such as copy a shortcode to your clipboard and show a Growl message, just use <code>pbcopy</code> and <code>growlnotify</code>. You could also just comment out the template part and let Hazel tell you when it’s done, if you want to handle things more manually. I’ll let you work out the details on that.</p>

<h4>Command line usage</h4>

<p>To use the script from the command line, save it as “html5encode.sh” somewhere in your path, change to its parent folder in Terminal and run <code>chmod a+x html5encode.sh</code>. The you can run it on any h.264 .mov or .mp4 file and it will handle the rest. It also handles batches, so you can specify multiple targets or use <code>*.mp4</code> to run it on all .mp4 files in a folder. It will process them one by one, creating new folders for each.</p>

<h4>Hazel</h4>

<p>If you want to run it with Hazel, you can follow the same procedure and set up a rule that runs a shell script when a .mov or .mp4 is detected in a watch folder. The script can then be run as a command or be pasted in its entirety into the Hazel script editor within the rule.</p>

<p>You should be able to pull off using this with OS X Folder Actions, as well, but I haven’t played with that yet.</p>

<p><strong>Bonus tip:</strong> <em>If you name your original .mov or .mp4 file with a CamelCased name, it will break apart the filename and create the title of your post based on it. Not an essential feature, but kind of nifty. Well, I think so anyway.</em></p>

<h3 id="thescript">The script</h3>

<p><a href="http://brettterpstra.com/share/html5encode.sh.txt">View Raw</a> | <a href="http://brettterpstra.com/share/html5encode.sh">Download</a></p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="co0">#!/bin/bash</span>
<span class="co0">#################################################################</span>
<span class="co0">### html5encode.sh by Brett Terpstra and Mike Rose</span>
<span class="co0">### Published 05/01/2011</span>
<span class="co0">### Freely distributed, modifications welcomed (with attribution)</span>
<span class="co0">#################################################################</span>
<span class="co0">### Configuration ###############################################</span>
<span class="co0">#################################################################</span>
<span class="re2">MAXSIZE</span>=<span class="st0">&quot;960x540&quot;</span>
<span class="re2">DISPLAYWIDTH</span>=<span class="st0">&quot;600&quot;</span>
<span class="re2">DISPLAYHEIGHT</span>=<span class="st0">&quot;338&quot;</span>
<span class="re2">SSHURL</span>=<span class="st0">&quot;username@ssh.host.name&quot;</span>
<span class="re2">SSHDIR</span>=<span class="st0">&quot;/server/folder/target/for/rsync/&quot;</span>
<span class="re2">WEBDIR</span>=<span class="st0">&quot;/front-end/url/path/video/&quot;</span> <span class="co0"># used for blog template</span>
<span class="re2">LOGGING</span>=<span class="kw2">true</span> <span class="co0"># send status messages and times to STDOUT and syslog</span>
<span class="re2">GROWLLOG</span>=<span class="kw2">false</span> <span class="co0"># duplicate messages to growl, if installed</span>
<span class="co0">##################################################################</span>
<span class="co0">### END Configuration ############################################</span>
<span class="co0">##################################################################</span>
&nbsp;
<span class="co0"># function to handle logging (if enabled) to STDOUT and STDERR </span>
<span class="co0"># as well as Growl (if enabled)</span>
<span class="kw1">function</span> logit<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="kw1">if</span> <span class="re1">$LOGGING</span> ; <span class="kw1">then</span>
    logger <span class="re5">-st</span> <span class="st0">&quot;HTML5 Encoder&quot;</span> <span class="st0">&quot;$1&quot;</span>
    <span class="kw1">if</span> <span class="re1">$GROWLLOG</span> ; <span class="kw1">then</span>
      <span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>bin<span class="sy0">/</span>growlnotify <span class="re5">-t</span> <span class="st0">&quot;HTML5 Encoder&quot;</span> <span class="re5">-a</span> <span class="st0">&quot;Terminal&quot;</span> <span class="re5">-m</span> <span class="st0">&quot;$1&quot;</span>
    <span class="kw1">fi</span>
  <span class="kw1">fi</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="co0"># Count the inputs for log message</span>
<span class="kw1">if</span> <span class="br0">&#91;</span><span class="br0">&#91;</span> <span class="re4">$#</span> <span class="re5">-gt</span> <span class="nu0">1</span> <span class="br0">&#93;</span><span class="br0">&#93;</span>; <span class="kw1">then</span>
  logit <span class="st0">&quot;Starting batch conversion.&quot;</span>
  <span class="re2">maintimer1</span>=<span class="sy0">`</span><span class="kw2">date</span> <span class="st_h">'+%s'</span><span class="sy0">`</span>
<span class="kw1">else</span>
  logit <span class="st0">&quot;Starting HTML5 Encoder&quot;</span>
<span class="kw1">fi</span>
&nbsp;
<span class="co0"># Loop through each passed file</span>
<span class="kw1">for</span> <span class="kw2">file</span> <span class="kw1">in</span> <span class="st0">&quot;$@&quot;</span>; <span class="kw1">do</span>
  <span class="re2">timer1</span>=<span class="sy0">`</span><span class="kw2">date</span> <span class="st_h">'+%s'</span><span class="sy0">`</span>
  <span class="re2">INPUT</span>=<span class="re1">$file</span>
  <span class="co0"># Check that input file is H.264</span>
  <span class="re2">isH264</span>=<span class="sy0">`</span>mdls <span class="re5">-raw</span> <span class="re5">-name</span> kMDItemCodecs <span class="re1">$INPUT</span><span class="sy0">|</span><span class="kw2">grep</span> H.264<span class="sy0">`</span>
&nbsp;
  <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="sy0">!</span><span class="re1">$isH264</span> <span class="br0">&#93;</span> ; <span class="kw1">then</span>
    logit <span class="st0">&quot;<span class="es2">$INPUT</span> is not h.264&quot;</span>
    <span class="kw3">continue</span>
  <span class="kw1">fi</span>
&nbsp;
  <span class="re2">DIRNAME</span>=<span class="sy0">`</span><span class="kw2">dirname</span> <span class="st0">&quot;<span class="es2">$INPUT</span>&quot;</span><span class="sy0">`</span>
  <span class="re2">FILENAME</span>=<span class="sy0">`</span><span class="kw2">basename</span> <span class="st0">&quot;<span class="es2">$INPUT</span>&quot;</span><span class="sy0">`</span>
  <span class="re2">BASENAME</span>=<span class="co1">${FILENAME%%.*}</span>
  logit <span class="st0">&quot;Conversion of <span class="es2">$FILENAME</span> started on <span class="es5">`date '+%D'`</span> at <span class="es5">`date '+%r'`</span>&quot;</span>
  <span class="re2">bytesize</span>=<span class="sy0">`</span><span class="kw2">stat</span> <span class="re5">-f</span> <span class="st_h">'%z'</span> <span class="re1">$FILENAME</span><span class="sy0">`</span>
  <span class="re2">filesize</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="st0">&quot;scale = 2 ; <span class="es2">$bytesize</span>/1048576&quot;</span><span class="sy0">|</span><span class="kw2">bc</span> -lq<span class="sy0">`</span>
  <span class="kw3">cd</span> <span class="st0">&quot;<span class="es2">$DIRNAME</span>&quot;</span>
  <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-d</span> <span class="st0">&quot;<span class="es2">$BASENAME</span>&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span>
    logit <span class="st0">&quot;Found <span class="es2">$FILENAME</span>, but directory <span class="es2">$BASENAME</span> already exists. Aborting&quot;</span>
    <span class="kw3">continue</span>
  <span class="kw1">fi</span>
  <span class="kw2">mkdir</span> <span class="st0">&quot;<span class="es2">$BASENAME</span>&quot;</span>
  <span class="kw2">mv</span> <span class="st0">&quot;<span class="es2">$FILENAME</span>&quot;</span> <span class="st0">&quot;<span class="es2">$BASENAME</span>/&quot;</span>
  <span class="kw3">cd</span> <span class="st0">&quot;<span class="es2">$BASENAME</span>&quot;</span>
  <span class="kw1">if</span> <span class="br0">&#91;</span><span class="br0">&#91;</span> <span class="co1">${FILENAME#*.}</span> <span class="re5">-eq</span> <span class="st0">&quot;mov&quot;</span> <span class="br0">&#93;</span><span class="br0">&#93;</span>; <span class="kw1">then</span> <span class="kw2">mv</span> <span class="re1">$FILENAME</span> <span class="co1">${BASENAME}</span>.mp4; <span class="kw1">fi</span>  
  <span class="re2">FILENAME</span>=<span class="co1">${BASENAME}</span>.mp4
  <span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>bin<span class="sy0">/</span><span class="kw2">ffmpeg</span> <span class="re5">-i</span> <span class="st0">&quot;<span class="es2">$FILENAME</span>&quot;</span> <span class="re5">-b</span> <span class="nu0">614400</span> <span class="re5">-s</span> <span class="re1">$MAXSIZE</span> <span class="re5">-aspect</span> <span class="nu0">16</span>:<span class="nu0">9</span> <span class="st0">&quot;<span class="es2">$BASENAME</span>&quot;</span>.webm
  logit <span class="st0">&quot;Completed webm conversion&quot;</span>
  <span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>bin<span class="sy0">/</span>ffmpeg2theora <span class="re5">--videoquality</span> <span class="nu0">5</span> <span class="re5">--audioquality</span> <span class="nu0">1</span> --max_size <span class="re1">$MAXSIZE</span> <span class="st0">&quot;<span class="es2">$FILENAME</span>&quot;</span> <span class="re5">-o</span> <span class="st0">&quot;<span class="es2">$BASENAME</span>.ogv&quot;</span>
  logit <span class="st0">&quot;Completed ogv conversion&quot;</span>
  <span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>bin<span class="sy0">/</span><span class="kw2">ffmpeg</span> <span class="re5">-i</span> <span class="st0">&quot;<span class="es2">$FILENAME</span>&quot;</span> <span class="re5">-ss</span> <span class="nu0">0</span> <span class="re5">-vframes</span> <span class="nu0">1</span> <span class="re5">-vcodec</span> mjpeg <span class="re5">-f</span> image2 <span class="st0">&quot;<span class="es3">${BASENAME}</span>Poster.jpg&quot;</span>
  logit <span class="st0">&quot;Created poster image&quot;</span>
&nbsp;
  <span class="co0"># Create a title from camelcased filename</span>
  <span class="re2">TITLE</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="st0">&quot;<span class="es2">$BASENAME</span>&quot;</span><span class="sy0">|</span><span class="kw2">sed</span> <span class="st_h">'s/\([A-Z][^A-Z]*\)/&amp; /g'</span><span class="sy0">|</span><span class="kw2">sed</span> <span class="st_h">'s/ $//'</span><span class="sy0">`</span>
  <span class="re2">SERVER</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="st0">&quot;<span class="es2">$SSHURL</span>&quot;</span><span class="sy0">|</span><span class="kw2">sed</span> <span class="st_h">'s/^.*\@//'</span><span class="sy0">`</span>
  logit <span class="st0">&quot;Uploading to <span class="es2">$SERVER</span>...&quot;</span>
  <span class="kw3">cd</span> ..
  rsync <span class="re5">-v</span> <span class="re5">-r</span> <span class="re5">-e</span> <span class="kw2">ssh</span> <span class="st0">&quot;<span class="es5">`pwd`</span>/<span class="es2">$BASENAME</span>&quot;</span> <span class="re1">$SSHURL</span>:<span class="re1">$SSHDIR</span>
  logit <span class="st0">&quot;Finished Uploading&quot;</span>
  <span class="co0"># remove trailing slash from $WEBDIR</span>
  <span class="re2">WEBDIR</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="st0">&quot;<span class="es2">$WEBDIR</span>&quot;</span><span class="sy0">|</span><span class="kw2">sed</span> <span class="st_h">'s/\/$//'</span><span class="sy0">`</span>
  <span class="kw2">cat</span> <span class="sy0">&gt;</span> <span class="st0">&quot;<span class="es2">$BASENAME</span>/<span class="es2">$BASENAME</span>.blog.markdown&quot;</span> <span class="co2">&lt;&lt;-POSTTEMPLATE
Type: Blog Post (Markdown)
Blog: BlogsmithVideo
Title: $TITLE
Keywords: 
Status: draft
Pings: On
Comments: On
Category: Tutorial
&nbsp;
Synopsis
&nbsp;
[video mp4=&quot;$WEBDIR/$BASENAME/$BASENAME.mp4&quot; ogg=&quot;$WEBDIR/$BASENAME/$BASENAME.ogv&quot; webm=&quot;$WEBDIR/$BASENAME/$BASENAME.webm&quot; poster=&quot;$WEBDIR/$BASENAME/${BASENAME}Poster.jpg&quot; preload=&quot;true&quot; width=&quot;$DISPLAYWIDTH&quot; height=&quot;$DISPLAYHEIGHT&quot;]
&nbsp;
&lt;!--more--&gt;
Transcript
&nbsp;
POSTTEMPLATE</span>
&nbsp;
  open <span class="st0">&quot;<span class="es2">$BASENAME</span>/<span class="es2">$BASENAME</span>.blog.markdown&quot;</span> <span class="re5">-a</span> <span class="st0">&quot;TextMate.app&quot;</span>
  <span class="re2">timer2</span>=<span class="sy0">`</span><span class="kw2">date</span> <span class="st_h">'+%s'</span><span class="sy0">`</span>
  <span class="re2">time</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="st0">&quot;scale=2 ; (<span class="es2">$timer2</span>-<span class="es2">$timer1</span>)/60&quot;</span><span class="sy0">|</span><span class="kw2">bc</span> -lq<span class="sy0">`</span>
  logit <span class="st0">&quot;Conversion of <span class="es2">$FILENAME</span> complete&quot;</span>
  logit <span class="st0">&quot;It took <span class="es2">$time</span> minutes to process a <span class="es3">${filesize}</span>M MP4 to webm and ogv and upload to <span class="es5">`echo &quot;$SSHURL&quot;|sed 's/^.*\@//'`</span>.&quot;</span>
<span class="kw1">done</span>
<span class="kw1">if</span> <span class="br0">&#91;</span><span class="br0">&#91;</span> <span class="re4">$#</span> <span class="re5">-gt</span> <span class="nu0">1</span> <span class="br0">&#93;</span><span class="br0">&#93;</span>; <span class="kw1">then</span>
  <span class="re2">maintimer2</span>=<span class="sy0">`</span><span class="kw2">date</span> <span class="st_h">'+%s'</span><span class="sy0">`</span>
  <span class="re2">total</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="st0">&quot;scale=2 ; (<span class="es2">$maintimer2</span>-<span class="es2">$maintimer1</span>)/60&quot;</span><span class="sy0">|</span><span class="kw2">bc</span> -lq<span class="sy0">`</span>
  logit <span class="st0">&quot;Batch conversion complete, total time <span class="es2">$total</span> minutes.&quot;</span>
<span class="kw1">fi</span></pre></div></div>


<p>Hopefully this will make a few people’s lives easier. Mike and I have battle tested it and it seems to be a pretty great fit for our needs. If you modify it for your own needs, please share (with credit) so that it can become as well-rounded as possible!</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:fnh264">
<p>The script runs a quick check using <code>mdls</code> to look for the h.264 codec. It will skip the file if it doesn’t match the criteria. It doesn’t check for AAC, but assumes that you know what you’re doing to <em>some</em> extent. If you’re running Hazel, just check for the specific extension you’re rendering to (<code>.mov</code> or <code>.mp4</code>) to avoid any hassle from the start. <a href="#fnref:fnh264" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/automating-html5-video-encodes/' rel='bookmark' title='Automating HTML5 video encodes'>Automating HTML5 video encodes</a></li>
<li><a href='http://brettterpstra.com/seriously-easy-html5-video-encoding/' rel='bookmark' title='Seriously easy HTML5 video encoding'>Seriously easy HTML5 video encoding</a></li>
<li><a href='http://brettterpstra.com/oft-bash-function-for-opening-a-specific-filetype/' rel='bookmark' title='oft: Bash function for opening a specific filetype'>oft: Bash function for opening a specific filetype</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/automated-html5-video-encoding-revisited/">Automated HTML5 video encoding revisited</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/automated-html5-video-encoding-revisited/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>TextMate drag command for Base64 encoding images</title>
		<link>http://brettterpstra.com/textmate-drag-command-for-base64-encoding-images/</link>
		<comments>http://brettterpstra.com/textmate-drag-command-for-base64-encoding-images/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 14:00:29 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[base64]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[commands]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[drag command]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=659</guid>
		<description><![CDATA[<p>Just a quick hit on this one… when hacking away at the styles of things one probably shouldn’t be hacking away at, embedding images right in the CSS is a handy trick. It’s done by Base64 encoding the image, removing line breaks from the resulting string, and using it to set the background property for the CSS rule. It looks&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/textmate-drag-command-for-base64-encoding-images/">TextMate drag command for Base64 encoding images</a></p>]]></description>
			<content:encoded><![CDATA[<p>Just a quick hit on this one… when hacking away at the styles of things one probably shouldn’t be hacking away at, embedding images right in the CSS is a handy trick. It’s done by <a href="http://en.wikipedia.org/wiki/Base64">Base64</a> encoding the image, removing line breaks from the resulting string, and using it to set the background property for the CSS rule.</p>

<p>It looks something like this (truncated):</p>

<p><code>background:url(data:image/png;base64,iVBORw0KG...AAAAASUVORK5CYII=);</code></p>

<p>The image/png changes depending on the filetype that’s encoded, becoming image/jpg or image/gif, etc. Anyway, I got tired of shelling out to encode the images, so here’s a very simple command I set up in TextMate which allows me to drag any JPEG, PNG or GIF file into a CSS rule and get the background property with encoded image all at once. Don’t try it with <em>big</em> images, but for the kind of thing you’d actually put into a CSS file, it works great.</p>

<p>The command itself is this (it’s a one-liner):</p>

<div markdown=0><pre><code>
# Drag command set to handle: jpg,png,gif
# scoped to: text.html.basic source.css.embedded.html, source.css meta.scope.property-list.css

openssl base64 -in "$TM_DROPPED_FILE" | awk -v ext="${TM_DROPPED_FILE#*.}" '{ str1=str1 $0 }END{ print "background:url(data:image/"ext";base64,"str1");" }'
</code></pre></div>

<p>It uses the <code>openssl</code> command that’s on a Mac by default. It encodes the file and outputs it to STDOUT, which is passed to awk. The extension of the dropped file is grabbed via Bash parameter substitution (<code>${TM_DROPPED_FILE#*.}</code>) and passed to awk where it’s subbed in and all of the line breaks are removed. Presto.</p>

<p>Here’s the actual TextMate command if you want to try it out and aren’t sure how to create a new one. Assuming you’re running TextMate (kind of a prerequisite for a TextMate command), just unzip and double click the file.</p>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/InsertBase64image.tmDragCommand.zip?9d7bd4" title="Download Base64 Image Encoder TextMate Drag Command (398)"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/downloads/thumbnails/2010/06/TextMateIcon.png?9d7bd4" alt="download image for Base64 Image Encoder TextMate Drag Command" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/InsertBase64image.tmDragCommand.zip?9d7bd4" title="Download Base64 Image Encoder TextMate Drag Command (398)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/InsertBase64image.tmDragCommand.zip?9d7bd4" title="Download Base64 Image Encoder TextMate Drag Command (398)">Base64 Image Encoder TextMate Drag Command</a> — Encodes a dropped image and inserts a CSS background property with the result in TextMate. Works in embedded CSS and in CSS files. <a href="http://brettterpstra.com/2010/06/19/textmate-drag-command-for-base64-encoding-images/">More Info</a></p></div>

<hr style="clear:both;visibility:hidden" />
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/a-textmate-command-for-fast-abbr-tags/' rel='bookmark' title='A TextMate Command for fast abbr tags'>A TextMate Command for fast abbr tags</a></li>
<li><a href='http://brettterpstra.com/textmate-as-writeroom-for-free/' rel='bookmark' title='TextMate as WriteRoom, for free'>TextMate as WriteRoom, for free</a></li>
<li><a href='http://brettterpstra.com/placeholder-image-textmate-snippet/' rel='bookmark' title='Placeholder image TextMate Snippet'>Placeholder image TextMate Snippet</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/textmate-drag-command-for-base64-encoding-images/">TextMate drag command for Base64 encoding images</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/textmate-drag-command-for-base64-encoding-images/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A System Service for to. url shortening</title>
		<link>http://brettterpstra.com/a-system-service-for-to-url-shortening/</link>
		<comments>http://brettterpstra.com/a-system-service-for-to-url-shortening/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 02:03:48 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[snow leopard]]></category>
		<category><![CDATA[System Service]]></category>
		<category><![CDATA[url shortener]]></category>
		<category><![CDATA[utility]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=399</guid>
		<description><![CDATA[<p>I’m fascinated by http://to. It’s a url shortener with no TLD. Some browsers, and apparently some DNS setups, don’t like the urls it creates (they want a .com or .org or anything at the end), so it’s not exactly in heavy usage. Still, I wish they had an API. In lieu of that, here’s a quick Ruby script that will&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/a-system-service-for-to-url-shortening/">A System Service for to. url shortening</a></p>]]></description>
			<content:encoded><![CDATA[<p>I’m fascinated by <a href="http://to.">http://to</a>. It’s a url shortener with no <acronym title="Top Level Domain">TLD</acronym>. Some browsers, and apparently some DNS setups, don’t like the urls it creates (they want a .com or .org or <em>anything</em> at the end), so it’s not exactly in heavy usage. Still, I wish they had an API. In lieu of that, here’s a quick Ruby script that will run on a stock OS X install as a System Service. It’s so simple that I’m not even going to package it up… It’ll be a good chance to show the steps for creating your own utilities using <a href="http://macosautomation.com/services/index.html">Snow Leopard Services</a>:</p>

<ul>
<li>Open Automator and choose “Service” from the first menu.</li>
<li>Tell it that the service “receives text” in “any application”. </li>
<li>Drag the “Run Shell Script” action from the left side. </li>
<li>Set the Shell to Ruby</li>
<li>Paste in the code below (or something of your own, hopefully far more interesting)</li>
<li>Save it with an intuitive name</li>
<li>Use it.</li>
</ul>


<div class="wp_syntax"><div class="code"><pre class="ruby"><span class="kw3">require</span> <span class="st0">'net/http'</span>
<span class="kw3">require</span> <span class="st0">'cgi'</span>
&nbsp;
input = STDIN.<span class="me1">read</span>
http = <span class="re2">Net::HTTP</span>.<span class="me1">new</span><span class="br0">&#40;</span><span class="st0">'to.'</span><span class="br0">&#41;</span>
path = <span class="st0">'/'</span>
&nbsp;
data = <span class="st0">&quot;url=#{CGI.escape(input.strip)}&quot;</span>
headers = <span class="br0">&#123;</span><span class="st0">'Content-Type'</span> <span class="sy0">=&gt;</span> <span class="st0">'application/x-www-form-urlencoded'</span><span class="br0">&#125;</span>
&nbsp;
resp, data = http.<span class="me1">post</span><span class="br0">&#40;</span>path, data, headers<span class="br0">&#41;</span>
&nbsp;
<span class="kw1">if</span> resp.<span class="me1">code</span>.<span class="me1">to_i</span> == <span class="nu0">200</span>
  <span class="kw3">print</span> data.<span class="kw3">split</span><span class="br0">&#40;</span><span class="sy0">/</span>value=<span class="st0">&quot;/)[1].split(/&quot;</span><span class="sy0">/</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>
<span class="kw1">else</span>
  <span class="kw3">print</span> input
<span class="kw1">end</span></pre></div></div>


<p>Basically, anything you can do to or with text or files using a major scripting language, you can make into a Snow Leopard service. Now that I’ve set the bar this low, I’d love to see what new Services everyone else is cooking up!</p>

<p><strong>Update:</strong> <del datetime="2010-04-29T03:34:55+00:00">Yeah, that didn’t work out so well. It works sometimes, but leaves url parameters in the shortened url half the time. I haven’t figured out why, but I’ll leave it up and see if someone can point out the error of my ways…</del><ins datetime="2010-04-29T03:34:55+00:00">Fixed it, just neglected to notice it needed a POST, not a GET</ins></p>

<p><strong>Update 2:</strong> Here, this one’s shorter and more useful :)</p>


<div class="wp_syntax"><div class="code"><pre class="ruby"><span class="kw3">require</span> <span class="st0">'open-uri'</span>
<span class="kw3">require</span> <span class="st0">'cgi'</span>
&nbsp;
input = STDIN.<span class="me1">read</span>
<span class="kw3">print</span> <span class="kw3">open</span><span class="br0">&#40;</span><span class="st0">&quot;http://is.gd/api.php?longurl=#{CGI.escape(input.strip)}&quot;</span><span class="br0">&#41;</span>.<span class="me1">read</span></pre></div></div>

<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/is-your-url-too-short-try-our-system-free/' rel='bookmark' title='Is your URL too short? Try our system, free!'>Is your URL too short? Try our system, free!</a></li>
<li><a href='http://brettterpstra.com/textexpander-bit-ly-with-authentication/' rel='bookmark' title='TextExpander: bit.ly with authentication'>TextExpander: bit.ly with authentication</a></li>
<li><a href='http://brettterpstra.com/textexpander-experiments/' rel='bookmark' title='TextExpander experiments'>TextExpander experiments</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/a-system-service-for-to-url-shortening/">A System Service for to. url shortening</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/a-system-service-for-to-url-shortening/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>fk: redux</title>
		<link>http://brettterpstra.com/fk-redux/</link>
		<comments>http://brettterpstra.com/fk-redux/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 17:49:15 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/2010/03/06/fk-redux/</guid>
		<description><![CDATA[<p>Just a quick change to my post on the bash function fk that I’ve been using. A small modification has greatly improved its usability: make the cancel option always be first in the menu. Just move “Cancel” before the $(fp $1) bit. It’s a little odd that I didn’t do that to begin with… fp () { #find and list&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/fk-redux/">fk: redux</a></p>]]></description>
			<content:encoded><![CDATA[<p>Just a quick change to <a href="http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/">my post on the bash function <code>fk</code></a> that I’ve been using. A small modification has greatly improved its usability: make the cancel option always be first in the menu. Just move “Cancel” before the <code>$(fp $1)</code> bit. It’s a little odd that I didn’t do that to begin with…</p>

<div markdown=0>
<pre><code>
fp () { #find and list processes matching a case-insensitive partial-match string
        ps Ao pid,comm|awk &#x27;{match($0,/[^\/]+$/); print substr($0,RSTART,RLENGTH)&quot;: &quot;$1}&#x27;|grep -i $1|grep -v grep
}

fk () { 
    IFS=$&#x27;\n&#x27;
    PS3=&#x27;Kill which process? (1 to cancel): &#x27;
    select OPT in &quot;Cancel&quot; $(fp $1); do
        if [ $OPT != &quot;Cancel&quot; ]; then
            kill $(echo $OPT|awk &#x27;{print $NF}&#x27;)
        fi
        break
    done
    unset IFS
}
</code></pre>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/fk-a-useful-bash-function/' rel='bookmark' title='fk: a useful bash function'>fk: a useful bash function</a></li>
<li><a href='http://brettterpstra.com/oft-bash-function-for-opening-a-specific-filetype/' rel='bookmark' title='oft: Bash function for opening a specific filetype'>oft: Bash function for opening a specific filetype</a></li>
<li><a href='http://brettterpstra.com/bash-auto-complete-for-running-applications/' rel='bookmark' title='Bash auto-complete for running applications'>Bash auto-complete for running applications</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/fk-redux/">fk: redux</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/fk-redux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic (Feed is rejected)
Page Caching using disk: enhanced
Database Caching 15/73 queries in 0.192 seconds using xcache
Object Caching 1871/1948 objects using xcache
Content Delivery Network via cdn2.brettterpstra.com

Served from: brettterpstra.com @ 2012-05-23 04:26:24 -->
