出てきたファイルは1,690バイトでした。0バイトではないので、壊れているとは誰も気づきません。
このサイトの動画圧縮を作っているときに見つけた、いちばん厄介な不具合の話です。ブラウザには「この形式で録れますか」と質問できる仕組みがあります。それがすべての組み合わせに対して「録れます」と答えたのに、実際に録ると壊れていた。
実際に測った4通り
| 入れ物 | 音声 | 出てきたもの |
|---|---|---|
| MP4 | なし | 15,947 バイト — 正常 |
| MP4 | あり | 1,690 バイト — 壊れている |
| WebM | なし | 21,896 バイト — 正常 |
| WebM | あり | 26,827 バイト — 正常 |
2行目だけが壊れています。映像に音声を混ぜてMP4にしようとすると、中身のほとんど無いファイルが出てくる。しかも0バイトではなく1,690バイトなので、「空だったら失敗」という判定をすり抜けます。
「WebMを使えばいい」では済まなかった
最初はそう考えました。壊れるのはMP4なのだから、WebMで録ればいい。ですがそれをやると、今度はSafariが動かなくなります。Safariは逆で、MP4は録れてWebMは録れません。片方を直すと片方が壊れる形です。
「Chromeならこれ、Safariならこれ」と機種ごとに書き分ける手もありますが、それは結局こちらの思い込みを埋め込むことになります。まだ存在しないブラウザや、次の版で挙動が変わった場合には対応できません。
聞くのをやめて、測ることにした
いまは、実際に使う経路そのままで600ミリ秒だけ録ってみて、要求した量に見合うデータが返ってきた入れ物を採用しています。質問ではなく実測です。
結果として、Chromeでは細かく指定したMP4が0バイトで落ち、指定を外した素のMP4に落ちて正しく録れました。この順番は、こちらが優先順位の一覧を手で書いていたら絶対に見つかりません。5.0MBのクリップが2.0MBのMP4になり、854×480で5.99秒として正しく再生されました。
ここから引き出せること
道具を作る側の話に見えますが、使う側にも効く教訓が1つあります。「変換できました」と出たファイルは、一度開いて確かめることです。とくに、圧縮率が異様に良いときは疑ってください。10分の動画が数百KBになったら、それは圧縮ではなく中身が消えています。
このサイトの画像・動画の圧縮は、書き出したあとに出来上がったファイルをもう一度読み直して、ちゃんと再生できる中身かを確かめています。上の1,690バイトを一度出してしまったので、その確認を入れました。
この記事で紹介したステム分離は、ブラウザで無料で試せます(登録不要・音源は端末から出ません)。