質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

917閲覧

canvasで、動画から毎秒15フレーム切り出したい

takushikai

総合スコア12

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2021/12/03 12:46

canvasに動画を表示し、毎秒15フレームのデータを切り出したいです。

video elementのcurrentTimeに時間を代入->描画->データ取得

という流れでコードを書きました。以下のコードは一応動作するのですが、下から7行目で1ミリ秒待っています。
この部分が無いとcanvasに描画されないのですが、ここで待たなければいけない理由がわかりません。ctx.drawImage()は、非同期実行なのでしょうか。そうだとすれば、どのようなイベントで描画が完了したことがわかりますでしょうか。

JavaScript

1const width = 800; 2const height = 600; 3 4const canvas = document.getElementsByTagName("canvas")[0]; 5const ctx = canvas.getContext("2d"); 6canvas.setAttribute("width", width); 7canvas.setAttribute("height", height); 8 9const videoElement = document.createElement("video"); 10videoElement.src = "../video.mp4"; 11 12 13const awaitForTimeupdate = (target) => { 14 return new Promise(resolve => { 15 const listener = resolve; 16 target.addEventListener("timeupdate", listener); 17 }); 18}; 19 20 21async function wait(millisec) { 22 await new Promise(resolve => setTimeout(resolve, millisec)); 23} 24 25// 毎秒15フレーム 26const FPS = 15; 27const Frames = 100;//100フレーム取る 28let nowTime = 0; 29 30 31async function start(){ 32 33 for (let i = 0; i < Frames; i++) { 34 await drawFrame(); 35      //取得したデータ 36 console.log(ctx.getImageData(0, 0, canvas.width, canvas.height).data); 37 38 //nowTimeのアップデート 39 nowTime = (i / FPS)*1000;//[ms] 40 } 41 42 43 async function drawFrame(){ 44 ctx.clearRect(0,0,canvas.width,canvas.height); 45 46 //currentTimeに代入 47 videoElement.currentTime = nowTime/1000; 48 49 await awaitForTimeupdate(videoElement); 50 51 ctx.drawImage(videoElement, 0,0,canvas.width,canvas.height); 52 53 //ここです 54 await wait(1); 55 } 56} 57 58document.querySelector("#start").addEventListener("click",()=>{ 59 start(); 60}); 61

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

MDNに書いてある以下の注意点に引っかかっているのではないでしょうか。

drawImage() only works correctly on an HTMLVideoElement when its HTMLMediaElement.readyState is greater than 1 (i.e., seek event fired after setting the currentTime property).

投稿2021/12/03 14:55

int32_t

総合スコア21020

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takushikai

2021/12/04 03:18

回答ありがとうございます。ご指摘にあったreadyStateを確認したところ、drawImageの直前の時点でreadyStateは3や4といった値になっているので1より大きいです。また、イベントリスナーの部分のtimeupdateをseekedに変えましたが、表示されないのは変わりませんでした。 ほかの原因は考えられますでしょうか。
takushikai

2021/12/04 03:29

【追記】 canvasに表示はされていませんが、データは取得できておりましたので解決とさせていただきます。 int32_t様 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問