é³å£°ã¨åç»ã®å å·¥
ã¦ã§ãã®ããã¨ããã¯ãè¤æ°ã®æè¡ãã¾ã¨ãã¦æ°ãããã®ãä½ããã¨ãã§ããç¹ã§ãããã¤ãã£ãã®é³å£°ãåç»ããã©ã¦ã¶ã¼ä¸ã§å©ç¨ã§ããã¨ãããã¨ã¯ããããã®ãã¼ã¿ã¹ããªã¼ã ã <canvas>ãWebGLãWeb Audio API ãå©ç¨ãã¦æä½ãããã¨ã§ãé³å£°ãåç»ã«ç´æ¥å¤æ´ãå ãããã¨ãã§ãããã¨ãæå³ãã¾ããä¾ãã°é³å£°ã«ãªãã¼ããã³ã³ãã¬ãã·ã§ã³å¹æããããããåç»ã«ã°ã¬ã¤ã¹ã±ã¼ã«ãã»ãã¢ã®ãã£ã«ã¿ã¼ããããããããã¨ãã§ãã¾ãããã®è¨äºã§ã¯ãå¿
è¦ãªãã¨ã説æããããã®ãªãã¡ã¬ã³ã¹ãæä¾ãã¾ãã
åç»ã®å å·¥
åç»ã®åãã¬ã¼ã ãããã¯ã»ã«ã®å¤ãèªããã¨ãã§ãããã¨ã¯ãã¨ã¦ãæç¨ã§ãã
åç»ã¨ãã£ã³ãã¹
<canvas> è¦ç´ ã¯ã¦ã§ããã¼ã¸ä¸ã§ã°ã©ãã£ãã¯ãæç»ããããã®å¹³é¢ãæä¾ãã¾ããããã¯å¼·åã§ãåç»ã®å¦çã«ãæç¨ã§ãã
ä¸è¬çãªãã¯ããã¯ã¯æ¬¡ã®ããã«ãªãã¾ãã
<video>è¦ç´ ããã®ãã¬ã¼ã ãä¸éã®<canvas>è¦ç´ ã«æç»ãã¾ãã- ä¸éã®
<canvas>è¦ç´ ãããã¼ã¿ãåå¾ãããããå å·¥ãã¾ãã - å å·¥ãããã¼ã¿ããç»é¢ãã®
<canvas>ãéãã¦æç»ãã¾ãã - 䏿忢ããç¹°ãè¿ãã¾ãã
ä¾ãã°ãåç»ãå¦çãã¦ã°ã¬ã¼ã¹ã±ã¼ã«ã§è¡¨ç¤ºããå ´åãèãã¦ã¿ã¾ãããããã®å ´åãã½ã¼ã¹åç»ã¨åºåã®ã°ã¬ã¼ã¹ã±ã¼ã«ã®ãã¬ã¼ã ã®ä¸¡æ¹ã表示ãã¾ããé常ããåç»ãã°ã¬ã¼ã¹ã±ã¼ã«ã§åçãæ©è½ãå®è£
ããå ´åã display: none ã <video> è¦ç´ ã®ã¹ã¿ã¤ã«ã«è¿½å ãã¦ãã½ã¼ã¹åç»ãç»é¢ã«æç»ãããã夿´ããããã¬ã¼ã ã®ã¿ã表示ããããã£ã³ãã¹ã表示ãããããã«ãã¾ãã
HTML
åç»ãã¬ã¤ã¤ã¼ã¨ã <canvas> è¦ç´ ã¯æ¬¡ã®ããã«è¨è¿°ãã¾ãã
<video
id="my-video"
controls="true"
width="480"
height="270"
crossorigin="anonymous">
<source
src="http://jplayer.org/video/webm/Big_Buck_Bunny_Trailer.webm"
type="video/webm" />
<source
src="http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v"
type="video/mp4" />
</video>
<canvas id="my-canvas" width="480" height="270"></canvas>
JavaScript
ãã®ã³ã¼ãã¯ãã¬ã¼ã ã®å å·¥ãæ±ãã¾ãã
var processor = {
timerCallback: function () {
if (this.video.paused || this.video.ended) {
return;
}
this.computeFrame();
var self = this;
setTimeout(function () {
self.timerCallback();
}, 16); // roughly 60 frames per second
},
doLoad: function () {
this.video = document.getElementById("my-video");
this.c1 = document.getElementById("my-canvas");
this.ctx1 = this.c1.getContext("2d");
var self = this;
this.video.addEventListener(
"play",
function () {
self.width = self.video.width;
self.height = self.video.height;
self.timerCallback();
},
false,
);
},
computeFrame: function () {
this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
var frame = this.ctx1.getImageData(0, 0, this.width, this.height);
var l = frame.data.length / 4;
for (var i = 0; i < l; i++) {
var grey =
(frame.data[i * 4 + 0] +
frame.data[i * 4 + 1] +
frame.data[i * 4 + 2]) /
3;
frame.data[i * 4 + 0] = grey;
frame.data[i * 4 + 1] = grey;
frame.data[i * 4 + 2] = grey;
}
this.ctx1.putImageData(frame, 0, 0);
return;
},
};
ãã¼ã¸ã®èªã¿è¾¼ã¿å¾ã«ã次ã®ããã«å¼ã³åºãã¦ãã ããã
processor.doLoad();
çµæ
ããã¯ããã£ã³ãã¹ã使ç¨ãã¦åç»ãã¬ã¼ã ãå å·¥ããæ¹æ³ã示ãã¨ã¦ãã·ã³ãã«ãªä¾ã§ããå¹çãããããããã«ã対å¿ãã¦ãããã©ã¦ã¶ã¼ã§å®è¡ããå ´å㯠requestAnimationFrame() ã setTimeout() ã®ä»£ããã«ä½¿ç¨ãããã¨ãæ¤è¨ããã»ããããã§ãããã
ã¡ã¢: æ½å¨çãªã»ãã¥ãªãã£ä¸ã®åé¡ã«ãããåç»ãã³ã¼ãã¨ç°ãªããã¡ã¤ã³ããé ä¿¡ããã¦ããå ´åãåç»ãé ä¿¡ãã¦ãããµã¼ãã¼ã§ CORS (ãªãªã¸ã³éãªã½ã¼ã¹å ±æ) ãæå¹ã«ããå¿ è¦ãããã¾ãã
åç»ã¨ WebGL
WebGL ã¯ãã£ã³ãã¹ã使ç¨ãã¦ãã¼ãã¦ã§ã¢ã¢ã¯ã»ã©ã¬ã¼ã·ã§ã³ã«ãã䏿¬¡å
ãäºæ¬¡å
ã®æç»ãè¡ãå¼·å㪠API ã§ãã <video> è¦ç´ ã¨çµã¿åããããã¨ã§ãåç»ããã¯ãã£ã¨ãã¦å©ç¨ã§ãã¾ããã¤ã¾ã䏿¬¡å
空éä¸ã«åç»ãé
ç½®ããåçã§ãã¾ãã
ã¡ã¢: ãã®ãã¢ã®ã½ã¼ã¹ã³ã¼ã㯠GitHub ã«ããã¾ã (ã©ã¤ãã§è¡¨ç¤ºã)ã
åçé度
é³å£°ãåç»ã®åçé度㯠<audio> ããã㯠<video> è¦ç´ ã® playbackRate ã¨å¼ã°ãã屿§ã使ç¨ãã¦èª¿æ´ãããã¨ãã§ãã¾ãã playbackRate ã«ã¯åçé度ã®åçãæå®ãã¾ããä¾ãã° 0.5 ãæå®ããã¨ååã®é度ã§ã 2 ãæå®ããã¨åéã§åçããã¾ãã
ãªãã playbackRate ããããã£ã¯ <audio> 㨠<video> ã®ä¸¡æ¹ã§åä½ãã¾ãããã©ã¡ãã®å ´åããåçé度ã夿´ãããã®ã®é³ç¨ã¯å¤æ´ãã¾ãããé³å£°ã®é«ãã夿´ããã«ã¯ã Web Audio API ã使ç¨ããå¿
è¦ãããã¾ãã AudioBufferSourceNode.playbackRate ããããã£ãåç
§ãã¦ãã ããã
HTML
<video
id="my-video"
controls
src="http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v"></video>
JavaScript
var myVideo = document.getElementById("my-video");
myVideo.playbackRate = 2;
ã¡ã¢: playbackRate ã®ãã¢ã試ãã¦ã¿ã¦ãã ããã
é³å£°ã®å å·¥
playbackRate ã®ä¸æ¹ã§ãé³å£°ãå å·¥ããããã«ã¯ Web Audio API ãå©ç¨ãããã¨ãä¸è¬çã§ãã
鳿ºã®é¸æ
Web Audio API ã¯ãæ§ã
ãªã½ã¼ã¹ããé³å£°ãåãåãããããå¦çãã¦ãåä¿¡ãããããå¦çãã¦é³ãå¦çããå¾ã«éä¿¡ããåºåæ©å¨ã表ã AudioDestinationNode ã«éãåºããã¨ãã§ãã¾ãã
| ãã®é³å£°ã½ã¼ã¹ã®å ´å... | ãã® Web Audio ãã¼ãåã使ç¨ãã¦ãã ãã node type |
|---|---|
HTML ã® <audio> ã¾ã㯠<video> è¦ç´ ã®é³å£°ãã©ã㯠|
MediaElementAudioSourceNode |
| ã¡ã¢ãªå ã®çã®é³å£°ãã¼ã¿ãããã¡ã¼ | AudioBufferSourceNode |
| ãµã¤ã³æ³¢ããã®ä»ã®åææ³¢å½¢ãçæãããªã·ã¬ã¼ã¿ã¼ | OscillatorNode |
WebRTC ã®é³å£°ãã©ã㯠(ä¾ãã° getUserMedia() ã使ç¨ãã¦åå¾ã§ãããã¤ã¯å
¥å) |
MediaStreamAudioSourceNode |
é³å£°ãã£ã«ã¿ã¼
Web Audio API ã§ã¯ BiquadFilterNode ãå©ç¨ãããã¨ã§æ§ã
ãªãã£ã«ã¿ã¼ãã¨ãã§ã¯ããå©ç¨ã§ãã¾ãã
HTML
<video id="my-video" controls src="myvideo.mp4" type="video/mp4"></video>
JavaScript
var context = new AudioContext(),
audioSource = context.createMediaElementSource(
document.getElementById("my-video"),
),
filter = context.createBiquadFilter();
audioSource.connect(filter);
filter.connect(context.destination);
// Configure filter
filter.type = "lowshelf";
filter.frequency.value = 1000;
filter.gain.value = 25;
ã¡ã¢: CORS ãæå¹ã«ãªã£ã¦ããªãç°å¢ã§ã¯ãåç»ã¯ã³ã¼ãã¨åããã¡ã¤ã³ä¸ã«ãªããã°ãªãã¾ãããããã¯ã»ãã¥ãªãã£ä¸ã®åé¡ãé¿ããããã§ãã
ãã使ãããé³å£°ãã£ã«ã¿ã¼
ãã®ãã¼ãã§ããå©ç¨ããããã£ã«ã¿ã¼ã¯ä»¥ä¸ã®éãã§ãã
- ãã¼ãã¹: é¾å¤ã«æå®ããã卿³¢æ°ããä½ãé³ã¯ééãããé«ããã®ã¯æ¸è¡°ããã¾ãã
- ãã¤ãã¹: é¾å¤ã«æå®ããã卿³¢æ°ããé«ãé³ã¯ééãããä½ããã®ã¯æ¸è¡°ããã¾ãã
- ãã³ããã¹: æå®ããã卿³¢æ°å¸¯ã®é³ã¯ééããããã以å¤ã¯æ¸è¡°ããã¾ãã
- ãã¼ã·ã§ã«ã: 卿³¢æ°ã«é¢ãããå ¨ã¦ã®é³ãééããã¾ãããé¾å¤ããä½ããã®ã¯å¢å¹ (ãããã¯æ¸è¡°) ããã¾ã
- ãã¤ã·ã§ã«ã: 卿³¢æ°ã«é¢ãããå ¨ã¦ã®é³ãééããã¾ãããé¾å¤ããé«ããã®ã¯å¢å¹ (ãããã¯æ¸è¡°) ããã¾ã
- ãã¼ãã³ã°: 卿³¢æ°ã«é¢ãããå ¨ã¦ã®é³ãééããã¾ãããæå®ããã卿³¢æ°å¸¯ã®ãã®ã¯å¢å¹ (ãããã¯æ¸è¡°) ããã¾ã
- ããã: æå®ããã卿³¢æ°å¸¯ãé¤ããå ¨ã¦ã®é³ãééããã¾ã
- ãªã¼ã«ãã¹: 卿³¢æ°ã«é¢ãããå ¨ã¦ã®é³ãééããã¾ãããå¹¾ã¤ãã®å¨æ³¢æ°éã®ç¸é¢ä¿ã夿´ãã¾ã
ã¡ã¢:
詳ãã㯠BiquadFilterNode ãåç
§ãã¦ãã ããã
ããã¿è¾¼ã¿ã¨ã¤ã³ãã«ã¹
ConvolverNode ãå©ç¨ãããã¨ã§ãé³å£°ã«ã¤ã³ãã«ã¹å¿çãé©ç¨ãããã¨ãã§ãã¾ããã¤ã³ãã«ã¹å¿çã¨ã¯ãã³ãã¯ã©ããã®ãããªçãé³ã®ã¤ã³ãã«ã¹ãã使ãããé³ã®ãã¨ã§ããã¤ã³ãã«ã¹å¿çã¯ã¤ã³ãã«ã¹ãä½ãããç°å¢ (ä¾ãã°ãã³ãã«å
ã§æãå©ããã¨ã§çºçããã¨ã³ã¼) ã示ãã¾ãã
ä¾
var convolver = context.createConvolver();
convolver.buffer = this.impulseResponseBuffer;
// Connect the graph.
source.connect(convolver);
convolver.connect(context.destination);
é©ç¨ä¾ã¨ãã¦ã¯ãã® Codepen ãã覧ãã ãã (ãã ããã¨ã¦ããã¨ã¦ããã ããªãã§ããå°ããªåã©ããåã¶ãããã§ããã)ã
空éçãªé³
ãã³ãã¼ãã¼ãã使ç¨ãããã¨ã§ã鳿ºã®ä½ç½®ãæä½ã§ãã¾ãããã³ãã¼ãã¼ãâPannerNodeâã¯ãã½ã¼ã¹ã³ã¼ã³ã®ä½ç½®ã ãã§ãªãããã®æ¹åãæå®ãããã¨ãã§ãã¾ããä½ç½®ãæ¹åã¯ä¸æ¬¡å
空éä¸ã§æå®ãã¾ãã
ä¾
var panner = context.createPanner();
panner.coneOuterGain = 0.2;
panner.coneOuterAngle = 120;
panner.coneInnerAngle = 0;
panner.connect(context.destination);
source.connect(panner);
source.start(0);
// Position the listener at the origin.
context.listener.setPosition(0, 0, 0);
ã¡ã¢: GitHub ãªãã¸ããªã«ä¾ãããã¾ã (ã©ã¤ãçã)ã
JavaScript ã«ããã³ã¼ããã¯
JavasCript ã§ããä½ã¬ãã«ã§ã®é³å£°æä½ãå¯è½ã§ãããããå©ç¨ãããã¨ã§ããªã¼ãã£ãªã³ã¼ããã¯ãèªä½ãããã¨ãã§ãã¾ãã
以ä¸ã«ãã©ã¼ãããã¨ãã®ã³ã¼ããã¯ã®ãªã¹ãã示ãã¾ãã
ã¡ã¢: AudioCogs ã§ããã¤ãã®ãã¢ã試ãã¾ãã Audiocogs 㯠JavaScript ã§ã®ã³ã¼ããã¯å®è£ ãè¡ãããã®ãã¬ã¼ã ã¯ã¼ã¯ã§ãã Aurora.js ãæä¾ãã¦ãã¾ãã
ä¾
é¢é£æ å ±
>ãã¥ã¼ããªã¢ã«
- ãã£ã³ãã¹ã使ç¨ããåç»ã®å å·¥
- HTML5 playbackRate ã®è§£èª¬
- Web Audio API ã®å©ç¨
- Web audio spatialisation ã®åºæ¬
- åç»ãã¬ã¼ã ã® WebGL ãã¯ã¹ãã£ã¨ãã¦ã®å©ç¨ (THREE.js WebGL ã©ã¤ãã©ãª (åã³ãã®ä») 㨠ãã®å¹æã®å®ç¾)
- WebGL ã«ãããã¢ãã¡ã¼ã·ã§ã³ãã¯ã¹ãã£
- Developing Game Audio with the Web Audio API (Room effects and filters)
ãªãã¡ã¬ã³ã¹
<audio>ããã³<video>è¦ç´HTMLMediaElementAPI<canvas>è¦ç´- Web Audio API
- AudioContext
- More info on Spatial Audio
- ã¦ã§ãã¡ãã£ã¢æè¡