Files
ArtPlayer/packages/artplayer/src/mse.js
T
2018-11-24 17:08:36 +08:00

86 lines
2.7 KiB
JavaScript

import { errorHandle, getExt } from './utils';
import config from './config';
export default class Mse {
constructor(art) {
this.art = art;
if (art.option.mse) {
this.init();
}
}
init() {
const { player, events } = this.art;
this.setMimeCodec();
Object.defineProperty(player, 'returnUrl', {
value: () => {
this.mediaSource = new MediaSource();
const url = URL.createObjectURL(this.mediaSource);
this.eventBind();
events.destroyEvents.push(() => {
URL.revokeObjectURL(url);
});
return url;
},
});
}
setMimeCodec() {
const { option } = this.art;
if (!option.type) {
const type = getExt(option.url);
errorHandle(
Object.keys(config.mimeCodec).includes(type),
`Can't find video's type '${type}' from '${option.url}'`,
);
option.type = type;
}
if (!option.mimeCodec) {
const mimeCodec = config.mimeCodec[option.type];
errorHandle(mimeCodec, `Can't find video's mimeCodec from ${option.type}`);
option.mimeCodec = mimeCodec;
}
errorHandle(
'MediaSource' in window && MediaSource.isTypeSupported(option.mimeCodec),
`Unsupported MIME type or codec: ${option.mimeCodec}`,
);
}
eventBind() {
const {
option,
events: { proxy },
} = this.art;
const { mediaSource, sourceBufferList, sourceBuffer } = config.mse;
mediaSource.events.forEach(eventName => {
proxy(this.mediaSource, eventName, event => {
this.art.emit(`mediaSource:${event.type}`, event);
});
});
sourceBufferList.events.forEach(eventName => {
proxy(this.mediaSource.sourceBuffers, eventName, event => {
this.art.emit(`sourceBuffers:${event.type}`, event);
});
proxy(this.mediaSource.activeSourceBuffers, eventName, event => {
this.art.emit(`activeSourceBuffers:${event.type}`, event);
});
});
this.art.on('mediaSource:sourceopen', () => {
this.sourceBuffer = this.mediaSource.addSourceBuffer(option.mimeCodec);
sourceBuffer.events.forEach(eventName => {
proxy(this.sourceBuffer, eventName, event => {
this.art.emit(`sourceBuffer:${event.type}`, event);
});
});
});
this.art.on('sourceBuffer:updateend', () => {
this.mediaSource.endOfStream();
});
}
}