SmallStyle


2007-10-29

_ plaggerのFilter::FFmpegで変換するときにファイル名が文字化けしてエラーになる

ニコニコ動画/YouTube の動画を Plagger で落として変換しようとした記録(3) - HsbtDiary(2007-10-29)について,週末に同じことをやろうとして,文字化けについては自分の環境では解決したっぽいので,せっかくだから書いておこう.ちなみに実行環境は OS X 上で文字コードは UTF-8 の環境です.

以下の yaml で実行してみる.

(略)
- module: Filter::FFmpeg
  config:
    dir: /tmp/work
    ext: MP4
    command: /opt/local/bin/ffmpeg
    encoding: utf-8
    option_string: '-y -threads 4 -s 640x480 -r 29.97 -vcodec xvid -g 250 -aspect 4:3 -b 600 -level 13 -loop 1 -sc_threshold 40 -partp4x4 1 -rc_eq blurCplx^(1-qComp) -refs 3 -maxrate 768 -async 50 -acodec aac -ar 44100 -ac 2 -ab 128'

で,実行してみると以下のようなエラーで変換に失敗する.

Plagger::Plugin::Filter::FFmpeg [info] Converting ぬこぬこトーク ...
Plagger::Plugin::Filter::FFmpeg [error] FFmpeg version SVN-r9102, Copyright (c) 2000-2007 Fabrice Bellard, et al.
 configuration: --prefix=/opt/local --prefix=/opt/local --disable-vhook --mandir=/opt/local/share/man --enable-shared --enable-pthreads --enable-libmp3lame --enable-libogg --enable-libvorbis --enable-libtheora --enable-gpl --enable-libfaac --enable-libfaad --enable-xvid --enable-x264 --enable-liba52
 libavutil version: 49.4.0
 libavcodec version: 51.40.4
 libavformat version: 51.12.1
 built on Oct 22 2007 01:34:17, gcc: 4.0.1 (Apple Computer, Inc. build 5367)
/tmp/work/???????????.flv: no such file or directory

まぁ,見てのとおりファイル名が化けてしまっている(???? の部分は実際は変な記号で化けています)ので,対象のファイルがありませんよー,ということ.文字コード問題ってのはどこにでもつきもののややこしいものです.

いろいろと調べてみた結果,UTF-8 フラグというのがキーワードっぽい.これがついてると何かと文字化けを引き起こす原因となっているらしい.そこで FFmpeg.pm に以下の関数を追加して,UTF-8 フラグがあれば除去してencodeするようにしてみた.

sub convert
  my ($self, $str) = @_;
  utf8::decode($str) unless utf8::is_utf8($str);
  return encode($self->conf->{encoding} || 'cp932', $str);
}

上記コードは,Publish::Pipe にあったものをそのまま利用しました.で,FFmpeg.pm 内で,

encode($encoding, $enclosure->local_path)

のような,encodeしている部分を,

$self->convert($enclosure->local_path)

先ほど追加した関数を通すようにしたところ,文字化けせずにファイルを出力できるようになりました.

一応,diffを貼付けておきます.

--- FFmpeg.pm.old       2007-09-24 22:10:10.000000000 +0900
+++ FFmpeg.pm   2007-10-29 22:05:44.000000000 +0900
@@ -48,15 +48,15 @@
         }

         my $ff = FFmpeg::Command->new($self->conf->{command});
-        $ff->input_options({ file => encode($encoding, $enclosure->local_path) });
+        $ff->input_options({ file =>  $self->convert($enclosure->local_path) });

         my $output_file = File::Spec->catfile($self->conf->{dir}, "$file");
         my $output_options = {
-            file    => encode($encoding, $output_file),
+            file    => $self->convert($output_file),
             device  => $self->conf->{device} || 'ipod',
-            title   => encode($encoding, $entry->title),
-            author  => encode($encoding, $entry->author),
-            comment => encode($encoding, $entry->summary),
+            title   => $self->convert($entry->title),
+            author  => $self->convert($entry->author),
+            comment => $self->convert($entry->summary),
             %{ $self->conf->{options} || {} },
         };

@@ -91,6 +91,13 @@
     }
 }

+
+sub convert {
+  my ($self, $str) = @_;
+  utf8::decode($str) unless utf8::is_utf8($str);
+  return encode($self->conf->{encoding} || 'cp932', $str);
+}
+
 1;
 __END__

試した環境は OS X 上なので,その他の環境でうまくいくかどうかわかりませんが,文字化けでお悩みの場合は一度お試しあれ.

Perl についてはあまりよく理解していないので,間違っていればどしどしご指摘ください.


about me

いろいろと興味を持ったことを書いてます.ちょっとしたことは hb(@smallstyle) on Twitter で書いてます.

Archive

2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|12|