debian linuxで手軽にプログレッシブ再生可能なh.264ファイルをエンコード

はじめに

apt-getで入手できるパッケージだけを使って、Flash Playerでプログレッシブ再生可能なh.264動画を作成する方法のメモです。ffmpeg関係は何かとハマる作業が多いのですが、この方法は僕が今まで試した中で一番手軽でした。

ffmpegとgpacのインストール

apt-getだけといっても標準のリポジトリではパッケージが足りないので、www.debian-multimedia.orgがsources.listにあることが前提です。ない場合は/etc/apt/sources.listに以下を追加、debianのバージョン指定は読み替えて下さい。

deb http://www.debian-multimedia.org etch main

h.264エンコードするためにffmpegを、出力されたmp4ファイルをプログレッシブ再生可能にするためにgpacを使います。両方ともwww.debian-multimedia.orgにあるので、apt-getでインストールします。

apt-get install ffmpeg gpac

mp4ファイルの作成

あとはお好みのオプションでmp4ファイルにエンコード。しかし、このmp4ファイルはメタデータの位置がメディアデータより後ろにあり、このままでは全てのデータを読まないと再生できないそうです。

ffmpeg -i hoge.avi -f mp4 -vcodec h264 -acodec aac piyo.mp4

プログレッシブ再生を可能にするには、ffmpegで吐き出したmp4ファイルをMP4Boxで出力し直して、メタデータがメディアデータの前に来るよう、ボックスを並び替えてやれば良いようです。

MP4Box -add piyo.mp4 -new fuga.mp4

感想

On2VP6を使った高画質なflvファイルをWindows以外の環境でエンコードするのは難しかったのですが、比較的新しいFlash Playerではコーデックとしてh.264がサポートされたため、LinuxできれいなFlash用ムービーを作るのが格段に簡単になった印象です。

ただし自分でffmpegをビルドしていないので、扱えるフォーマットがやや限られています。例えばsvn版ではサポートしているらしいwmv3がデコードできないため、ソースがwmvだと色々と不便がありそうです。

typo補足

typoインストールの覚え書き - 黒糖々日記/kokutoto diaryでadministration.cssのパスが適切でないと書きましたが、24日にリリースされたtypo 5.0.3では既に修正されています。ただしtypo 5.0.3はRails app installerがRails 2.0.2でバグっており、インストールしてもTypoがまともに動かないのでgemが提供されないそうです。

No gem?

We won’t provide you the habitual gem we used to. Rails app installer – formerly known as Typo installer – is brocken with Rails 2.0.2 and Typo instances installed this way just don’t work.

http://blog.typosphere.org/articles/2008/02/24/typo-5-0-3-don-mc-cullin-release

http://rubyforge.org/frs/?group_id=555&release_id=19512で確認してもTypoのアップグレードは間隔が空く場合があるようなので、下手に安定版のgemをインストールするのではなく、svnからtrunkを取得したほうが良いのかも知れません。

時間を空けてしまうと書けない

気づいたら最後の投稿から1ヶ月以上経ってしまいました。「パブリックにアウトプットを出す!」を今年の目標にしているのですが、書きたいと思っていることはあっても、時間を空けてしまいblogに書くタイミングを逃してしまう…というのを繰り返していた気がします。これからはもっと意識的に「書きたいと思ったら即座に書く」を実行していこうと思います。

typoインストールの覚え書き

debian etchtypoをインストールしてmongrelで動作させApache(mod_proxy)経由でアクセスできるようにするまでの覚え書きです。gemsは少しだけ使ったことがあっても、railsはアプリケーションのインストールを含めて初めてでした。

typoのインストール手順

typoはgemsにもあるのですが、ざっと検索してみるとsvnで入手している人も多いようです。このあたりは好みの問題でしょうか。僕はgemsを使ってインストールしました。

gem install -y typo --remote

typo install /some/pathを実行すると/some/pathに実体がコピーされます。その後、自動的に実行されるテストがすべて正常終了して、mongreltypoが走るのを確認します。

typo installにはオプションが指定でき、例えばport-numberはmongrelが待ち受けるポート番号を、url-prefixはパスをそれぞれ指定できるようです。インストール後も設定はtypo configで変更できます。

下記のようにするとhttp://example.org:4000/blog/のような感じでアクセスできるようになります。

typo install /some/path port-number=4000 url-prefix=/blog

Apache(mod_proxy)の設定

Apache2.2系でmod_proxy、mod_proxy_httpが有効になっていることが前提です。設定方法はあらかたInstaller/apache20.conf.exampleに書いてある通りですが一応。

ローカルhttp://localhost:4000/blog/で動作しているtypoに、リモートからhttp://example.org:80/blog/でアクセスできることを目標に、リバースプロキシを設定します。

mod_proxyそのものの設定。debianだと/etc/apache2/mods-enabled/proxy.confが一般的。

<IfModule mod_proxy.c>
        ProxyRequests Off

        <Proxy *>
                AddDefaultCharset off
                Order deny,allow
                Allow from all
        </Proxy>

        ProxyVia On
</IfModule>

例えば/etc/apache2/sites-enabled/typo.confは以下のような感じ。

<VirtualHost *:80>
	#省略

    <Location /blog>
        ProxyPass http://localhost:4000/blog
        ProxyPassReverse http://localhost:4000/blog
    </Location>

    ProxyPreserveHost On
</VirtualHost>

ハマった点まとめ

すんなり行くかと思いきや、意外に落とし穴が多かったです。もっと素直な環境でgemsやrailsに慣れていれば、こんなハマり方はしないと思います。日々邁進。

gemsのbinにパスが通っていない
apt-get install rubygems

でインストールしてもgemsのbinディレクトリ(/var/lib/gems/1.8/bin/)にパスは通らないようです。僕は/etc/profileや~/.bashrcからPATHに/var/lib/gems/1.8/binを加えてexportしてやることにしました。

export=$PATH:/bar/lib/gems/1.8/bin

type installにはsystem()を使ってrakeを呼んでいる箇所があるので、rakeにパスが通っていないユーザで無理にインストールしようとすると、下記のようなエラーが出てしまいました。rakeをapt-getではなくgemからインストールしていたのでハマりかけました。

/var/lib/gems/1.8/gems/typo-5.0.2/bin/typo:59:in `migrate': Migration failed (RailsInstaller::InstallFailed)
        from /var/lib/gems/1.8/gems/rails-app-installer-0.2.0/lib/rails-installer.rb:689:in `in_directory'
        from /var/lib/gems/1.8/gems/typo-5.0.2/bin/typo:57:in `migrate'
        from /var/lib/gems/1.8/gems/rails-app-installer-0.2.0/lib/rails-installer.rb:217:in `install_sequence'
        from /var/lib/gems/1.8/gems/rails-app-installer-0.2.0/lib/rails-installer.rb:192:in `install'
        from /var/lib/gems/1.8/gems/rails-app-installer-0.2.0/lib/rails-installer/commands.rb:95:in `command'
        from /var/lib/gems/1.8/gems/rails-app-installer-0.2.0/lib/rails-installer.rb:646:in `execute_command'
        from /var/lib/gems/1.8/gems/typo-5.0.2/bin/typo:93
        from /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in `load'
        from /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in `load'
        from /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
        from /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in `load'
        from /var/lib/gems/1.8/bin/typo:18
published?でTests failed

インストール時のテストが失敗してしまいました。起動もして一見まともに動いているようなのに、投稿画面を開くとデータベースまわりでエラーが起こるらしく、published?を呼ぶ箇所でApplication Errorが発生するという症状がでました。

類似の症状がないか探してみたのですが見つからず。しばらく悩んだ末、gemsのものとは別にaptからlibsqlite3-rubyをインストールしていたのを思い出し、これを削除して改めてgemsのsqlite3-rubyを入れたら何事もなく動作しました。

aptにもパッケージがあるのは大変助かるのですが、やはり混ざってしまうと色々と問題があるようですね…。それまでaptを使っていてgemsを使い始めたような場合は注意が必要そうです。

管理画面で背景画像が表示されない

管理画面のCSSはbackgroundのurlが絶対パスで指定されているので、インストールの際に設定でurl-prefix=/blogなどと指定していると、背景画像が抜けてしまうことがわかりました。

以下のようにpublic/stylesheets/administration.css中の絶対パス相対パスで書き直すとうまく表示できました。

--- administration.css	2008-02-24 17:27:03.000000000 +0900
+++ administration.css_orig	2008-02-22 23:03:20.000000000 +0900
@@ -20,7 +20,7 @@
 #topnav {
   height: 36px;
   margin: 0;
-  background: transparent url("../images/admin/bgoff.png") repeat-x top left;
+  background: transparent url("/images/admin/bgoff.png") repeat-x top left;
   font: 12px Tahoma, Helvetica, sans-serif;
 }
 
@@ -48,19 +48,19 @@
   text-decoration: none;
   color: #333;
   text-transform: capitalize;
-  background: transparent url("../images/admin/bgdivider.png") no-repeat top right;
+  background: transparent url("/images/admin/bgdivider.png") no-repeat top right;
 }
 
 /* OK */
 #topnav  ul li a:hover {
   color: #fff;
-  background: #fff url("../images/admin/bgover.png") repeat-x top left;
+  background: #fff url("/images/admin/bgover.png") repeat-x top left;
 }
 
 /* OK */
 #topnav ul li a.current {
   color: #fff;
-  background: #fff url("../images/admin/bgselected.png") repeat-x top left;
+  background: #fff url("/images/admin/bgselected.png") repeat-x top left;
 }
 
 /* OK */
@@ -238,7 +238,7 @@
 }
 
 .list table th {
-	background: url("../images/admin/table-header.png") #324e79 repeat-x;
+	background: url("/images/admin/table-header.png") #324e79 repeat-x;
   text-align: left;
   font-weight: bold;
   padding: 2px 5px;
@@ -248,11 +248,11 @@
 }
 
 .list table th.first {
-	background: url("../images/admin/table-header-first.png") #324e79 top left no-repeat;
+	background: url("/images/admin/table-header-first.png") #324e79 top left no-repeat;
 }
 
 .list table th.last {
-	background: url("../images/admin/table-header-last.png") #324e79 top right no-repeat;
+	background: url("/images/admin/table-header-last.png") #324e79 top right no-repeat;
 }
 .list table th a {
 	color: #fff;
@@ -284,7 +284,7 @@
 }
 
 .paginate {
-  background: url("../images/admin/bc-bg.gif") repeat-x top left;
+  background: url("/images/admin/bc-bg.gif") repeat-x top left;
   padding: 5px 20px;
   margin-bottom: 15px;
 	border-left: #ddd 1px solid;
@@ -503,7 +503,7 @@
 
 /* OK */
 #available h3, #active h3, #cnt-active h3 {
-  background: url("../images/admin/bc-bg.gif") #b5b5b5 top left repeat-x;
+  background: url("/images/admin/bc-bg.gif") #b5b5b5 top left repeat-x;
   color: #000;
   margin: 0 0 10px 0;
   padding: 2px 5px;
@@ -516,7 +516,7 @@
 
 /* OK */
 .handle {
-	background: url("../images/admin/table-header-first.png") #324e79 top left no-repeat;
+	background: url("/images/admin/table-header-first.png") #324e79 top left no-repeat;
 	color: #fff;
   cursor: move;
   font-size: 13px;
@@ -531,7 +531,7 @@
 
 /* OK */
 .dragitem {
-	background: url("../images/admin/loginformbg.png") #fff bottom left no-repeat;
+	background: url("/images/admin/loginformbg.png") #fff bottom left no-repeat;
   width: 300px;
 }
 
@@ -724,7 +724,7 @@
 #page_form input.submit,
 .submit {
 	width: 260px;
-	background: url("../images/admin/bc-bg.gif") #b5b5b5 top left repeat-x;
+	background: url("/images/admin/bc-bg.gif") #b5b5b5 top left repeat-x;
 	font: 14px "Trebuchet MS", Helvetica, sans-serif;
 }
 
@@ -745,7 +745,7 @@
 /* OK */
 #loginform div.form {
   border: none;
-  background: url("../images/admin/loginformbg.png") #fff bottom left no-repeat;
+  background: url("/images/admin/loginformbg.png") #fff bottom left no-repeat;
   margin-bottom: 10px;
   padding: 30px 10px 10px;
 }
@@ -753,7 +753,7 @@
 /* OK */
 #loginform h3 {
 	text-align: left;
-	background: url("../images/admin/bgoff.png") #f00 repeat-x top left;
+	background: url("/images/admin/bgoff.png") #f00 repeat-x top left;
 }
 
 /* OK */
@@ -812,7 +812,7 @@
 }
 
 #flash .notice {
-  background: url("../images/admin/bc-bg.gif") #ccc repeat-x;
+  background: url("/images/admin/bc-bg.gif") #ccc repeat-x;
   border: 1px solid #336699;
 }
 
@@ -877,14 +877,14 @@
 .dashboard h3 {
 	padding: 0;
 	margin: 0;
-	background: url("../images/admin/table-header-first.png") #324e79 top left no-repeat;
+	background: url("/images/admin/table-header-first.png") #324e79 top left no-repeat;
 	font-size: 14px;
 	font-weight: normal;
 }
 
 /* OK */
 .dashboard h3 span {
-	background: url("../images/admin/table-header-last.png") top right no-repeat;
+	background: url("/images/admin/table-header-last.png") top right no-repeat;
 	display: block;
 	padding: 0 3px;
 }
@@ -916,7 +916,7 @@
 
 .theme-filer {
 	width: 300px;
-	background: url('../images/admin/loginformbg.png') no-repeat scroll left bottom;
+	background: url('/images/admin/loginformbg.png') no-repeat scroll left bottom;
 	padding: 5px 0;
 	margin-bottom: 15px;
 }
@@ -932,7 +932,7 @@
 }
 
 #theme_list h3 {
-	background: url("../images/admin/table-header-first.png") #324e79 top left no-repeat;
+	background: url("/images/admin/table-header-first.png") #324e79 top left no-repeat;
 	color: #fff;
   cursor: move;
   font-size: 13px;

はてなフォトライフよりFlickr

常識なのかも知れませんが、単に写真をブログに貼る目的なら、はてなフォトライフよりFlickrの方が断然良さそうですね。

はてなフォトライフがサービスとして貧弱だというより、Flickrの太っ腹ぶりと気の利き方が異常という印象です。

FlickrToBlog

問題はFlickrの写真をはてなダイアリーに貼り付けるのが少し面倒という点ですが、まちゅさんの公開しているFlickrToBlogというBookmarkletを見つけました。

Flickr の写真をブログへ載せるための Bookmarklet - まちゅダイアリー(2008-01-13)

FlickrToBlogはFlickrの写真をブログへ載せるためのBookmarkletで、起動すると写真の一覧がポップアップして、クリックするだけでFlickrの写真を表示するタグが挿入されます。これは便利。

flickr2blog

ブラウズしているページのtextareaを見つけてタグを挿入する仕組みのため、はてなダイアリーに限らず、いろいろなブログサービスで利用可能だそうです。これでかなりFlickrの写真が使いやすくなりますね。

ちょこっと改造

FlickrToBlogの挿入するimgタグは、title属性はついているのに、HTML4.01で必須のalt属性がついていません。できるだけ正確にマークアップしたいので、僕はここだけ改造して使っています。

Index: flickr2blog.js
===================================================================
--- flickr2blog.js      (revision 5028)
+++ flickr2blog.js      (working copy)
@@ -218,7 +218,7 @@
   // HTML
   html: {
     link: function(webUrl, srcUrl, photo, size) {
-      var img = '<img src="' + srcUrl + '" title="' + photo.title + '">';
+      var img = '<img src="' + srcUrl + '" title="' + photo.title + '" alt="' +  photo.title + '">';
       return '<a href="' + webUrl + '">' + img + '</a>';
     },
     textarea: function() {

*1:ただし無料のサービスだとFlickrで表示できる写真が200枚に制限されるようです。http://www.flickr.com/help/photos/#34