@jxstjh/jhvideo
Version:
HTML5 jhvideo base on MPEG2-TS Stream Player
181 lines • 6.81 kB
JavaScript
/*
* Copyright (C) 2016 Bilibili. All Rights Reserved.
*
* @author zheng qian <xqq@xqq.im>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { BaseLoader, LoaderStatus, LoaderErrors } from './loader.js';
import { RuntimeException } from '../utils/exception.js';
// For MPEG-TS/FLV over WebSocket live stream
var WebSocketLoader = /** @class */ (function (_super) {
__extends(WebSocketLoader, _super);
function WebSocketLoader() {
var _this = _super.call(this, 'websocket-loader') || this;
_this.TAG = 'WebSocketLoader';
_this._needStash = true;
_this._ws = null;
_this._requestAbort = false;
_this._receivedLength = 0;
_this._lastCmd = null;
return _this;
}
WebSocketLoader.isSupported = function () {
try {
return (typeof self.WebSocket !== 'undefined');
}
catch (e) {
return false;
}
};
WebSocketLoader.prototype.destroy = function () {
if (this._ws) {
this.abort();
}
_super.prototype.destroy.call(this);
};
WebSocketLoader.prototype.open = function (dataSource) {
try {
var ws = this._ws = new self.WebSocket(dataSource.url);
ws.binaryType = 'arraybuffer';
ws.onopen = this._onWebSocketOpen.bind(this);
ws.onclose = this._onWebSocketClose.bind(this);
ws.onmessage = this._onWebSocketMessage.bind(this);
ws.onerror = this._onWebSocketError.bind(this);
this._status = LoaderStatus.kConnecting;
}
catch (e) {
this._status = LoaderStatus.kError;
var info = { code: e.code, msg: e.message };
if (this._onError) {
this._onError(LoaderErrors.EXCEPTION, info);
}
else {
throw new RuntimeException(info.msg);
}
}
};
WebSocketLoader.prototype.abort = function () {
var ws = this._ws;
if (ws && (ws.readyState === 0 || ws.readyState === 1)) { // CONNECTING || OPEN
this._requestAbort = true;
ws.close();
}
this._ws = null;
this._status = LoaderStatus.kComplete;
};
WebSocketLoader.prototype._onWebSocketOpen = function (e) {
this._status = LoaderStatus.kBuffering;
};
WebSocketLoader.prototype._onWebSocketClose = function (e) {
if (this._requestAbort === true) {
this._requestAbort = false;
return;
}
this._status = LoaderStatus.kComplete;
if (this._onComplete) {
this._onComplete(0, this._receivedLength - 1);
}
};
WebSocketLoader.prototype._onWebSocketMessage = function (e) {
var _this = this;
var data = e.data;
if (data instanceof ArrayBuffer) {
if (e.data instanceof ArrayBuffer) {
this._dispatchArrayBuffer(e.data);
}
else if (e.data instanceof Blob) {
var reader_1 = new FileReader();
reader_1.onload = function () {
_this._dispatchArrayBuffer(reader_1.result);
};
reader_1.readAsArrayBuffer(e.data);
}
else {
this._status = LoaderStatus.kError;
var info = { code: -1, msg: 'Unsupported WebSocket message type: ' + e.data.constructor.name };
if (this._onError) {
this._onError(LoaderErrors.EXCEPTION, info);
}
else {
throw new RuntimeException(info.msg);
}
}
}
else if (typeof data === 'string') {
// TODO海康接口返回数据兼容性写法
this._handleInteract(data);
// this.onError(LoaderErrors.STRING_DATA, data)
}
};
/**
* 交互信息处理
* @param {*} strData
*/
WebSocketLoader.prototype._handleInteract = function (strData) {
var jsonData = JSON.parse(strData);
if (jsonData.hasOwnProperty('errorCode')) { // 交互消息
var errorCode = jsonData.errorCode, errorMsg = jsonData.errorMsg;
if (parseInt(errorCode) !== 0) {
var errorCodeHex = '0x0' + errorCode.toString(16);
this.onError(LoaderErrors.STRING_DATA, errorCodeHex);
// console.error(errorCode,errorMsg)
}
else {
this.onInformation(LoaderErrors.JSON_DATA, jsonData);
}
}
else {
this.onInformation(LoaderErrors.JSON_DATA, jsonData);
}
};
WebSocketLoader.prototype._dispatchArrayBuffer = function (arraybuffer) {
var chunk = arraybuffer;
var byteStart = this._receivedLength;
this._receivedLength += chunk.byteLength;
if (this._onDataArrival) {
this._onDataArrival(chunk, byteStart, this._receivedLength);
}
};
WebSocketLoader.prototype._onWebSocketError = function (e) {
this._status = LoaderStatus.kError;
var info = {
code: e.code,
msg: e.message
};
if (this._onError) {
this._onError(LoaderErrors.EXCEPTION, info);
}
else {
throw new RuntimeException(info.msg);
}
};
return WebSocketLoader;
}(BaseLoader));
export default WebSocketLoader;
//# sourceMappingURL=websocket-loader.js.map