動画から1コマ取り出す
動画をえらぶえらんだ動画は、あなたのブラウザの中だけで開きます。どこかへ送ることはありません
受け取れるのは200MBまでです(このサイトが自分で決めた上限です)。
えらんだ動画はこの画面の外へ出ていきません。 コマを探すのも、絵にして書き出すのも、全部あなたのブラウザの中でやっています。 ネットにつながっていなくても、いちど開いたあとなら動きます。
よくある質問
取り出した絵がぼやけたり、思っていたのと違うコマが出るのはなぜですか?
動画は、すべてのコマが1枚の絵として入っているわけではありません。ときどき入っている「まるごとの絵」(キーフレーム)と、その間の「前のコマとの違いだけを書いたコマ」でできています。だから途中の1コマを見るには、近くのまるごとの絵まで戻って、間のコマを順に組み立て直す必要があります。組み立てが終わる前に写すと、1つ前のコマが出ます。この道具は、ブラウザが「その時刻の準備ができた」と知らせてくる seeked という合図を待ってから写しています。
1秒あたりのコマ数が「測れませんでした」と出ます。なぜ数字を書いてくれないのですか?
コマ数はファイルの中に書いてありますが、ブラウザはそれを読む窓口を用意していません。この道具は、動画を1秒くらいだけ音を消して流し、出てきたコマの枚数と進んだ時刻から割り算して測っています。その仕組み(requestVideoFrameCallback)が無いブラウザや、流すのをブラウザに止められたときは測れません。そのときに「たぶん30コマ」と書くと、画面の数字と実際の絵が食い違ってしまうので、書かないことにしています。
動画はどこかに送られますか?
送られません。えらんだ動画はあなたのブラウザの中だけで開いていて、通信は1回も起きません。いちどページを開いたあとは、ネットにつながっていなくても動きます。取り出した絵も、保存ボタンを押すまではブラウザの中にあるだけです。
動画の長さより後ろの時刻を入れたら、終わりの1コマを出してくれませんか?
出しません。かわりに「この動画は何秒で終わります」と理由を出して止めます。黙って終わりに寄せると、画面に出ている時刻と、実際に見ている絵が別のものになります。打ち間違いに気づけなくなるほうが困るので、この道具は範囲の外を静かに切り捨てません。
iPhone で動画が勝手に全画面になったり、読み込まれなかったりするのはなぜですか?
iPhone の Safari には、動画の再生のしかたに決まりがあります。WebKit の資料は「playsinline が付いた video は画面の中で再生してよく、再生のときに全画面へ切り替わらない」「playsinline が無い video は、iPhone では全画面でしか再生できない」と書いています。また「音のトラックが無いか、muted が true なら、利用者の操作なしに再生してよい」とも決まっています。このページの video には playsinline と muted の両方を付けてあります。
よそのサイトにある動画の URL を貼って取り出せますか?
できません。別のサイトから来た動画を描き込んだ画板(canvas)は「汚れた」状態になり、中身を画像として読み出そうとすると SecurityError で断られる決まりだからです。HTML の仕様が、そうしないと他のサイトの中身を勝手に覗けてしまうため、そう定めています。このページは自分の端末のファイルをえらぶ形なので、この問題は起きません。
大きい動画を入れると、押しても何も起きません。
この道具が受け取るのは200MBまでにしてあります(このサイトが自分で決めた上限です)。上限の中でも、長い動画の終わりのほうを指すと、そこまで読み進むのに時間がかかります。20秒待っても届かなければ「届きませんでした」と理由を出して止めるので、押しても何も起きないまま終わることはありません。
動画の好きな瞬間を静止画にして保存します。1秒あたりのコマ数を測って出すので、時刻を1コマぶんずつ動かせます。動画はブラウザの中だけで開きます。
動画は「パラパラ漫画」です。1コマずつずらすと、それが見えます
動画は、少しずつちがう絵を、すごい速さで順番に見せているだけのものです。 ノートのはしに描くパラパラ漫画とまったく同じ仕組みで、 1枚1枚の絵のことをコマ(フレーム)といいます。
上の道具で「1コマ ▶」を押してから取り出すと、となりあった2つのコマが並んで出ます。 手が少しだけ動いている、目が半分 閉じかけている ── そういう1コマぶんのちがいが見えたら、 動画がパラパラ漫画であることを自分の目で確かめたことになります。
1秒に何枚めくっているかが1秒あたりのコマ数です。 この道具は、その数をファイルから読むのではなく、実際に少し流して数えています。ブラウザには「この動画は1秒に何コマか」を直接教えてくれる窓口が無いからです。 かわりに、コマが1枚出るたびにそのコマの時刻とこれまでに出した枚数を知らせてくれる仕組みがあるので、 「増えた枚数 ÷ 進んだ時刻」で割り算しています。 数えられなかったときは「測れませんでした」とだけ出します。 それらしい数を書くと、画面の数字と実際の絵が食い違うからです。
じつは、全部のコマが「絵」として入っているわけではありません
ここが面白いところです。動画のファイルの中には、ときどき「まるごとの絵」が入っているだけで、 その間のコマは「前のコマとの、ちがうところ」しか書かれていません。 空が青いままなら、青いという情報を毎回書かずに済むからです。 だから動画は、同じ長さの写真の束よりずっと小さくなります。
そのかわり、途中の1コマだけを見るのが大変になります。 近くの「まるごとの絵」まで戻って、そこから間のコマを順に組み立てては捨てて、やっと目当てのコマにたどり着くからです。
これは想像ではありません。ブラウザの決まりを書いた HTML の仕様書に、 時刻を動かすときの説明として「近くのキーフレームに寄せてもよい。そうすれば、再生を再開する前に 間のコマを復号しては捨てる時間を使わずに済むからだ」と、そのまま書かれています。HTML 仕様 4.8.11.9 Seeking(新しいタブで開きます)にある一文です。
同じところに fastSeek() という命令の説明もあって、「できるだけ速く、指定した時刻の近くへ飛ぶ。正確さと引きかえに速さを取る」「正確な時刻へ動かしたいときは currentTime を使うこと」と書いてあります。この道具は正確なほうを使っています。1コマずつ確かめるのが目的なのに、近くのコマで済まされては困るからです。
時刻を変えた「直後」に写すと、1つ前のコマが写ります
これは、この手の道具を作るときにほぼ必ず踏む落とし穴です。 時刻を変える命令を出しても、その瞬間に絵が入れ替わるわけではありません。 上に書いたとおり、絵を組み立て直すには時間がかかります。
HTML の仕様は、画板(canvas)に動画を写すときの材料について「そのメソッドを呼んだ瞬間の再生位置のコマを使う」と決めています。つまり、まだ絵が入れ替わっていないうちに写しの命令を出すと、前のコマが、何ごともなかったような顔で保存されます。 エラーも警告も出ません。
だからこの道具は、ブラウザが「その時刻の準備ができました」と知らせるseeked という合図を待ってから写しています。 仕様の手順にも、「その位置のデータがあるかどうかが分かって、あれば再生できるだけ復号し終わるまで待つ」→その後で seeked を出す、と順番が書かれています。
もうひとつ、この道具が待つのをやめる場合があります。すでにその時刻にいるときです。時刻が動かなければseeked は飛んで来ないので、待ち続けると永久に終わらない画面になります。 それも「押しても何も起きない」の 一種なので、そこだけは待たずに写します。
iPhone が動画を画面の中で再生するには、条件があります
同じ HTML を書いても、iPhone の Safari だけは動きが違います。 WebKit(Safari の中身)の資料に、こう書かれています。
- 「iPhone では、
playsinlineが付いた video は 画面の中で再生できるようになり、再生が始まるときに自動で全画面へ移らない」 - 「
playsinlineが無い video は、iPhone では 引き続き全画面でしか再生できない」 - 「音のトラックが入っていないか、
mutedが true なら、 利用者の操作なしにplay()してよい」
このページの動画にはその2つを両方付けてあります。muted は「いきなり音が鳴ってびっくりしない」ためでもあり、コマ数を測るために少しだけ流すことが許される条件でもあります。 1つのおまじないが2つの役目をしているので、外すと2か所が同時に壊れます。
読み込みについても決まりがあります。Apple の資料は「Safari は preload="metadata" を尊重し、 その動画の大きさ・長さ・入っているトラックが分かるだけのデータを読み込む」と書いています。この道具が、動画を最後まで読まないうちに 「長さ」と「絵の大きさ」を出せるのはこのためです。
よそのサイトの動画は取り出せません。画板が「汚れる」からです
別のサイトにある動画を画板(canvas)に描くと、その画板は「汚れた」状態になります。HTML の仕様は、 よそから来た絵を描いた画板のorigin-clean という印を false にすると決め、 その画板から中身を取り出す命令(toBlob や toDataURL)にはSecurityError で断らせると定めています。
意地悪をしているのではありません。これが無いと、ログインした状態でしか見えないはずの絵を、別のサイトが勝手に読み取れてしまうからです。 このページは自分の端末のファイルをえらぶ形なので、 ここには引っかかりません。 それでも、断られたときの言い分けは用意してあります。黙って何も起きないページが、いちばんわるいからです。
「時刻を打つ欄」を必ず置いている理由
時刻の指定をつまみ(スライダー)だけにしている道具をよく見かけますが、つまみを正確に動かせない人がいます。 アクセシビリティの決まり(WCAG 2.2 の SC 2.5.7 ドラッグ動作)は、ドラッグでする操作には、ドラッグしなくてもできる道を用意することを求めています。
だからこの道具では、数字を直接打てる欄と、1コマぶんだけ動かすボタンを置いてあります。 そもそも「1コマだけずらす」という操作は、つまみでは狙えません ── 1コマは、30コマの動画なら0.03秒しかないからです。
コマを指すときは、そのコマの真ん中の時刻を指しています。 境目ぴったりを指すと、小数のわずかな丸めで1つ手前のコマに落ちてしまうことがあるためです。 真ん中なら、 前後どちらへ丸められても同じコマに乗ります。
出どころ: WebKit「New <video> Policies for iOS」(2016年7月25日)(新しいタブで開きます)と Apple「Delivering Video Content for Safari」(新しいタブで開きます)(playsinline・muted・preload の決まり)、WHATWG HTML 仕様 4.8.11.9 Seeking(新しいタブで開きます)(seeked を出すまでの手順と fastSeek())、同 4.12.5 Canvas(新しいタブで開きます)(写す材料は「呼んだ瞬間の再生位置のコマ」・origin-clean と SecurityError)、 コマ数を数える仕組みは WICG「HTMLVideoElement.requestVideoFrameCallback()」(新しいタブで開きます)(mediaTime と presentedFrames の定義)。 受け取れる大きさの上限だけはこのサイトが自分で決めた値で、 出どころのある数ではありません。
音のほうで同じことを試すなら 音の波を見る、 取り出した絵をいじるなら 写真の明るさ調整が同じくブラウザの中だけで動きます。