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
media / test / data / eme_player_js / mse_player_utils.js [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// MSEPlayerUtils provides functionality to load and append media segments using
// MSE API. The segments can be fetched at specified intervals to simulate
// generic MSE video players.
class MSEPlayerUtilsClass {
loadMediaSegmentsFromTestConfig(testConfig) {
this.mediaSegments = testConfig.mediaFile;
this.mediaType = testConfig.mediaType;
// Duration for each of the media segment.
this.MSESegmentDurationMS = testConfig.MSESegmentDurationMS
// How long before media play end should the next segment be fetched.
this.MSESegmentFetchDelayBeforeEndMS =
testConfig.MSESegmentFetchDelayBeforeEndMS
if (!this.mediaSegments || !Array.isArray(this.mediaSegments)) {
Utils.failTest('Missing mediaSegments.');
return;
}
if (!this.mediaType) {
Utils.failTest('Missing mediaType.');
return;
}
if (this.MSESegmentDurationMS <= 0) {
Utils.failTest('Invalid MSESegmentDurationMS.');
return;
}
if (this.MSESegmentFetchDelayBeforeEndMS <= 0) {
Utils.failTest('Invalid MSESegmentFetchDelayBeforeEndMS.');
return;
}
this.mediaSource = new MediaSource();
this.video = document.querySelector("video");
this.video.src = URL.createObjectURL(this.mediaSource);
this.mediaSource.addEventListener("sourceopen",
this.onMediaSourceOpen.bind(this));
this.currentSegmentIndex = 0
}
onMediaSourceOpen() {
this.sourceBuffer = this.mediaSource.addSourceBuffer(this.mediaType);
this.sourceBuffer.addEventListener("updateend",
this.onSourceBufferUpdateEnd.bind(this));
// Trigger the first segment fetch
this.fetchNextSegmentAndAppend();
}
onSourceBufferUpdateEnd() {
this.sourceBuffer.timestampOffset += this.MSESegmentDurationMS/1000;
// The next segment should be fetched MSESegmentFetchDelayBeforeEndMS millis
// before the end of video play.
const total_duration = this.currentSegmentIndex*this.MSESegmentDurationMS;
setTimeout(this.fetchNextSegmentAndAppend.bind(this),
total_duration - (1000*this.video.currentTime) -
this.MSESegmentFetchDelayBeforeEndMS)
}
fetchNextSegmentAndAppend() {
if (this.currentSegmentIndex >= this.mediaSegments.length) {
this.mediaSource.endOfStream()
return;
}
const sourceBuffer = this.sourceBuffer;
const xhr = new XMLHttpRequest();
xhr.open('GET', this.mediaSegments[this.currentSegmentIndex++]);
xhr.responseType = 'arraybuffer';
xhr.addEventListener('load', function() {
sourceBuffer.appendBuffer(xhr.response);
});
xhr.send();
}
}
const MSEPlayerUtils = new MSEPlayerUtilsClass();