.currentTime
<audio>
の要素をチェックすることで、メディアのストリーミング中に正確なアニメーションを実行するために、1秒間に3〜4回発射される<audio>
要素のtimeupdate
イベントを利用しています。アニメーションやトランジションは、1秒間に数回まで起動または停止できます。
ブラウザで利用できる場合は、リソースのReadableStream
を返し.then()
リターンresponse.body.getReader()
で、オーディオリソースを要求するためにfetch()
を使用することができます。新しいMediaSource
オブジェクトを作成し、MediaSource
の<audio>
またはnew Audio()
.src
〜objectURL
を設定します。 .read()
が.then()
からsourceBuffer
、MediaSource
、.mode
が"sequence"
に設定されている最初のストリームチャンクを追加します。残りのチャンクをsourceBuffer
にsourceBuffer
updateend
イベントに追加します。
もしfetch()
response.body.getReader()
は、あなたはまだメディアストリーミング再生の必要な第2のアニメーションやトランジションを開始または停止、.currentTime
をチェックする<audio>
要素のtimeupdate
またはprogress
イベントを使用することができ、ブラウザでは利用できません。
canplay
のイベントを<audio>
要素に使用すると、ストリームが適切なバッファを蓄積したときにメディアを再生して、再生を続行することができます(MediaSource
)。
あなたが正確なアニメーションを実行するようにアニメーション化されるべきアニメーションが発生した場合<audio>
の.currentTime
に対応する番号、および要素のcss
プロパティに設定された値に設定するプロパティを持つオブジェクトを使用することができます。
以下のjavascript
では、アニメーションは、0
で始まり、20秒ごとに、メディアの再生が終了するまで60秒ごとに発生します。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<style>
body {
width: 90vw;
height: 90vh;
background: #000;
transition: background 1s;
}
span {
font-family: Georgia;
font-size: 36px;
opacity: 0;
}
</style>
</head>
<body>
<audio controls></audio>
<br>
<span></span>
<script type="text/javascript">
window.onload = function() {
var url = "/path/to/audio";
// given 240 seconds total duration of audio
// 240/12 = 20
// properties correspond to `<audio>` `.currentTime`,
// values correspond to color to set at element
var colors = {
0: "red",
20: "blue",
40: "green",
60: "yellow",
80: "orange",
100: "purple",
120: "violet",
140: "brown",
160: "tan",
180: "gold",
200: "sienna",
220: "skyblue"
};
var body = document.querySelector("body");
var mediaSource = new MediaSource;
var audio = document.querySelector("audio");
var span = document.querySelector("span");
var color = window.getComputedStyle(body)
.getPropertyValue("background-color");
//console.log(mediaSource.readyState); // closed
var mimecodec = "audio/mpeg";
audio.oncanplay = function() {
this.play();
}
audio.ontimeupdate = function() {
// 240/12 = 20
var curr = Math.round(this.currentTime);
if (colors.hasOwnProperty(curr)) {
// set `color` to `colors[curr]`
color = colors[curr]
}
// animate `<span>` every 60 seconds
if (curr % 60 === 0 && span.innerHTML === "") {
var t = curr/60;
span.innerHTML = t + " minute" + (t === 1 ? "" : "s")
+ " of " + Math.round(this.duration)/60
+ " minutes of audio";
span.animate([{
opacity: 0
}, {
opacity: 1
}, {
opacity: 0
}], {
duration: 2500,
iterations: 1
})
.onfinish = function() {
span.innerHTML = ""
}
}
// change `background-color` of `body` every 20 seconds
body.style.backgroundColor = color;
console.log("current time:", curr
, "current background color:", color
, "duration:", this.duration);
}
// set `<audio>` `.src` to `mediaSource`
audio.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener("sourceopen", sourceOpen);
function sourceOpen(event) {
// if the media type is supported by `mediaSource`
// fetch resource, begin stream read,
// append stream to `sourceBuffer`
if (MediaSource.isTypeSupported(mimecodec)) {
var sourceBuffer = mediaSource.addSourceBuffer(mimecodec);
// set `sourceBuffer` `.mode` to `"sequence"`
sourceBuffer.mode = "sequence";
fetch(url)
// return `ReadableStream` of `response`
.then(response => response.body.getReader())
.then(reader => {
var processStream = (data) => {
if (data.done) {
return;
}
// append chunk of stream to `sourceBuffer`
sourceBuffer.appendBuffer(data.value);
}
// at `sourceBuffer` `updateend` call `reader.read()`,
// to read next chunk of stream, append chunk to
// `sourceBuffer`
sourceBuffer.addEventListener("updateend", function() {
reader.read().then(processStream);
});
// start processing stream
reader.read().then(processStream);
// do stuff `reader` is closed,
// read of stream is complete
return reader.closed.then(() => {
// signal end of stream to `mediaSource`
mediaSource.endOfStream();
return mediaSource.readyState;
})
})
// do stuff when `reader.closed`, `mediaSource` stream ended
.then(msg => console.log(msg))
}
// if `mimecodec` is not supported by `MediaSource`
else {
alert(mimecodec + " not supported");
}
};
}
</script>
</body>
</html>
plnkr http://plnkr.co/edit/fIm1Qp?p=preview
私は違いを測定する方法があるとは思わないので、私は通常、ストリームを分析クライアント - WebAudioAPIを使用してブラウザ内に表示します。このテクニックを使用すると、ブラウザで再生されているIcecastストリームと密接に関連するアニメーション(イコライザなど)を作成できます。 –