Bug 1836734 [wpt PR 40379] - MediaRecorder: Don't throw with video mimeType for audio...
[gecko.git] / testing / web-platform / tests / mediacapture-record / MediaRecorder-mimetype.html
blob994792790a20ef9fd44eb8a3336f5829965cb76d
1 <!doctype html>
2 <html>
3 <head>
4 <title>MediaRecorder mimeType</title>
5 <link rel="help" href="https://w3c.github.io/mediacapture-record/MediaRecorder.html#dom-mediarecorder-mimeType">
6 <script src="/resources/testharness.js"></script>
7 <script src="/resources/testharnessreport.js"></script>
8 <script src="utils/sources.js"></script>
9 </head>
10 <body>
11 <script>
12 const AUDIO_ONLY_MIME_TYPES = [
13 'audio/mp4',
14 'audio/ogg',
15 'audio/webm',
18 const AUDIO_CODECS_MIME_TYPES = [
19 'audio/ogg; codecs="vorbis"',
20 'audio/ogg; codecs="opus"',
21 'audio/webm; codecs="vorbis"',
22 'audio/webm; codecs="opus"',
25 const VIDEO_ONLY_MIME_TYPES = [
26 'video/mp4',
27 'video/webm',
30 const VIDEO_CODECS_MIME_TYPES = [
31 'video/webm; codecs="vp8"',
32 'video/webm; codecs="vp9"',
33 'video/webm; codecs="av1"',
36 const AUDIO_VIDEO_MIME_TYPES = [
37 'video/webm; codecs="vp8, vorbis"',
38 'video/webm; codecs="vp8, opus"',
39 'video/webm; codecs="vp9, vorbis"',
40 'video/webm; codecs="vp9, opus"',
41 'video/webm; codecs="av1, opus"',
44 const AUDIO_MIME_TYPES = [
45 ...AUDIO_ONLY_MIME_TYPES,
46 ...AUDIO_CODECS_MIME_TYPES,
47 ...AUDIO_VIDEO_MIME_TYPES,
50 const VIDEO_MIME_TYPES = [
51 ...VIDEO_ONLY_MIME_TYPES,
52 ...VIDEO_CODECS_MIME_TYPES,
53 ...AUDIO_VIDEO_MIME_TYPES,
56 const MIME_TYPES = [
57 ...AUDIO_ONLY_MIME_TYPES,
58 ...AUDIO_CODECS_MIME_TYPES,
59 ...VIDEO_ONLY_MIME_TYPES,
60 ...VIDEO_CODECS_MIME_TYPES,
61 ...AUDIO_VIDEO_MIME_TYPES,
64 test(t => {
65 const recorder = new MediaRecorder(createAudioStream(t).stream);
66 assert_equals(recorder.mimeType, "",
67 "MediaRecorder has no default mimeType");
68 }, "MediaRecorder sets no default mimeType in the constructor for audio");
70 test(t => {
71 const recorder = new MediaRecorder(createVideoStream(t).stream);
72 assert_equals(recorder.mimeType, "",
73 "MediaRecorder has no default mimeType");
74 }, "MediaRecorder sets no default mimeType in the constructor for video");
76 test(t => {
77 const recorder = new MediaRecorder(createAudioVideoStream(t).stream);
78 assert_equals(recorder.mimeType, "",
79 "MediaRecorder has no default mimeType");
80 }, "MediaRecorder sets no default mimeType in the constructor for audio/video");
82 test(t => {
83 assert_throws_dom("NotSupportedError",
84 () => new MediaRecorder(new MediaStream(), {mimeType: "audio/banana"}));
85 }, "MediaRecorder invalid audio mimeType throws");
87 test(t => {
88 assert_false(MediaRecorder.isTypeSupported("audio/banana"));
89 }, "MediaRecorder invalid audio mimeType is unsupported");
91 test(t => {
92 assert_throws_dom("NotSupportedError",
93 () => new MediaRecorder(new MediaStream(), {mimeType: "video/pineapple"}));
94 }, "MediaRecorder invalid video mimeType throws");
96 test(t => {
97 assert_false(MediaRecorder.isTypeSupported("video/pineapple"));
98 }, "MediaRecorder invalid video mimeType is unsupported");
100 for (const mimeType of MIME_TYPES) {
101 if (MediaRecorder.isTypeSupported(mimeType)) {
102 test(t => {
103 const recorder = new MediaRecorder(new MediaStream(), {mimeType});
104 assert_equals(recorder.mimeType, mimeType, "Supported mimeType is set");
105 }, `Supported mimeType ${mimeType} is set immediately after constructing`);
106 } else {
107 test(t => {
108 assert_throws_dom("NotSupportedError",
109 () => new MediaRecorder(new MediaStream(), {mimeType}));
110 }, `Unsupported mimeType ${mimeType} throws`);
114 promise_test(async t => {
115 const recorder = new MediaRecorder(createFlowingAudioStream(t).stream);
116 recorder.start();
117 await new Promise(r => recorder.onstart = r);
118 assert_not_equals(recorder.mimeType, "");
119 }, "MediaRecorder sets a nonempty mimeType on 'onstart' for audio");
121 for (const mimeType of AUDIO_MIME_TYPES) {
122 if (MediaRecorder.isTypeSupported(mimeType)) {
123 test(t => {
124 const recorder = new MediaRecorder(createFlowingAudioStream(t).stream, {mimeType});
125 recorder.start();
126 }, `MediaRecorder start() does not throw with ${mimeType} for audio`);
127 } else {
128 test(t => {
129 assert_throws_dom("NotSupportedError",
130 () => new MediaRecorder(createFlowingAudioStream(t).stream, {mimeType}));
131 }, `Unsupported mimeType ${mimeType} throws for audio`);
135 for (const mimeType of VIDEO_MIME_TYPES) {
136 if (MediaRecorder.isTypeSupported(mimeType)) {
137 test(t => {
138 const recorder = new MediaRecorder(createFlowingVideoStream(t).stream, {mimeType});
139 recorder.start();
140 }, `MediaRecorder start() does not throw with ${mimeType} for video`);
141 } else {
142 test(t => {
143 assert_throws_dom("NotSupportedError",
144 () => new MediaRecorder(createFlowingVideoStream(t).stream, {mimeType}));
145 }, `Unsupported mimeType ${mimeType} throws for video`);
149 for (const mimeType of VIDEO_ONLY_MIME_TYPES) {
150 if (MediaRecorder.isTypeSupported(mimeType)) {
151 test(t => {
152 const recorder = new MediaRecorder(createFlowingAudioStream(t).stream, {mimeType});
153 recorder.start();
154 }, `MediaRecorder start() does not throw with ${mimeType} for audio`);
158 promise_test(async t => {
159 const recorder = new MediaRecorder(createFlowingVideoStream(t).stream);
160 recorder.start();
161 await new Promise(r => recorder.onstart = r);
162 assert_not_equals(recorder.mimeType, "");
163 }, "MediaRecorder sets a nonempty mimeType on 'onstart' for video");
165 promise_test(async t => {
166 const recorder = new MediaRecorder(createFlowingAudioVideoStream(t).stream);
167 recorder.start();
168 await new Promise(r => recorder.onstart = r);
169 assert_not_equals(recorder.mimeType, "");
170 }, "MediaRecorder sets a nonempty mimeType on 'onstart' for audio/video");
172 promise_test(async t => {
173 const recorder = new MediaRecorder(createFlowingAudioStream(t).stream);
174 recorder.start();
175 assert_equals(recorder.mimeType, "");
176 }, "MediaRecorder mimeType is not set before 'onstart' for audio");
178 promise_test(async t => {
179 const recorder = new MediaRecorder(createFlowingVideoStream(t).stream);
180 recorder.start();
181 assert_equals(recorder.mimeType, "");
182 }, "MediaRecorder mimeType is not set before 'onstart' for video");
184 promise_test(async t => {
185 const recorder = new MediaRecorder(createFlowingAudioVideoStream(t).stream);
186 recorder.start();
187 assert_equals(recorder.mimeType, "");
188 }, "MediaRecorder mimeType is not set before 'onstart' for audio/video");
190 promise_test(async t => {
191 const recorder = new MediaRecorder(createFlowingAudioStream(t).stream);
192 const onstartPromise = new Promise(resolve => {
193 recorder.onstart = () => {
194 recorder.onstart = () => t.step_func(() => {
195 assert_not_reached("MediaRecorder doesn't fire 'onstart' twice");
197 resolve();
200 recorder.start();
201 await onstartPromise;
202 await new Promise(r => t.step_timeout(r, 1000));
203 }, "MediaRecorder doesn't fire 'onstart' multiple times for audio");
205 promise_test(async t => {
206 const recorder = new MediaRecorder(createFlowingVideoStream(t).stream);
207 const onstartPromise = new Promise(resolve => {
208 recorder.onstart = () => {
209 recorder.onstart = () => t.step_func(() => {
210 assert_not_reached("MediaRecorder doesn't fire 'onstart' twice");
212 resolve();
215 recorder.start();
216 await onstartPromise;
217 await new Promise(r => t.step_timeout(r, 1000));
218 }, "MediaRecorder doesn't fire 'onstart' multiple times for video");
220 promise_test(async t => {
221 const recorder = new MediaRecorder(createFlowingAudioVideoStream(t).stream);
222 const onstartPromise = new Promise(resolve => {
223 recorder.onstart = () => {
224 recorder.onstart = () => t.step_func(() => {
225 assert_not_reached("MediaRecorder doesn't fire 'onstart' twice");
227 resolve();
230 recorder.start();
231 await onstartPromise;
232 await new Promise(r => t.step_timeout(r, 1000));
233 }, "MediaRecorder doesn't fire 'onstart' multiple times for audio/video");
235 promise_test(async t => {
236 const recorder = new MediaRecorder(createFlowingAudioStream(t).stream);
237 recorder.start();
238 await new Promise(r => recorder.onstart = r);
239 assert_regexp_match(recorder.mimeType, /^audio\//,
240 "mimeType has an expected media type");
241 assert_regexp_match(recorder.mimeType, /^[a-z]+\/[a-z]+/,
242 "mimeType has a container subtype");
243 assert_regexp_match(
244 recorder.mimeType, /^[a-z]+\/[a-z]+;[ ]*codecs=[^,]+$/,
245 "mimeType has one codec a");
246 }, "MediaRecorder formats mimeType well after 'start' for audio");
248 promise_test(async t => {
249 const recorder = new MediaRecorder(createFlowingVideoStream(t).stream);
250 recorder.start();
251 await new Promise(r => recorder.onstart = r);
252 assert_regexp_match(recorder.mimeType, /^video\//,
253 "mimeType has an expected media type");
254 assert_regexp_match(recorder.mimeType, /^[a-z]+\/[a-z]+/,
255 "mimeType has a container subtype");
256 assert_regexp_match(
257 recorder.mimeType, /^[a-z]+\/[a-z]+;[ ]*codecs=[^,]+$/,
258 "mimeType has one codec a");
259 }, "MediaRecorder formats mimeType well after 'start' for video");
261 promise_test(async t => {
262 const recorder = new MediaRecorder(createFlowingAudioVideoStream(t).stream);
263 recorder.start();
264 await new Promise(r => recorder.onstart = r);
265 assert_regexp_match(recorder.mimeType, /^video\//,
266 "mimeType has an expected media type");
267 assert_regexp_match(recorder.mimeType, /^[a-z]+\/[a-z]+/,
268 "mimeType has a container subtype");
269 assert_regexp_match(
270 recorder.mimeType, /^[a-z]+\/[a-z]+;[ ]*codecs=[^,]+,[^,]+$/,
271 "mimeType has two codecs");
272 }, "MediaRecorder formats mimeType well after 'start' for audio/video");
273 </script>
274 </body>
275 </html>