ドラッグ&ドロップで動画を読み込み、Web Audio API と Canvas で加工しながら再生する
ちょっとやろうと思ったことがあって、確認と練習がてら色々試したら表題にあるとおりの動画プレイヤーができたので、どんな感じでやるのかを簡単に書きます。
こういう感じのものが出来ます。
Glitched Movie Player
1. ドラッグ&ドロップで動画を読み込む
$(window).on 'dragover', -> false $(window).on 'drop', (e)-> file = e.originalEvent.dataTransfer.files[0] video = document.createElement 'video' $(video).on 'loadeddata', -> video.muted = true video.play() video.type = file.type video.src = URL.createObjectURL file false
video.src には URL.createObjectURL で得たurlを入れてあげます。
音声はWeb Audio API経由で出すので video.muted にしてあげましょう。
videoにどういう要素やイベントがあるのかは以下のページが分かりやすかったです。
11. メディア要素に関連したAPIの一覧 » HTML5 -
2. 動画を加工する
canvas.context.drawImage video, 0, 0, video.videoWidth, video.videoHeight
動画も静止画像と同じように drawImage で貼付けることができます。
キャンバスに貼付けた後は普通のキャンバスの操作と同じ。
getImageData で ImageData を取得して加工した後、putImageData するとか。
Canvasはこのページが分かりやすいと思う。
Canvasリファレンス - HTML5.JP
2.1 任意のポイントの画像を取得する
$(video).on 'seeked', -> canvas.context.drawImage video, 0, 0, video.videoWidth, video.videoHeight video.currentTime = 20.5
video.currentTime で再生位置を秒指定できます。
その位置に移動できたら seeked イベントが来るのでその時に処理しましょう。
ここまでの内容だとこんな感じのものができる。
動画からサムネイルを抽出するやつ
3. 音声を加工する
Web Audio API を使います。
context = new webkitAudioContext media = context.createMediaElementSource video gain = context.createGainNode() gain.gain.value = 0 node = context.createJavaScriptNode(1024, 2, 2) node.onprocess = (e)-> inL = e.inputBuffer.getChannelData 0 inR = e.inputBuffer.getChannelData 1 # 読み込む outL = e.outputBuffer.getChannelData 0 outR = e.outputBuffer.getChannelData 1 # 書き込む gain.connect context.destination node.connect context.destination
経路は以下のようになっています。
MediaSource -> (JavaScriptNode, GainNode)=> context.destination
GainNode は無くても良さそうだけど、そうすると JavaScriptNode への入力が空になる。謎ですね。JavaScriptNodeで加工した音だけを出したいのならば gain.value = 0 にして音を出さないようにします。 あと、再生しながらでないと音の情報は取れないっぽいです。残念ですね。
Web Audio API はここくらいしか見るとこない。
Web Audio API
最初にあげた動画プレイヤーのソースはこんな感じで、 process みたいな箇所を書き換えるとアイデア次第で面白簡単便利動画プレイヤーが比較的楽にできると思います。
https://github.com/mohayonao/the-mohayonao-com/blob/master/static/glitchedmovie/main.coffee