5

キャンバス オーバーレイを含むビデオ要素があります。次に、ビデオの上に描画するための描画ツールのセットアップと、ビデオとキャンバスの両方から drawImage を実行して圧縮されたフレームを保存する保存ボタンがあります。ただし、最初に [保存] を押すと、キャンバスの drawImage からの結果しか得られず、ビデオは表示されません。その後の保存では、両方の画像が適切にレイヤー化されて表示されます。これはビデオ イメージの読み込みに問題があるのではないかと考えましたが、保存する前にビデオが完全に読み込まれ、フレームを進めて 2 回目の保存で適切に動作させることもできます。

これがコードです...

<div style="width:960px; height:540px; display:inline-block;">
    <video id="video" src="media/_tmp/AA_017_COMP_v37.mov" width="960" height="540" ></video>
</div>
<canvas id="canvas" width="960" height="540" style="position:absolute; top:40px; left:9px; z-index:100;"></canvas>
<input type="button" value="save" id="btn" size="30" onclick="save()" style="float:left; padding:4px; margin-right:4px;" >
<div id="saved" style="border:1px solid #000; position:absolute; top:626px; left:10px; bottom:40px; width:958px; overflow:auto;">SAVED:</div>


function save() {

    //COMP CANVAS OVER VIDEOFRAME
    var video = document.getElementById("video");
    var currentFrame = Math.floor((<?php echo $mov_frames ?> / video.duration) * video.currentTime);

    var compCanvas = document.createElement('canvas');
    compCanvas.width = video.width;
    compCanvas.height = video.height;
    compContext = compCanvas.getContext('2d');
    compContext.drawImage(video, 0, 0);
    compContext.drawImage(canvas, 0, 0);
    var dataURL = compCanvas.toDataURL();

    $("#saved").append('<div style="width:954px; border-bottom:1px solid #000; padding:2px 2px 0 2px;"><img id="compFrame_'+currentFrame+'" width="180" height="90" src="'+dataURL+'" />Frame: '+currentFrame+'</div>');
}
4

3 に答える 3

2

これは Safari を搭載した OSX 上にあるため、いくつかの悪いニュースがあります。

注: キャンバス drawImage() メソッドのソースとしてのビデオは、現在 iOS ではサポートされていません。

ソース

これが古い情報であるかどうかはわかりませんが、どちらの場合も現在の実装には問題があります。(コメントで)確立されているように、問題はコーデックに関連しているとは考えられません。これは他のフォーマットでも発生するためです。フィドルtoDataURL()はソースとしてのメソッドを排除するので、残っているのはメソッドですdrawImage()

これは提供されたコードを使用して他のプラットフォームで動作するため、見た目からは、これが問題の原因ではないため、ここでは OSX プラットフォームの Safari ブラウザで発生する可能性が非常に高い問題 (バグ) を調べています。

上記の公式ドキュメントにも、これはサポートされていないと記載されているため、これはおそらくまだいくつかの問題がある非常に初期の実装です。

その点でできることはあまりありませんが、待ってから問題として報告する必要があります (報告された問題を探しましたが、何も見つからなかったので、これを行うことをお勧めします)。

于 2013-11-15T20:00:50.120 に答える
2

私は最近、同じ問題に遭遇し、「実際の」作業を行う前に、ビデオを「ダミー」キャンバスに描画することで回避しました。これは、動画を解析しようとするコード内のすべてのメソッドが、動画で「canplaythrough」イベントがトリガーされるまで待機するため、うまく機能します。「canplaythrough」イベント ハンドラーを Promise でラップし、「canplaythrough」イベントが受信され、ビデオをダミー キャンバスに描画しようとしたときにのみ、Promise を解決します。 これは、Safari のバグに対する効果的な回避策のようです。

例えば:

var readyPromise = new Promise(function(resolve) {
    video.addEventListener("canplaythrough", function() {
        var canvas = document.createElement("canvas"),
            context = canvas.getContext("2d");

        context.drawImage(video, 0, 0);

        resolve(video);
    });
});

readyPromise.then(function() {
    // NOW manipulate the video, draw it onto a canvas, etc
});
于 2014-05-29T04:06:03.163 に答える