Media Source Extensions 中 "update" 和 "updateend" 事件的区别
Difference between "update" and "updateend" events in Media Source Extensions
任何人都可以解释两个 SourceBuffer
事件之间的区别以及何时使用一个而不是另一个吗? W3C spec 让我感到困惑,因为它读起来像同一件事("completed" vs "ended"):
- 更新 - 添加或移除已成功完成
- updateend - 添加或删除已结束。
使用下面的代码进行测试。 Chrome 触发 error
事件,Firefox 不会:
const tests = {
// 64K of invalid bytes
'Invalid Bytes': new Int8Array(1024 * 64),
// valid WebM Opus header bytes (from a random file)
'Valid Header Bytes': new Uint8Array([26,69,223,163,1,0,0,0,0,0,0,31,66,134,129,1,66,247,129,1,66,242,129,4,66,243,129,8,66,130,132,119,101,98,109,66,135,129,4,66,133,129,2,24,83,128,103,1,0,0,0,0,0,217,18,17,77,155,116,64,29,77,187,139,83,171,132,21,73,169,102,83,172,129,223,77,187,140,83,171,132,22,84,174,107,83,172,130,1,48,236,1,0,0,0,0,0,0,179,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,73,169,102,1,0,0,0,0,0,0,69,42,215,177,131,15,66,64,77,128,141,76,97,118,102,53,54,46,52,48,46,49,48,49,87,65,141,76,97,118,102,53,54,46,52,48,46,49,48,49,115,164,144,52,234,234,126,227,12,45,154,239,221,105,21,212,101,42,213,68,137,136,64,184,70,0,0,0,0,0,22,84,174,107,1,0,0,0,0,0,0,98,174,1,0,0,0,0,0,0,89,215,129,1,115,197,129,1,156,129,0,34,181,156,131,117,110,100,134,134,65,95,79,80,85,83,86,170,131,99,46,160,86,187,132,4,196,180,0,131,129,2,225,1,0,0,0,0,0,0,17,159,129,2,181,136,64,231,112,0,0,0,0,0,98,100,129,16,99,162,147,79,112,117,115,72,101,97,100,1,2,56,1,128,187,0,0,0,0,0])
};
(async () => {
for (let testName of Object.keys(tests)) {
console.group(testName);
await testSourceBuffer(tests[testName])
console.groupEnd();
};
console.log('All tests done!');
})()
async function testSourceBuffer(byteArray) {
return new Promise(resolve => {
const audio = new Audio();
const mediaSource = new MediaSource();
// debug other MediaSource Events
['sourceended', 'sourceclose'].forEach(name => {
mediaSource.addEventListener(name, e => {
console.log('MediaSource', e.type);
if (e.type === 'sourceended') {
resolve();
}
})
})
mediaSource.onsourceopen = e => {
console.log('MediaSource', e.type);
URL.revokeObjectURL(audio.src);
const sourceBuffer = mediaSource.addSourceBuffer('audio/webm; codecs=opus');
// debug SoruceBuffer events
['abort', 'error', 'update', 'updateend', 'updatestart'].forEach(name => {
sourceBuffer.addEventListener(name, e => {
const color = e.type === 'error'? 'color: red' : ''
console.log(`%cSourceBuffer ${name}`, color);
if (e.type === 'updateend') {
if (mediaSource.readyState === 'open') {
mediaSource.endOfStream();
}
}
})
})
sourceBuffer.appendBuffer(byteArray);
}
audio.src = URL.createObjectURL(mediaSource)
});
}
区别在于完成的成功。
update
事件仅在 append or removal operations did succeed, while updateend
is also fired when there has been an error while appending, or when the operation has been aborted.
任何人都可以解释两个 SourceBuffer
事件之间的区别以及何时使用一个而不是另一个吗? W3C spec 让我感到困惑,因为它读起来像同一件事("completed" vs "ended"):
- 更新 - 添加或移除已成功完成
- updateend - 添加或删除已结束。
使用下面的代码进行测试。 Chrome 触发 error
事件,Firefox 不会:
const tests = {
// 64K of invalid bytes
'Invalid Bytes': new Int8Array(1024 * 64),
// valid WebM Opus header bytes (from a random file)
'Valid Header Bytes': new Uint8Array([26,69,223,163,1,0,0,0,0,0,0,31,66,134,129,1,66,247,129,1,66,242,129,4,66,243,129,8,66,130,132,119,101,98,109,66,135,129,4,66,133,129,2,24,83,128,103,1,0,0,0,0,0,217,18,17,77,155,116,64,29,77,187,139,83,171,132,21,73,169,102,83,172,129,223,77,187,140,83,171,132,22,84,174,107,83,172,130,1,48,236,1,0,0,0,0,0,0,179,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,73,169,102,1,0,0,0,0,0,0,69,42,215,177,131,15,66,64,77,128,141,76,97,118,102,53,54,46,52,48,46,49,48,49,87,65,141,76,97,118,102,53,54,46,52,48,46,49,48,49,115,164,144,52,234,234,126,227,12,45,154,239,221,105,21,212,101,42,213,68,137,136,64,184,70,0,0,0,0,0,22,84,174,107,1,0,0,0,0,0,0,98,174,1,0,0,0,0,0,0,89,215,129,1,115,197,129,1,156,129,0,34,181,156,131,117,110,100,134,134,65,95,79,80,85,83,86,170,131,99,46,160,86,187,132,4,196,180,0,131,129,2,225,1,0,0,0,0,0,0,17,159,129,2,181,136,64,231,112,0,0,0,0,0,98,100,129,16,99,162,147,79,112,117,115,72,101,97,100,1,2,56,1,128,187,0,0,0,0,0])
};
(async () => {
for (let testName of Object.keys(tests)) {
console.group(testName);
await testSourceBuffer(tests[testName])
console.groupEnd();
};
console.log('All tests done!');
})()
async function testSourceBuffer(byteArray) {
return new Promise(resolve => {
const audio = new Audio();
const mediaSource = new MediaSource();
// debug other MediaSource Events
['sourceended', 'sourceclose'].forEach(name => {
mediaSource.addEventListener(name, e => {
console.log('MediaSource', e.type);
if (e.type === 'sourceended') {
resolve();
}
})
})
mediaSource.onsourceopen = e => {
console.log('MediaSource', e.type);
URL.revokeObjectURL(audio.src);
const sourceBuffer = mediaSource.addSourceBuffer('audio/webm; codecs=opus');
// debug SoruceBuffer events
['abort', 'error', 'update', 'updateend', 'updatestart'].forEach(name => {
sourceBuffer.addEventListener(name, e => {
const color = e.type === 'error'? 'color: red' : ''
console.log(`%cSourceBuffer ${name}`, color);
if (e.type === 'updateend') {
if (mediaSource.readyState === 'open') {
mediaSource.endOfStream();
}
}
})
})
sourceBuffer.appendBuffer(byteArray);
}
audio.src = URL.createObjectURL(mediaSource)
});
}
区别在于完成的成功。
update
事件仅在 append or removal operations did succeed, while updateend
is also fired when there has been an error while appending, or when the operation has been aborted.