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>
12 const AUDIO_ONLY_MIME_TYPES
= [
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
= [
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
,
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
,
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");
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");
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");
83 assert_throws_dom("NotSupportedError",
84 () => new MediaRecorder(new MediaStream(), {mimeType
: "audio/banana"}));
85 }, "MediaRecorder invalid audio mimeType throws");
88 assert_false(MediaRecorder
.isTypeSupported("audio/banana"));
89 }, "MediaRecorder invalid audio mimeType is unsupported");
92 assert_throws_dom("NotSupportedError",
93 () => new MediaRecorder(new MediaStream(), {mimeType
: "video/pineapple"}));
94 }, "MediaRecorder invalid video mimeType throws");
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
)) {
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`);
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
);
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
)) {
124 const recorder
= new MediaRecorder(createFlowingAudioStream(t
).stream
, {mimeType
});
126 }, `MediaRecorder start() does not throw with ${mimeType} for audio`);
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
)) {
138 const recorder
= new MediaRecorder(createFlowingVideoStream(t
).stream
, {mimeType
});
140 }, `MediaRecorder start() does not throw with ${mimeType} for video`);
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
)) {
152 const recorder
= new MediaRecorder(createFlowingAudioStream(t
).stream
, {mimeType
});
154 }, `MediaRecorder start() does not throw with ${mimeType} for audio`);
158 promise_test(async t
=> {
159 const recorder
= new MediaRecorder(createFlowingVideoStream(t
).stream
);
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
);
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
);
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
);
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
);
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");
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");
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");
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
);
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");
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
);
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");
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
);
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");
270 recorder
.mimeType
, /^[a-z]+\/[a-z]+;[ ]*codecs=[^,]+,[^,]+$/,
271 "mimeType has two codecs");
272 }, "MediaRecorder formats mimeType well after 'start' for audio/video");