Skip to content

Commit 243e84c

Browse files
alastor0325moz-wptsync-bot
authored andcommitted
add a WPT to verify the spec src reset behavior.
Differential Revision: https://phabricator.services.mozilla.com/D280511 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=2016210 gecko-commit: 8ab8241f0554f64020902f1ebafa8bb517822e59 gecko-reviewers: pehrsons
1 parent 9d18397 commit 243e84c

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src=/resources/testharness.js></script>
5+
<script src=/resources/testharnessreport.js></script>
6+
<script src=../webrtc/RTCPeerConnection-helper.js></script>
7+
</head>
8+
<body>
9+
<video loop controls></video>
10+
<script>
11+
12+
// Verify captureStream tracks are removed when src is reset, and updated when
13+
// the source is changed directly without an explicit reset. Both src and
14+
// srcObject attributes are tested. Tests run sequentially on the same video
15+
// element and stream.
16+
// https://w3c.github.io/mediacapture-fromelement/#methods
17+
18+
const VIDEO_ONLY_TEST = {
19+
filename : "test-v-128k-320x240-24fps-8kfr.webm",
20+
trackCount : 1
21+
};
22+
const AUDIO_ONLY_TEST = {
23+
filename : "test-a-128k-44100Hz-1ch.webm",
24+
trackCount : 1
25+
};
26+
const AUDIO_VIDEO_TEST = {
27+
filename : "test-av-384k-44100Hz-1ch-320x240-30fps-10kfr.webm",
28+
trackCount : 2
29+
};
30+
const NO_TRACKS = 0;
31+
32+
const video = document.querySelector("video");
33+
assert_implements("captureStream" in video, "HTMLMediaElement.captureStream() is not implemented");
34+
const stream = video.captureStream();
35+
36+
// Native streams used as srcObject sources. Kept alive across tests so that
37+
// their tracks remain active until explicitly replaced, ensuring removetrack
38+
// fires on the captured stream only when srcObject is changed.
39+
const nativeStreams = [];
40+
41+
promise_test(async function testSrcVideoOnly(t) {
42+
video.onerror = t.unreached_func("video error");
43+
video.src = "/media/" + VIDEO_ONLY_TEST.filename;
44+
await video.play();
45+
assertStreamStatus(VIDEO_ONLY_TEST.trackCount);
46+
}, "src-video-only");
47+
48+
promise_test(async function testSrcAudioOnly(t) {
49+
const prevTrackCount = stream.getTracks().length;
50+
video.onerror = t.unreached_func("video error");
51+
video.src = "/media/" + AUDIO_ONLY_TEST.filename;
52+
await waitForNEvents(stream, "removetrack", prevTrackCount);
53+
assertStreamStatus(NO_TRACKS);
54+
await video.play();
55+
assertStreamStatus(AUDIO_ONLY_TEST.trackCount);
56+
}, "src-audio-only");
57+
58+
promise_test(async function testSrcReset(t) {
59+
const prevTrackCount = stream.getTracks().length;
60+
video.src = "";
61+
video.removeAttribute("src");
62+
await waitForNEvents(stream, "removetrack", prevTrackCount);
63+
assertStreamStatus(NO_TRACKS);
64+
}, "src-reset");
65+
66+
promise_test(async function testSrcObjAudioVideo(t) {
67+
video.onerror = t.unreached_func("video error");
68+
const ns = await getNoiseStream({audio: true, video: true});
69+
nativeStreams.push(ns);
70+
video.srcObject = ns;
71+
await video.play();
72+
assertStreamStatus(AUDIO_VIDEO_TEST.trackCount);
73+
}, "srcObj-audio-video");
74+
75+
promise_test(async function testSrcObjVideoOnly(t) {
76+
const prevTrackCount = stream.getTracks().length;
77+
video.onerror = t.unreached_func("video error");
78+
const ns = await getNoiseStream({video: true});
79+
nativeStreams.push(ns);
80+
video.srcObject = ns;
81+
await waitForNEvents(stream, "removetrack", prevTrackCount);
82+
assertStreamStatus(NO_TRACKS);
83+
await video.play();
84+
assertStreamStatus(VIDEO_ONLY_TEST.trackCount);
85+
}, "srcObj-video-only");
86+
87+
promise_test(async function testSrcAudioVideo(t) {
88+
const prevTrackCount = stream.getTracks().length;
89+
video.onerror = t.unreached_func("video error");
90+
video.srcObject = null;
91+
video.src = "/media/" + AUDIO_VIDEO_TEST.filename;
92+
await waitForNEvents(stream, "removetrack", prevTrackCount);
93+
assertStreamStatus(NO_TRACKS);
94+
await video.play();
95+
assertStreamStatus(AUDIO_VIDEO_TEST.trackCount);
96+
}, "src-audio-video");
97+
98+
promise_test(async function testSrcObjAudioOnly(t) {
99+
const prevTrackCount = stream.getTracks().length;
100+
video.onerror = t.unreached_func("video error");
101+
t.add_cleanup(() => {
102+
for (const s of nativeStreams) {
103+
s.getTracks().forEach(track => track.stop());
104+
}
105+
video.srcObject = null;
106+
video.src = "";
107+
video.removeAttribute("src");
108+
});
109+
const ns = await getNoiseStream({audio: true});
110+
nativeStreams.push(ns);
111+
video.srcObject = ns;
112+
await waitForNEvents(stream, "removetrack", prevTrackCount);
113+
assertStreamStatus(NO_TRACKS);
114+
await video.play();
115+
assertStreamStatus(AUDIO_ONLY_TEST.trackCount);
116+
}, "srcObj-audio-only");
117+
118+
function assertStreamStatus(trackCount) {
119+
assert_equals(stream.getTracks().length, trackCount, "stream track count");
120+
if (trackCount > 0) {
121+
assert_true(stream.active, "stream must be active");
122+
} else {
123+
assert_false(stream.active, "stream must be inactive");
124+
}
125+
}
126+
127+
function waitForNEvents(target, name, count) {
128+
return new Promise(resolve => {
129+
let seen = 0;
130+
function onEvent(e) {
131+
if (++seen >= count) {
132+
target.removeEventListener(name, onEvent);
133+
resolve();
134+
}
135+
}
136+
target.addEventListener(name, onEvent);
137+
});
138+
}
139+
140+
</script>
141+
</body>
142+
</html>

0 commit comments

Comments
 (0)