2017年12月12日

ffmpegって名前付きパイプだとうまくいかないのかなぁ…と思いかけた落とし穴にハマる

(1)ネット経由でストリーミング受信した音声ファイル(rtmpdumpでflvを生成)を、(2)ffmpegでm4aに変換し、(3)さらに1.45倍速にしたものもm4aにする自動処理を行っていました。これは、Raspberry PiのLinux上で実施しています。
(Raspberry Piでffmpegを使うには、通常以上の手間が必要になるのですが、それについてはまた今度)

今までは、(1)(2)(3)の処理を逐次行っていたため、処理時間は非常に長かったのですが、

(1)で必要とするCPU利用率は0.2%程度。必要な時間は2時間30分。
(2)で必要とするCPU利用率はほぼ100%。必要な時間は13分。
(3)で必要とするCPU利用率はほぼ100%。必要な時間は13分。

という感じでした。
もし、(1)と並行して、ゆっくりと(2)(3)を行うことができるなら、うしろの26分間をほぼゼロに近づけることができるんじゃないか?と思いまして。

試しに、(1)と(2)を並行で実施することにしてみました。
rtmpdumpは、出力ファイル名を指定しなければ(-o ファイル名 を付けない)、ファイルの内容は標準出力に出力されます。
ffmpeg は -i pipe 0 というオプションを付けると、標準入力から入力を受け付けます。
指定するコマンドはこんな感じ。

$ rtmpdump (様々なオプション) | ffmpeg -i pipe 0 -ab 64k 出力ファイル名.m4a

参考サイト:rtmpdumpとffmpegをつかったライブトランスコーディング - 別館 子子子子子子(ねこのここねこ)

さて、(1)(2)に加え、(3)も並行で実行するにはどうしたらよいか?
パイプを2分岐させれば良いことになります。

rtmpdump→標準出力→標準入力→tee→→→ ファイル 
    └→→標準出力→標準入力→ffmpeg

パイプの2分岐は、teeコマンドを用います。
teeコマンドは、標準入力を、「ファイル」と「標準出力」に2分岐させるためのコマンドです。

このうち「標準出力」は、別のコマンド(今回の場合はffmpeg)の入力にすることができますが、「ファイル」を別のコマンドへの入力にするにはどうしたらよいか?

色々調べたところ、名前付きパイプを使えば良いことが分かりました。
名前付きパイプは、ファイル名を媒介にして、2つのプロセス同士の標準出力と標準入力を繋ぐための方法です。

名前付きパイプはmkfifoコマンドで、あたかもファイルのように作成できます。
以後、そのファイル名へ書き込みをすれば、別のプロセスへの標準入力になるというわけです。
(なお、1つの標準出力を2つのプロセスの標準入力に割り当てることはできません。手元の環境で実験したところ、後から名前付きパイプをオープンしたプロセスに対してのみ、入力が行われました)

mkfifo temp_pipe
ffmpeg -i pipe:0 -ab 64k -af atempo=1.45 出力ファイル名_x145.m4a < temp_pipe &
rtmpdump (様々なオプション) | tee temp_pipe | ffmpeg -i pipe 0 -ab 64k 出力ファイル名.m4a
rm temp_pipe

2行目の最後に & を付けないと、パイプからの入力待ちでブロックされてしまいます。以後のコマンドと並列処理をさせるために & を付けています。

で、これで実行してみると、なんだか上手くいきません。
音楽再生プレイヤーで開くと、「出力ファイル名_x145.m4a」の内容が不正という扱いになります。

色々見直してみましたが、何がおかしいのかよく分からない…。
うーん、名前付きパイプからの入力を、ffmpeg が受け付けられないとか?そんなことはないよなぁ…。

ここで悩むこと5時間。

 :
 :
 :
 :



続きを読む
posted by ayacy at 00:00 | Comment(0) | TrackBack(0) | PC

2017年12月11日

忘年会シーズンになったので一応注意喚起。カバン盗難に注意

11月7日の当ブログでも書きましたけど、京浜東北線の車内でカバンを持ち去られそうになったことがありました。

途中駅に着いた途端に、隣に座っていた20代前半くらいの男性が、平然と、持ち手の部分を掴んで、持っていこうとされまして。
たぶん、僕が寝ていると勘違いしたんでしょう。肩掛け紐が首の後ろに回っていたのも気づかなかったんでしょう。オマヌケなドロボーさんです。

まぁ、アルコールは入っていたので、外から見たらデロンデロンに酔って寝ているように見えたのかも知れません。
が、意識はハッキリしており、目が合ったので、「オイ!」と声をかけたところ、そのまま華麗な動作で開いているドアから出て行きました。

盗むにしても逃げるにしても、ドアが開いている方が都合が良いから、途中駅に着いたところで盗もうとするんでしょうかね。
幸いにも未遂に終わりましたが、僕が本当にグッスリ寝ていて、肩掛け紐を首の後ろに回すのを忘れていたら、そのまま盗まれていたのかも知れません。

これから忘年会シーズン。アルコールが入って、電車の中を朦朧と過ごす日も多くなるかと思います。
となると、カバンの置き引きを狙うドロボーも増えてくるはず。より一層、気を引き締めて行かなければなりません。
電車の中で寝ることに抗うのは大変かもしれませんので、肩掛け紐で確実に体に固定できるようにしておくことは必須です。


posted by ayacy at 00:00 | Comment(0) | TrackBack(0) | 日記

2017年12月10日

改めて2038年問題を考える…すでに2004年に問題が発生していたとは知らなかった

昨日、TL上で2038年問題に関する話題が上がっていて、そういえば、2038年問題って、実際に発生するXデーがいつなのかよく分かっていなかったことに気づきました。

2000年問題なら、2000/1/1 0:00:00 という、一般人でも分かりやすい日付時刻に発生する事象でしたが、2038年問題はそんなに分かりやすい日付時刻ではないはず。C言語を扱うプログラマ以外の一般の人にとっても、わかりにくい事象となるでしょう。

2038年問題とは、C/C++のtime_t型が1970年1月1日0時0分0秒からの積算秒数と定義されており、その最大値の一般的な実装が2,147,483,648となっていることから、その最大値を超えたときに不具合が発生するというものです。

というわけで、Xデーは、世界協定時で2038年1月19日03時14分7秒(UTC)となります。
日本時間だと、2038年1月19日12時14分7秒(JST)になるので、もしトラブルが発生するとしたら真っ昼間です。大混乱になるかもしれません。

2000年問題の時と同様に、全世界のSEが血眼になって、問題が発生しないよう努力するはずなので、きっと何も起きないはず…であることを祈りたいです。

この問題をWikipediaで調べていて知ったのですが、2004年には既に、2038年問題を原因とするトラブルが発生していたんだそうでビックリです。


続きを読む
posted by ayacy at 00:24 | Comment(0) | TrackBack(0) | C/C++