jsmad/index.html

93 lines
2.3 KiB
HTML

<!doctype html>
<html>
<head>
</head>
<body>
<script>
var Module = {
onRuntimeInitialized: function() {
}
};
</script>
<script src="wrapper.js"></script>
<input type="file" id="file" name="file" />
<script>
var minPortion = 4096;
var maxPortion = 40960;
var time = 0;
var ctx = new AudioContext();
ctx.suspend();
var decoder;
var fragments = [];
var decoding = false;
function onChange(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
decoder = new Module.Decoder();
createFileFragments(reader.result);
scheduleData();
setTimeout(ctx.resume.bind(ctx), 1000);
}
reader.readAsArrayBuffer(file);
}
function schedule() {
decoding = false;
if (decoder.hasMore()) {
var audio = decoder.decode(20);
if (audio) {
var source = ctx.createBufferSource();
source.buffer = audio;
source.connect(ctx.destination);
source.start(time);
time += audio.duration;
setTimeout(schedule, Math.floor(audio.duration * 200));
decoding = true;
} else {
decoder.delete();
}
} else {
decoder.delete();
}
}
function scheduleData() {
if (fragments.length) {
var frag = fragments.shift();
decoder.addFragment(frag);
if (fragments.length) {
setTimeout(scheduleData, 100);
}
if (!decoding) {
schedule();
}
}
}
function createFileFragments(buffer) {
var src = new Uint8Array(buffer);
var shoved = 0;
while (shoved !== src.length) {
var ps = Math.min(Math.floor(Math.random() * (maxPortion - minPortion) + minPortion), src.length - shoved);
var portion = new Uint8Array(buffer, shoved, ps)
shoved += ps;
fragments.push(portion);
}
}
document.getElementById("file").addEventListener("change", onChange, false);
</script>
</body>
</html>