質問: はじめまして phpで複数のmp3を結合して1つのファイルにし、再生したいと考えてます。 ``` "; shell_exec($cmd ,$mp9,$rtn); ?> ``` すると9.mp3のみの音が流れてしまい、結合ができていません。 1.catの結合の仕方が間違っていないか? 2.結合したmp3はどこに格納されているのか?ルート、mp3フォルダ下? 3.この結合したmp3ファイルはデータとして保存できるか? よろしくお願いいたします。
回答: * mp3 の仕様上、`cat` で結合して出来た mp3 ファイルを再生できるソフトウェアは存在します。ただし「再エンコーディングはされない」「曲のタイトルなどタグの情報は整合性が取れなくなってしまう」という 2 つのデメリットがあるので、きちんと結合したいのであれば mp3 結合用の別ソフトウェアを使う方が良いです。 + より詳しく説明すると、mp3 のファイルフォーマットは `[タグ用ファイルヘッダー] -- [音声データ] -- [タグ用ファイルフッター]` の形式で、更に音楽データは `[フレームヘッダー] -- [音声バイト列]` の形のフレームが並んでいる形式になっています。したがって単にバイト列を `cat` するだけでもフレームの並びの中にタグが細切れで入るだけで、mp3 ファイルとして無理矢理読み込もうとすれば読めてしまいます。しかし細切れになったタグ情報は普通失われてしまいます。 - 逆に言うと、元のファイルたちにタグがついていないなら `cat` で正常に結合できます。 + mp3 を正確に結合できるソフトウェアについては (英語ですが) 以下の Q&A が参考になります。 - What is the best way to merge mp3 files? - Merging MP3 files in Linux Debian using PHP * `shell_exec()` 関数は引数を 1 つしか受け取りません。今のソースコードだと 3 つになっているので、何かがおかしいです。`exec()` 関数と間違っていませんか? * `cat ../mp3/1.mp3 ../mp3/2.mp3 > ../mp3/9.mp3` というコマンドを実行したのであれば、結合結果は `../mp3/9.mp3` というファイルに保存されています。 * そもそもの問題として、シェルコマンドに変数の中身をそのまま渡すのはセキュリティ的に危ない場合があります。質問文中のソースコードではファイル名が固定になっていますが、もしこれが動的に変わりうるなら(特に、任意の入力文字列が代入されうるなら)、どういう実装にするのか慎重になるべきです。