/*
|
* Buffer Controller
|
*/
|
/* eslint-disable */
|
import Event from "../events";
|
import EventHandler from "../event-handler";
|
|
class BufferController extends EventHandler {
|
constructor(wfs) {
|
super(wfs, Event.MEDIA_ATTACHING, Event.BUFFER_APPENDING, Event.BUFFER_RESET);
|
|
this.mediaSource = null;
|
this.media = null;
|
this.pendingTracks = {};
|
this.sourceBuffer = {};
|
this.segments = [];
|
|
this.appended = 0;
|
this._msDuration = null;
|
|
// Source Buffer listeners
|
this.onsbue = this.onSBUpdateEnd.bind(this);
|
|
this.browserType = 0;
|
if (navigator.userAgent.toLowerCase().indexOf("firefox") !== -1) {
|
this.browserType = 1;
|
}
|
this.mediaType = "H264Raw";
|
|
this.websocketName = undefined;
|
this.channelName = undefined;
|
this.cameraInfo = {};
|
}
|
|
destroy() {
|
EventHandler.prototype.destroy.call(this);
|
}
|
|
onMediaAttaching(data) {
|
let media = (this.media = data.media);
|
this.mediaType = data.mediaType;
|
this.websocketName = data.websocketName;
|
this.channelName = data.channelName;
|
this.cameraInfo = data.cameraInfo;
|
if (media) {
|
// setup the media source
|
var ms = (this.mediaSource = new MediaSource());
|
//Media Source listeners
|
this.onmso = this.onMediaSourceOpen.bind(this);
|
this.onmse = this.onMediaSourceEnded.bind(this);
|
this.onmsc = this.onMediaSourceClose.bind(this);
|
ms.addEventListener("sourceopen", this.onmso);
|
ms.addEventListener("sourceended", this.onmse);
|
ms.addEventListener("sourceclose", this.onmsc);
|
// link video and media Source
|
media.src = URL.createObjectURL(ms);
|
}
|
}
|
|
onMediaDetaching() {}
|
|
onBufferAppending(data) {
|
if (!this.segments) {
|
this.segments = [data];
|
} else {
|
this.segments.push(data);
|
}
|
this.doAppending();
|
}
|
|
onMediaSourceClose() {
|
// console.log('media source closed');
|
}
|
|
onMediaSourceEnded() {
|
console.log("media source ended");
|
}
|
|
onSBUpdateEnd(event) {
|
// Firefox
|
if (this.browserType === 1) {
|
this.mediaSource.endOfStream();
|
this.media.play();
|
}
|
|
this.appending = false;
|
this.doAppending();
|
this.updateMediaElementDuration();
|
}
|
|
updateMediaElementDuration() {}
|
|
onMediaSourceOpen() {
|
let mediaSource = this.mediaSource;
|
if (mediaSource) {
|
// once received, don't listen anymore to sourceopen event
|
mediaSource.removeEventListener("sourceopen", this.onmso);
|
}
|
|
if (this.mediaType === "FMp4") {
|
this.checkPendingTracks();
|
}
|
|
this.wfs.trigger(Event.MEDIA_ATTACHED, {
|
media: this.media,
|
channelName: this.channelName,
|
mediaType: this.mediaType,
|
websocketName: this.websocketName,
|
cameraInfo: this.cameraInfo
|
});
|
}
|
|
checkPendingTracks() {
|
this.createSourceBuffers({ tracks: "video", mimeType: "" });
|
this.pendingTracks = {};
|
}
|
|
onBufferReset(data) {
|
if (this.mediaType === "H264Raw") {
|
this.createSourceBuffers({ tracks: "video", mimeType: data.mimeType });
|
}
|
}
|
|
createSourceBuffers(tracks) {
|
var sourceBuffer = this.sourceBuffer,
|
mediaSource = this.mediaSource;
|
let mimeType;
|
if (tracks.mimeType === "") {
|
mimeType = "video/mp4;codecs=avc1.420028"; // avc1.42c01f avc1.42801e avc1.640028 avc1.420028
|
} else {
|
mimeType = "video/mp4;codecs=" + tracks.mimeType;
|
}
|
|
try {
|
let sb = (sourceBuffer["video"] = mediaSource.addSourceBuffer(mimeType));
|
sb.addEventListener("updateend", this.onsbue);
|
track.buffer = sb;
|
} catch (err) {}
|
this.wfs.trigger(Event.BUFFER_CREATED, { tracks: tracks });
|
this.media.play();
|
}
|
|
doAppending() {
|
var wfs = this.wfs,
|
sourceBuffer = this.sourceBuffer,
|
segments = this.segments;
|
if (Object.keys(sourceBuffer).length) {
|
if (this.media.error) {
|
this.segments = [];
|
// console.log(
|
// 'trying to append although a media error occured, flush segment and abort'
|
// );
|
return;
|
}
|
if (this.appending) {
|
return;
|
}
|
|
wfs.playerStatus = 1;
|
|
if (segments && segments.length) {
|
var segment = segments.shift();
|
try {
|
if (sourceBuffer[segment.type]) {
|
this.parent = segment.parent;
|
sourceBuffer[segment.type].appendBuffer(segment.data);
|
this.appendError = 0;
|
this.appended++;
|
this.appending = true;
|
} else {
|
}
|
} catch (err) {
|
// in case any error occured while appending, put back segment in segments table
|
segments.unshift(segment);
|
// var event = { type: ErrorTypes.MEDIA_ERROR };
|
// if (err.code !== 22) {
|
// if (this.appendError) {
|
// this.appendError++;
|
// } else {
|
// this.appendError = 1;
|
// }
|
// event.details = ErrorDetails.BUFFER_APPEND_ERROR;
|
// event.frag = this.fragCurrent;
|
// if (this.appendError > wfs.config.appendErrorMaxRetry) {
|
// segments = [];
|
// event.fatal = true;
|
// return;
|
// } else {
|
// event.fatal = false;
|
// }
|
// } else {
|
// this.segments = [];
|
// event.details = ErrorDetails.BUFFER_FULL_ERROR;
|
// return;
|
// }
|
}
|
}
|
}
|
}
|
}
|
|
export default BufferController;
|