Subscribed unsubscribe Subscribe Subscribe

flv2avi (iAudio X5向け)

PC

世界各国からflv2aviと検索してくる人がいるので,ちょっとメモを書こうと思う.manpageを一目見ればわかるとおり,mencoderのオプションは大量でちゃんと読む気も失せる充実ぶり.仕方なく日本語でなおかつX5向けというニッチ向けのメモになった.

必要なオプション

コーデックは映像・音声ともにlibavcodecを使えばよい模様.気をつけなければならないのはビットレートとフレームレートをいくつにするかということ.マニュアルやまとめサイトを見る限り

  • 画面サイズ160x128
  • フレームレート15fps以下
  • ビットレート約240kbps以下

という条件を満たすmpeg4なら良いようだが,パラメータを調整しないとエンコードに失敗したり,成功してもX5で再生すると映像と音声が大きくずれて音声が途中までしか再生されなかったりすることが起きる.何度か調整してみたところ,YouTubeのflvビデオはビットレート128k,フレームレートは10fpsにするのが一番良いようだ.

従ってmencoderのオプションは次のようになる.

mencoder <input file> -ofps 10 -vf scale=160:-3 -oac lavc -ovc lavc -lavcopts acodec=mp3:abitrate=128:vbitrate=128 -o <output file>

ここでHaskell

毎回このオプションを指定するのは大変面倒なので,Playing Movies on the iAudio X5のようにスクリプトを書くのがよい.

x5enc() {
    mencoder $1 -ofps 10 -vf scale=160:-3 -oac lavc -ovc lavc -lavcopts acodec=mp3:abitrate=128:vbitrate=128 -o $2
}

ここで出力ファイル名を指定するのではなく,勝手に拡張子を変えてくれると嬉しい.でも正規表現とかよくわからんしなあということでHaskellで書くことにした.

module Main where 
import System
import System.Process
import Data.List

main :: IO ()
main = do
  args <- getArgs
  case args of
    [] -> usage
    fs -> mapM_ x5enc fs

usage :: IO ()
usage = putStrLn "usage: x5enc files"

x5enc :: FilePath -> IO ExitCode
x5enc f = do
  ph <- runCommand $ "mencoder " ++ escape f ++ " -ofps 10 -vf scale=160:-3 -oac lavc -ovc lavc -lavcopts acodec=mp3:abitrate=128:vbitrate=128 -o " ++ rename (escape f)
  waitForProcess ph

escape :: FilePath -> FilePath
escape []        = []
escape (' ':xs)  = "\\ " ++ escape xs
escape ('\'':xs) = "\\'" ++ escape xs
escape ('#':xs)  = "\\#" ++ escape xs
escape (':':xs)  = "\\:" ++ escape xs
escape (x:xs)    = x:escape xs

rename :: FilePath -> FilePath
rename f = case break (== '.') $ reverse f of
             (_,[]) -> f ++ ".avi"
             (_,xs) -> reverse xs ++ "avi"

長い.でも文字列がリストって嬉しいね.コマンド自体が単純な文字列なのは微妙だね.エラーチェックしてないね.拡張子を付け替えた後の名前と同一名のファイルがあったら,何の警告も無しに上書きするね.まあいいか.

ちなみにshで空白を含むファイル名をスクリプトの引数として正しく扱うには環境変数IFSを変更するのが常套手段らしい.

IFS=$'\n'

とでもしておけば間違いないそうだ.