スマホで撮った動画をメールに添付しようとして、上限を超えて送れない。必要な部分だけを切り出し、解像度や画質を落として作り直せば送れる。動画の切り出し・圧縮 は、この作業をするツールである。動画はサーバーに送らず、ブラウザの中で変換する。
動画を小さくするには、圧縮された映像をいったん 1 枚ずつの画像にほどき(復号)、少ないデータ量で圧縮し直す(符号化)必要がある。ブラウザでこれをやるなら、動画変換の定番である FFmpeg を WebAssembly にしたもの(ffmpeg.wasm など)を持ち込む方法がある。このツールはそうせず、ブラウザに組み込まれたエンコーダを WebCodecs という API で呼び出している。自前で持ち込まないぶん、使えるものはブラウザに左右される。
WebCodecs は、何をしてくれる API か
WebCodecs は、映像と音声の符号化と復号を、フレーム単位の細かさで Web ページから扱うための
API である(MDN の解説)。映像のエンコーダとデコーダ(VideoEncoder、VideoDecoder)、音声のエンコーダとデコーダ(AudioEncoder、AudioDecoder)の
4 つが中心になる。
ただし WebCodecs が扱うのは、符号化と復号だけである。MP4 や WebM のファイルから映像のデータを取り出すことも、符号化したデータを再生できるファイルにまとめることもしない。動画ファイルは、映像と音声のデータを時刻の情報と一緒に詰めた入れ物(コンテナ)で、その読み書きは別に用意しなければならない。MDN もその用途のライブラリとして挙げている Mediabunny(MPL-2.0)を、このツールは MP4、MOV、WebM の読み込みと、MP4 と WebM への書き出しに使っている。切り出し、解像度の変更、エンコーダの設定も Mediabunny を通して行う。
どのブラウザで使えるのか
4 つの API がそろった時期は、ブラウザによって違う。MDN の browser-compat-data(2026年9月17日時点の 8.1.2)では、次のとおりである。
- Chrome と Edge: 94 から 4 つともある(パソコン、Android)
- Firefox: パソコン版は 130 から 4 つともある。Android 版にはない
-
Safari: 16.4 で
VideoEncoderとVideoDecoderが入り、26 でAudioEncoderとAudioDecoderが加わった(Mac、iPhone、iPad)
出典は MDN の VideoEncoder と AudioEncoder の互換性表である。Can I use も Safari 16.4〜18 を部分対応、26 からを対応としている。Safari 26 で音声のエンコーダが加わったことは、WebKit のリリースノート(WebKit Features in Safari 26.0)にも書かれている。
したがって Safari 16.4〜18 では、映像は変換できても音声は作れない。この環境では音声ありの形式を選べなくし、その理由と、音声を「なし」にすれば映像だけで書き出せることを画面に出す。
API があっても、エンコーダがあるとは限らない
VideoEncoder
があることは、H.264
のエンコーダがあることを意味しない。どのコーデック(圧縮の方式)を符号化できるかは、ブラウザ、OS、端末ごとに違う。そこでツールは、ページを開くたびに
VideoEncoder.isConfigSupported() と
AudioEncoder.isConfigSupported()
で、H.264、VP9、VP8 の映像と、AAC、Opus
の音声を符号化できるかをブラウザに問い合わせる。対応表を自分では持たない。
いちばん差が出るのが、MP4 の音声に使う AAC である。MDN のコーデックの選び方の解説は、WebCodecs の AAC の符号化は、どのプラットフォームの Firefox でも、パソコンの Linux ではどのブラウザでも使えない、と書いている。
書き出す形式は二つ用意し、問い合わせの結果から選べるかを決める。
- MP4(H.264 + AAC): H.264 と AAC がそろえば選べる。音声を「なし」にするなら H.264 だけでよい
- WebM(VP9 か VP8 + Opus): VP9 か VP8 と、Opus がそろえば選べる
選べない形式には、足りないエンコーダの名前を添える。両方選べるときは、MP4 を選んだ状態から始める。MP4 の中に Opus の音声を入れる組み合わせも、仕組みの上では作れる。それを選ばなかったのは、再生できない端末が多いと判断したからである。WebM にも、iPhone の写真アプリなど再生できない環境があるので、WebM を選ぶと画面にそう添える。
Linux のブラウザで AAC が使えないことは、開発者の側では実機で確かめていない。MDN の記述を根拠にしているが、ツール自体は上の問い合わせで判断するので、仮に AAC が使える環境があれば、音声ありの MP4 を選べる。
読み込む側にも、環境の差がある。iPhone の動画は HEVC(H.265)で記録されていることが多く、HEVC を復号できるかはブラウザと端末によって違う。ツールは読み込んだ時点で復号できるかを確かめ、できなければ理由を示し、iPhone のカメラの設定を「互換性優先」にすると H.264 で記録されることを案内して止まる。
出力サイズの目安は、どう計算するのか
ファイルの大きさは、おおよそ「1 秒あたりのデータ量(ビットレート)× 長さ」で決まる。以前のツールは、この式を逆向きに使っていた。送り先の上限と切り出した長さからビットレートを逆算し、解像度やフレームレートまで自動で決める。送り先に収めるだけなら、利用者の手間は少ない。
ところが、解像度やフレームレートは自分で決めたいという要望があった。自動で決めた音声のビットレートが、音声を消す原因にもなっていた。いまは式を順向きに使い、利用者が選んだ設定からビットレートを決めて、大きさの目安を出す。
- 解像度は、元のまま、長辺 1920・1280・854・640 ピクセル、幅の指定から選ぶ。高さは縦横比から決め、幅と高さを偶数に丸める。H.264 などで一般的な色の間引き方(4:2:0)が、縦横とも偶数の大きさを前提にしているからである。元の動画より大きくはしない。
- フレームレートは、元のまま、60・30・24・15 fps、数値の指定から選ぶ。元より上げはしない。
- 映像のビットレートは、kbps で直接指定するか、画質を「高・中・低」から選ぶ。画質で選んだときは、幅 × 高さ × フレームレートに、1 画素・1 フレームあたりのビット数を掛ける。H.264 では高 0.15、中 0.10、低 0.06 とし、同じ見た目を少ないデータで作れる VP9 では 0.11、0.07、0.045 にしている。
- 音声は、192・128・96・64 kbps か、なしから選ぶ。
- 目安は、映像と音声のビットレートの合計に長さを掛けて 8 で割り、ファイルの管理情報のぶん(64 KB と、1 秒あたり 2.5 KB)を足した値である。
たとえば 1920 × 1080 ピクセル、30 fps の動画を 1280 × 720 に縮め、画質「中」、音声 128 kbps で 30 秒を切り出すと、映像は約 2.76 Mbps、目安は約 11.0 MB になる。854 × 480、画質「低」、音声 96 kbps にすると、60 秒を切り出しても目安は約 6.5 MB である。どちらもツールの計算部分に同じ条件を与えて出した値である。
送り先の上限とは、比べるだけにした。設定を選ぶたびに、目安がメール(上限 10 MB)、Gmail(25 MB)、Microsoft Teams(100 MB)に収まるかを表示し、設定そのものは変えない。メールでは、上限そのものとは比べない。添付ファイルは送信時に Base64 という文字の並びに変換され、3 バイトが 4 文字になり、76 文字ごとに改行が入る(RFC 2045 の 6.8 節)ので、約 1.37 倍に膨らむ。メールサーバーの上限はこの膨らんだあとの大きさに掛かることが多いので、上限 10 MB のメールでは 7.2 MB までを「収まる」とみなす。先の例の 6.5 MB はメールに収まり、11.0 MB は Gmail(18.2 MB まで)にだけ収まる。
H.264 はレベルという区分ごとに扱える画面の大きさに上限があるので、変換の直前に、選んだ解像度とビットレートでもう一度エンコーダに問い合わせる。
Windows の Chrome で、音声だけが消えていた
目標サイズから逆算していたころ、利用者から報告があった。長さ 35 分、2150 MB、1920 × 1080 の H.264 と AAC の動画を Windows の Chrome で変換すると、書き出した動画から音が消える。同じ環境で短く切り出したときは、音声が残った。
長い動画でだけ起きるので、長時間の処理のどこかで音声のデータが途切れたように見える。ところが、手がかりは処理の長さではなく、ビットレートの計算の分岐にあった。
以前の逆算は、全体のビットレートが 600 kbps を下回ると、音声を 64 kbps にしていた。35 分の動画でこの分岐を避けるには、目標を約 180 MB 以上にしなければならない。たとえば Teams の 100 MB を選ぶと、全体は約 320 kbps で、音声は 64 kbps になる。報告にあった短い切り出し(1 分 35 秒、854 × 480)は、25 MB 前後の目標を選んだときの計算と合い、このとき音声は 96 kbps 以上になる。
一方、Windows の Chrome と Edge は、AAC の符号化を 96・128・160・192 kbps
でしか受け付けない。Chromium のソース(audio_encoder.cc)では、Windows でこの四つ以外のビットレートを指定すると、AudioEncoder.isConfigSupported()
が非対応と答える。Mac では、エンコーダが扱える近いビットレートに下げて符号化する。
64 kbps の AAC を作れないと分かると、Mediabunny は音声のトラックを出力から外し、外した理由を記録する。ただし映像のトラックが残っていれば、変換そのものは有効とみなして進む。ツールはその記録を見ていなかったので、音のない動画が何の知らせもなく書き出された。
報告者が選んだ目標サイズは分かっていないので、報告者の環境でこの経路を再現したわけではない。確かめられたのは、報告された条件がこの分岐と矛盾しないところまでである。開発環境では、Windows
の Chrome と同じ答えを返す偽の AudioEncoder を置き、64 kbps を指定すると
Mediabunny が音声を外したまま変換を有効とみなすことを、テストで確かめた。
いまのツールは、音声のビットレートごとにエンコーダへ問い合わせ、受け付けない値を選べなくしている。それでも音声が外されたら、変換を始める前に止めて理由を示す。書き出したあとは、ファイルを開き直して音声のトラックがあるかを表示する。
固定ビットレートを指定しても、目安を超えることがある
ビットレートの指定は、エンコーダへの目安である。目安と実際の大きさが離れないよう、場面ごとに配分を変えるより平均を守ってほしいので、ツールは固定ビットレートを指定している。それでも、指定どおりの大きさになるとは限らなかった。
開発中、Linux のヘッドレス Chromium(画面を出さずに動かす Chromium。H.264 の符号化には OpenH264 が使われる)で、時間方向のノイズを強く載せた 1080 × 1920 の映像に 3.9 Mbps を指定したところ、出力は 6.7 Mbps になった。ノイズの多い映像は圧縮しにくく、エンコーダが指定を下回れなかったと考えられる。同じ素材でも 720 × 1280 に落とすと、当時の目標サイズに収まった。
画素数に対して低いビットレートを選ぶほど、このずれは起きやすいと考えられる。そのため、書き出したファイルは開き直して大きさと長さ、トラックを確かめ、実際の大きさが目安から何 % ずれたかを表示する。作り直すかどうかは、その差を見て利用者が決める。
書き出す動画に残るもの、確かめていないこと
書き出す動画には、元の動画の撮影日時や撮影場所などのメタデータを引き継がない。ffmpeg でタイトル、位置情報、作成日時を入れた MP4 を変換し、出力に残るのが作成日時(変換した時刻)だけであることを ffprobe で確かめた。
読み込んだ動画は、必要な部分だけをファイルから読む。困るのは書き出す側である。報告のあった 35 分の動画を 1280 × 720、画質「低」、音声 96 kbps で書き出すと、目安は約 467 MB になる。書き出す動画をすべてメモリに溜めてからダウンロードさせる方式では、少なくとも出力と同じ大きさのメモリが要り、メモリの少ない端末では途中で止まるおそれがある。
そこでパソコンの Chrome と Edge では、File System Access API の
showSaveFilePicker() で保存先を先に選んでもらい、Mediabunny の
StreamTarget
で変換しながらファイルに書き込む。メモリに溜まるのは、書き込み待ちの数十 MB
ほどで済む。目安が 200 MB 以上なら、この方式を選んだ状態から始める。Safari や Firefox
のように showSaveFilePicker() が無いブラウザではメモリに作るしかなく、目安が
500 MB 以上なら、途中で止まるおそれがあると画面に出す。
確かめていないこともある。iPhone の実機での変換は、まだ確認していない。Safari 26 の対応は、ここまでに挙げた資料に基づく。Linux で AAC が使えないことと、Windows の Chrome が受け付ける AAC のビットレートも、資料と Chromium のソースに基づくもので、開発者の側では実機で試していない。ファイルへの直接の書き込みは、ヘッドレス Chromium で、保存先を選ぶ画面の代わりにブラウザ内の保存領域(OPFS)のファイルを渡して確かめた。
FFmpeg を持ち込まなかったぶん、ブラウザに無いエンコーダは使えず、ブラウザのエンコーダが受け付けない設定も使えない。受け付けるかどうかは、音声のビットレート一つまで、問い合わせてみるまで分からない。その代わり、ツールが配るのはページと Mediabunny を含む JavaScript で、符号化と復号そのものはブラウザが持つエンコーダとデコーダが行う。どの形式とビットレートを選べるかは、ページを開いた環境で問い合わせた結果として、画面に出る。