webページで扱う動画の沼に嵌った話
あけましてだいぶ経ちましたね。おめでとうございます。PS4を買ってゲーム生活が充実しているyamashitaです。
年末と変わらず、動画についての業務にかかわり気味なので引き続きそんな感じの記事です。
しかし、調べれば調べるほど奥が深くてこのテーマで記事を書こうとしてことを後悔してます。
まずはじめに疑問に思ったので試してみました。
videoタグに対応してない拡張子の動画を使ったらどうなるの?
<video controls width="100">
<source src="/movie/sample.flv">
</video>
なるほど拡張子はmp4に変えないとダメか
<video controls width="100">
<source src="/movie/sample.mp4">
</video>
何故ダメなのか
いやわかってましたよ・・・?世代ですからね。動画は変換しなくちゃいけないんですよね。
でもここで一つの疑問が出てくるのです。不特定多数のユーザーがアップロードした動画をweb上で再生する時にこういう事が起こりえるのではないか?
そんなことを防ぐにはどうしたらいいのだろうか?
コーデック形式で判断する
どうやって判断するかと言えばこいつです。
ffmpeg
動画の事なら大体なんとかなるフリーソフト(らしい)です。
こいつをインストールしておけばコマンド一つで動画情報を取得できます。
例えば
ffmpeg -i sample.flv
// 出力前略 以下末尾
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 98 kb/s
Stream #0:1: Video: vp6f, yuv420p, 1920x1080, 1740 kb/s, 29.97 fps, 29.97 tbr, 1k tbn
"Video:"の横に続くパラメーターの "vp6f"がコーデック形式です。これが何かによって再生可能な動画かどうかがわかります。
他にも
ffprobe -show_streams sample.mp4
とするとこんな感じになります。上の2行の出力を詳しくした感じです。
[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=High
codec_type=video
codec_time_base=31333/1860000
codec_tag_string=avc1
codec_tag=0x31637661
width=1920
height=1080
coded_width=1920
coded_height=1080
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=yuv420p
level=40
color_range=tv
color_space=bt470bg
color_transfer=smpte170m
color_primaries=bt470bg
chroma_location=left
field_order=unknown
timecode=N/A
refs=1
is_avc=true
nal_length_size=4
id=N/A
r_frame_rate=30/1
avg_frame_rate=930000/31333
time_base=1/90000
start_pts=0
start_time=0.000000
duration_ts=281997
duration=3.133300
bit_rate=17609324
max_bit_rate=N/A
bits_per_raw_sample=8
nb_frames=93
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:rotate=90
TAG:creation_time=2017-12-04T09:05:05.000000Z
TAG:language=eng
TAG:handler_name=VideoHandle
[SIDE_DATA]
side_data_type=Display Matrix
displaymatrix=
00000000: 0 65536 0
00000001: -65536 0 0
00000002: 0 0 1073741824
rotation=-90
[/SIDE_DATA]
[/STREAM]
codecnameやcodeclong_nameがコーデック形式に該当するのでそれらを参照します。
これをphpからexec()やsystem()で実行して使えば、拡張子よりは正確に動画を分別できるのではないでしょうか。
動画をコーデック形式で分けた後はどうすれば?
大人しくvideoタグを使用しない別の方法で再生するか、変換しましょう。
ffmpeg -i sample.flv sample.mp4
で変換できます。
拡張子から一番適した形式を判断して出力してくれるようです。
わざわざ変換しないでアップロードさせないとかでもいいのではないかと気づきましたが「そういう事もできるよ」という事で。
以上、軽い気持ちで動画の再生とか形式とか変換とかに手を出したら奥が深すぎた話でした。