ファイルのアップロード 3 | ストックオーディオコンバーター

MIMEタイプ

PHPでファイルのMIMEタイプを取得するには、

$mime = mime_content_type($file['tmp_name'][0]);

形式はtype/subtypeです。例えばmp3の場合、代表的なMIMEタイプはaudio/mpegですが、独自拡張のaudio/mp3audio/x-mpeg等を含めるために、これらのmpegやmp3を$subtypeと置くと、

$bool = preg_match('/^audio.*'.$subtype.'$/',$mime);

この関数は第1引数で指定したパターンが第2引数に含まれているかどうかを真偽で返します。第1引数の/で囲まれる文字列には正規表現を指定します。^は文頭を、$は文末を、.は任意の文字を、*は直前の文字の0個以上の繰り返しを意味します。この.*の指定によって、x-という接頭辞の有無によらず判定をしています。

Application/octet-stream

このmp3に関してなのですが、正確な判別がされずに、未知のMIMEタイプとしてapplication/octet-streamを返すことがありました。PHPの関数だけでなくLinuxのコマンドであるfileで調べても同様だったので、Super Userを参考にして、/etc/magicのファイルに以下の一文を追加しました。

# MPEG Layer 3 sound files
0       beshort     &0xffe0     audio/mpeg
!:mime  audio/mpeg
#MP3 with ID3 tag
0       string      ID3     audio/mpeg
!:mime  audio/mpeg

これにより、Linuxのコマンドfileを用いると

file -bi town.mp3

オプションについて、bはファイル名の出力を省略し、iはMIMEタイプ形式で出力します。この結果は以下のようになります。

$ file -bi town.mp3
audio/mpeg; charset=binary

この出力を取得するために、上記のコマンドを$commandと置き、PHPのexec()を用いると、

exec($command.' </dev/null 2>&1',$contentAry,$error);

2>&1の指定によって、標準エラー出力は標準出力と同じ出力にリダイレクトされ、その結果は$contentAryに格納されます。第3引数の$errorには、コマンド成功時には0が、失敗時には1が入ります。
次に、この出力から特定の文字列を抜き出します。

preg_match('/^(.*); charset/',$contentAry[0],$mimeAry);

第1引数のパターン内に()を指定して、パターンが第2引数にマッチした際に、その括弧の中の文字列を、第3引数である$mimeAryに渡します。この第3引数は配列形式で、$mimeAry[0]にはマッチしたパターン全体が、$mimeAry[1]には括弧で指定した文字列が格納されるので、

$mime = $mimeAry[1];

として、目的の文字列audio/mpegを取り出します。

以上が、今のサイトの仕様なのですが、音楽素材として配布されている中には、m4aであればMIMEタイプがvideo/mp4といったものもあります。上記の方法よりも、FFmpegにおいてファイルを解析する機能であるFFprobeを使って調べるなど、他の方法を検討する余地があります。

URL: sac.ringil-music.com
環境: さくらのVPS・Centos7・Nginx・PHP-FPM

コメントを残す

メールアドレスが公開されることはありません。