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
|
// This is similar to mediasource-worker-play.js, except that the buffering is
// longer and done in tiny chunks to enable a better chance of the main thread
// detaching the element while interesting buffering work is still occurring. To
// assist the main thread understanding when the buffering has started already
// or has completed already, we also perform extra messaging.
importScripts("mediasource-worker-util.js");
onmessage = function(evt) {
postMessage({ subject: messageSubject.ERROR, info: "No message expected by Worker" });
};
let util = new MediaSourceWorkerUtil();
let sentStartedBufferingMessage = false;
util.mediaSource.addEventListener("sourceopen", () => {
let sourceBuffer;
try {
sourceBuffer = util.mediaSource.addSourceBuffer(util.mediaMetadata.type);
} catch(e) {
// Detachment may have already begun, so allow exception here.
// TODO(https://crbug.com/878133): Consider a distinct readyState for the case
// where exception occurs due to "Worker MediaSource attachment is closing".
// That would assist API users and narrow the exception handling here.
return;
}
sourceBuffer.onerror = (err) => {
postMessage({ subject: messageSubject.ERROR, info: err });
};
util.mediaLoadPromise.then(mediaData => bufferInto(sourceBuffer, mediaData, 100, 0),
err => { postMessage({ subject: messageSubject.ERROR, info: err }) } );
}, { once : true });
let handle = util.mediaSource.handle;
postMessage({ subject: messageSubject.HANDLE, info: handle }, { transfer: [handle] } );
// Append increasingly large pieces at a time, starting/continuing at |position|.
// This allows buffering the test media without timeout, but also with enough
// operations to gain coverage on detachment concurrency with append.
function bufferInto(sourceBuffer, mediaData, appendSize, position) {
if (position >= mediaData.byteLength) {
postMessage({ subject: messageSubject.FINISHED_BUFFERING });
try {
util.mediaSource.endOfStream();
} catch(e) {
// Detachment may have already begun, so allow exception here.
// TODO(https://crbug.com/878133): Consider a distinct readyState for the case
// where exception occurs due to "Worker MediaSource attachment is closing".
// That would assist API users and narrow the exception handling here.
// FALL-THROUGH - return.
}
return;
}
var nextPosition = position + appendSize;
const pieceToAppend = mediaData.slice(position, nextPosition);
position = nextPosition;
appendSize += 100;
sourceBuffer.addEventListener("updateend", () => {
if (!sentStartedBufferingMessage) {
postMessage({ subject: messageSubject.STARTED_BUFFERING});
sentStartedBufferingMessage = true;
}
bufferInto(sourceBuffer, mediaData, appendSize, position);
}, { once : true });
try {
sourceBuffer.appendBuffer(pieceToAppend);
} catch(e) {
// Detachment may have already begun, so allow exception here.
// TODO(https://crbug.com/878133): Consider a distinct readyState for the case
// where exception occurs due to "Worker MediaSource attachment is closing".
// That would assist API users and narrow the exception handling here.
// FALL-THROUGH - return.
}
}
|