-
Notifications
You must be signed in to change notification settings - Fork 0
/
audio_recorder.html
121 lines (105 loc) · 3.87 KB
/
audio_recorder.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<title>createMediaStreamDestination() demo</title>
</head>
<body>
<h1>createMediaStreamDestination() demo</h1>
<p>Encoding a pure sine wave to an Opus file</p>
<button>Make sine wave</button>
<audio controls></audio>
<div id="codecs"></div>
<script>
//const mimeType = "audio/ogg; codecs=opus";
const mimeType = "audio/wav";
//const mimeType = "audio/pcm;rate=96000";
//const mimeType = "audio/x-ogg-pcm";
//const mimeType = "audio/x-ogg-flac";
//const mimeType = "audio/webm;codecs=PCM";
const b = document.querySelector("button");
let clicked = false;
const chunks = [];
const ac = new AudioContext({sampleRate: 96000});
const osc = ac.createOscillator();
const dest = ac.createMediaStreamDestination();
const mediaRecorder = new MediaRecorder(
dest.stream,
{
mimeType: "audio/webm;codecs=PCM",
},
);
osc.connect(dest);
b.addEventListener("click", (e) => {
if (!clicked) {
mediaRecorder.start();
osc.start(0);
e.target.textContent = "Stop recording";
clicked = true;
} else {
mediaRecorder.stop();
osc.stop(0);
e.target.disabled = true;
}
});
mediaRecorder.ondataavailable = (evt) => {
// Push each chunk (blobs) in an array
console.log(evt.data.type);
chunks.push(evt.data);
};
mediaRecorder.onstop = (evt) => {
// https://www.digipres.org/formats/mime-types/
// Make blob out of our blobs, and open it.
const blob = new Blob(chunks, { type: mimeType});
document.querySelector("audio").src = URL.createObjectURL(blob);
};
</script>
<script>
// https://stackoverflow.com/questions/41739837/all-mime-types-supported-by-mediarecorder-in-firefox-and-chrome/42307926#42307926
function getSupportedMimeTypes(media, types, codecs) {
const isSupported = MediaRecorder.isTypeSupported;
const supported = [];
types.forEach((type) => {
const mimeType = `${media}/${type}`;
codecs.forEach((codec) => [
`${mimeType};codecs=${codec}`,
`${mimeType};codecs=${codec.toUpperCase()}`,
// /!\ false positive /!\
// `${mimeType};codecs:${codec}`,
// `${mimeType};codecs:${codec.toUpperCase()}`
].forEach(variation => {
if(isSupported(variation))
supported.push(variation);
}));
if (isSupported(mimeType))
supported.push(mimeType);
});
return supported;
};
function displayCodecs(codecs, type) {
const el = document.getElementById("codecs");
let node = document.createElement("div");
el.appendChild(node);
title = document.createElement("H1");
title.setHTML(type);
node.appendChild(title);
codecs.forEach((codec, id) => {
const p = document.createElement("p");
p.setHTML(codec);
if (id === 0) {
p.setAttribute("style", "color:red");
}
node.appendChild(p);
});
}
// Usage ------------------
const videoTypes = ["webm", "ogg", "mp4", "x-matroska"];
const audioTypes = ["webm", "ogg", "mp3", "x-matroska"];
const codecs = ["should-not-be-supported","vp9", "vp9.0", "vp8", "vp8.0", "avc1", "av1", "h265", "h.265", "h264", "h.264", "opus", "pcm", "aac", "mpeg", "mp4a"];
const supportedVideos = getSupportedMimeTypes("video", videoTypes, codecs);
const supportedAudios = getSupportedMimeTypes("audio", audioTypes, codecs);
displayCodecs(supportedAudios, "Audio");
displayCodecs(supportedVideos, "Video");
</script>
</body>
</html>