aboutsummaryrefslogtreecommitdiff
path: root/build/blog/2015-05-09-storyboard-reached-01.html
diff options
context:
space:
mode:
Diffstat (limited to 'build/blog/2015-05-09-storyboard-reached-01.html')
-rw-r--r--build/blog/2015-05-09-storyboard-reached-01.html113
1 files changed, 113 insertions, 0 deletions
diff --git a/build/blog/2015-05-09-storyboard-reached-01.html b/build/blog/2015-05-09-storyboard-reached-01.html
new file mode 100644
index 00000000..dfb0c953
--- /dev/null
+++ b/build/blog/2015-05-09-storyboard-reached-01.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<meta content="pandoc" name="generator"/>
+<meta content="Zhiming Wang" name="author"/>
+<meta content="2015-05-09T00:32:28-07:00" name="date"/>
+<title>storyboard reached 0.1</title>
+<link href="/img/apple-touch-icon-152.png" rel="apple-touch-icon-precomposed"/>
+<meta content="#FFFFFF" name="msapplication-TileColor"/>
+<meta content="/img/favicon-144.png" name="msapplication-TileImage"/>
+<meta content="width=device-width, initial-scale=1" name="viewport"/>
+<link href="/css/normalize.min.css" media="all" rel="stylesheet" type="text/css"/>
+<link href="/css/theme.css" media="all" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="archival-notice">This blog has been archived.<br/>Visit my home page at <a href="https://zhimingwang.org">zhimingwang.org</a>.</div>
+<nav class="nav">
+<a class="nav-icon" href="/" title="Home"><!--blog icon--></a>
+<a class="nav-title" href="/"><!--blog title--></a>
+<a class="nav-author" href="https://github.com/zmwangx" target="_blank"><!--blog author--></a>
+</nav>
+<article class="content">
+<header class="article-header">
+<h1 class="article-title"><code>storyboard</code> reached 0.1</h1>
+<div class="article-metadata">
+<time class="article-timestamp" datetime="2015-05-09T00:32:28-07:00">May 9, 2015</time>
+</div>
+</header>
+<p>For quite some time I've been working on a Python project called <a href="https://github.com/zmwangx/storyboard"><code>storyboard</code></a>, and today I finally released the 0.1 stable (or you can think of it as 1.0).</p>
+<p>As described on <a href="https://storyboard.readthedocs.org/en/0.1/index.html">the index page</a>,</p>
+<blockquote>
+<p><code>storyboard</code> is a FFmpeg-based customizable video storyboard generator with metadata reporting directly embedded in the generated images. Reported metadata fields include, but are not limited to, title, filename, file size, SHA-1 digest, container format, duration, pixel dimension, display aspect ratio (DAR), scan type (progressive, interlaced, or telecined), frame rate, and per-stream metadata (type, codec, profile, dimensions, bitrate, etc.).</p>
+</blockquote>
+<p>And the motivation was</p>
+<blockquote>
+<p><code>storyboard</code> was inspired by the storyboards I frequently encounter on video-sharing Internet forums, mostly generated by proprietary video players. Those storyboards often come with video/file metadata bundled, which I see as a great all-in-one solution for video sharing, saving one the labor of typing multiple console commands, copying and pasting output, and worrying about the forum’s crappy formatting. However, I, for one, dislike proprietary players. Also, those storyboards are usually ugly and uninformative, using stupid fonts and lacking crucial information that hackers look for (e.g., hash). Therefore, I developed this customizable storyboard generator for hackers.</p>
+</blockquote>
+<p>The project itself isn't very important, and I don't see any possibility of it gaining recognition; but its educational value to me was pretty huge. This is the first full package I ever developed, in the sense that it's complete with documentation, test suites, continuous integration and tested portability, as well as distributed to a package index (<a href="https://pypi.python.org/pypi/storyboard">PyPI</a> in this case). Here's what I observed and learned:</p>
+<ol style="list-style-type: decimal">
+<li><p>It's just really different from casual hacking, where I would try to achieve what I need in the shortest amount of programmer time possible, drop hard-coded values (even OAuth tokens) in scripts, leave things undocumented, etc. I'm a perfectionist so my casual code is usually not so bad, but <code>storyboard</code> is just different — to ensure quality of API and CLI, I wrote more documentation than actual code. Through this project I realized how hard real-world coding (or idealized real-world coding) is: the initial 10% is excitement, and the rest is just chores (compare that to casual hacking, where at least 30% is excitement).</p></li>
+<li><p>Write once, debug everywhere. Not really, but ensuring portability is really difficult. Trying to debug something on a platform which I can't lay my hands upon is insanely frustrating. This afternoon I spent a long time trying to pin down a weird hanging bug on AppVeyor; the complete process is documented in <a href="https://github.com/zmwangx/storyboard/commit/e8a28e5a92f744157fedd03893fa8fe5a5e7d445">this squashed commit</a>. In the end the bug wasn't in my program, but in that specific version of FFmpeg (which I wouldn't believe since FFmpeg is really stable from my experience), or that specific version of FFmpeg combined with AppVeyor, or that specific version of FFmpeg combined with AppVeyor combined with Azure, or... who knows. The only thing I could say is it was not in my program, because I could reproduce the infinite loop in <code>ffprobe</code> even before I launched my program... Anyway, in this case I can lay my hands on the platform, just indirectly and painful. What about real world development where developers need to handle bug reports from users who could have broken everything? I don't want to imagine.</p></li>
+<li><p>The project was a clear manifestation of Hofstadter's law:</p>
+<blockquote>
+<p>It always takes longer than you expect, even when you take into account Hofstadter's Law.</p>
+</blockquote>
+<p>Enough said; so true. In fact, towards the end of the development cycle I got pretty bogged down<a class="footnoteRef" href="#fn1" id="fnref1"><sup>1</sup></a> and stopped for a while to work on renovating this blog (60% excitement!). Meanwhile, I was too busy with other parts of life, so I rushed towards the stable 0.1 release in the past two days, dropping several ideas I wanted to implement (for completeness). Although I "rushed", it still took at least four times as long as I expected.</p></li>
+</ol>
+<p>Anyway, here it is, the <a href="https://github.com/zmwangx/storyboard/releases/tag/0.1">0.1</a> <a href="https://pypi.python.org/pypi/storyboard/0.1">release</a>. The badges certainly weren't bad:</p>
+<div class="figure">
+<a href="https://i.imgur.com/miOoX5Y.png" target="_blank"><img alt="storyboard's got quite a few badges of honor" src="https://i.imgur.com/miOoX5Y.png"/></a>
+<p class="caption"><code>storyboard</code>'s got quite a few badges of honor</p>
+</div>
+<p>I created <a href="https://asciinema.org/a/19782">an asciinema recording</a> to commemorate the release (the original asciicast is <a href="https://dl.bintray.com/zmwangx/generic/storyboard-0.1-walkthrough-asciicast.json">here</a>):<a class="footnoteRef" href="#fn2" id="fnref2"><sup>2</sup></a></p>
+<div style="width: 672px; text-align: center; margin: auto;">
+<script async="" id="asciicast-19782" src="https://asciinema.org/a/19782.js" type="text/javascript"></script>
+<noscript>
+Javascript disabled. Check out the cast <a href="https://asciinema.org/a/19782">here</a>.
+</noscript>
+</div>
+<p>And, just to demonstrate <code>storyboard</code>, I re-screen-recorded the asciinema screencast with QuickTime, saved to <a href="https://dl.bintray.com/zmwangx/generic/storyboard-0.1-walkthrough.mov">an MOV file</a>, and ran it through my <code>metadata</code> and <code>storyboard</code>:</p>
+<pre><code>&gt; metadata storyboard-0.1-walkthrough.mov
+Filename: storyboard-0.1-walkthrough.mov
+File size: 60418244 (57.7MiB)
+Container format: QuickTime movie
+Duration: 00:06:36.30
+Pixel dimensions: 672x846
+Display aspect ratio: 112:141
+Scan type: Progressive scan
+Frame rate: 60 fps
+Streams:
+ #0: Video, H.264 (Main Profile level 3.2), 672x846 (DAR 112:141), 60 fps, 1213 kb/s
+
+&gt; storyboard storyboard-0.1-walkthrough.mov
+Processing storyboard-0.1-walkthrough.mov
+Crunching metadata...
+Trying to determine scan type...
+Inspecting frame 40/40...
+Generating main storyboard...
+Extracting frame 16/16...
+Generating thumbnail 16/16...
+Tiling thumbnails...
+Generating metadata sheet...
+Computing SHA-1 digest...
+57.7MiB 0:00:00 [ 571MiB/s] [=================================================================================&gt;] 100%
+Generating promotional banner...
+Assembling pieces...
+
+storyboard saved to: /tmp/storyboard-se3fbiif.jpg
+</code></pre>
+<p>Here's the actual image:</p>
+<div class="figure">
+<a href="https://i.imgur.com/c3E3M8R.jpg" target="_blank"><img alt="storyboard of storyboard-0.1-walkthrough.mov (1964x2694), generated with the default settings by storyboard 0.1" src="https://i.imgur.com/c3E3M8R.jpg"/></a>
+<p class="caption">storyboard of <code>storyboard-0.1-walkthrough.mov</code> (1964x2694), generated with the default settings by <code>storyboard 0.1</code></p>
+</div>
+<p>Credit to <code>lolcat</code> for making my storyboard colorful.</p>
+<div class="footnotes">
+<hr/>
+<ol>
+<li id="fn1"><p>I was implementing stuff that I wouldn't ever need myself — for completeness, and that was not rewarding in the slightest.<a class="footnotes-backlink" href="#fnref1">↩︎</a></p></li>
+<li id="fn2"><p>The screencast's color scheme is actually off in some places, since in my iTerm2 bold font is displayed as bold, not bright.<a class="footnotes-backlink" href="#fnref2">↩︎</a></p></li>
+</ol>
+</div>
+</article>
+<hr class="content-separator"/>
+<footer class="footer">
+<span class="rfooter">
+<a class="rss-icon" href="/rss.xml" target="_blank" title="RSS feed"><!--RSS feed icon--></a><a class="atom-icon" href="/atom.xml" target="_blank" title="Atom feed"><!--Atom feed icon--></a><a class="cc-icon" href="https://creativecommons.org/licenses/by/4.0/" target="_blank" title="Released under the Creative Commons Attribution 4.0 International license."><!--CC icon--></a>
+<a href="https://github.com/zmwangx" target="_blank">Zhiming Wang</a>
+</span>
+</footer>
+</body>
+</html>