bonc-htmlplayer
Advanced tools
Comparing version 1.0.22 to 1.0.23
{ | ||
"name": "bonc-htmlplayer", | ||
"version": "1.0.22", | ||
"version": "1.0.23", | ||
"description": "东方国信的html播放器内核", | ||
@@ -5,0 +5,0 @@ "main": "./dist/BoncH5Player.js", |
@@ -1,2 +0,2 @@ | ||
import './libffmpeg_264_265.js'; | ||
// import './libffmpeg_264_265.js'; | ||
import WebGLPlayer from './webgl'; | ||
@@ -7,2 +7,3 @@ import localRecorder from '../util/webmdownload/webmdownload'; | ||
import AudioPlayer from './audio'; | ||
import ByteArray from '../util/ByteArray'; | ||
@@ -20,13 +21,16 @@ class H265CanvasPlayer { | ||
this.info = { | ||
_timeStempAudio : 0, | ||
audioseg:0 | ||
_timeStempAudio: 0, | ||
audioseg: 0 | ||
}; | ||
this.isStart = false | ||
this.modulestart = null; | ||
this.initialized = false | ||
this.naltypeObj = {} | ||
if (audioNode) { | ||
this.nalsbonAudioarr = new Proxy(this.bufferArray,{ | ||
get(target, property){ | ||
this.nalsbonAudioarr = new Proxy(this.bufferArray, { | ||
get(target, property) { | ||
return target[property] | ||
}, | ||
set(target, property, value){ | ||
set(target, property, value) { | ||
target[property] = value; | ||
@@ -41,12 +45,20 @@ loadNextBuffer() | ||
audioNode, | ||
nalsbonAudioarr:this.bufferArray, | ||
info:this.info | ||
nalsbonAudioarr: this.bufferArray, | ||
info: this.info | ||
}); | ||
var loadNextBuffer = this.audioPlayer.loadNextBuffer | ||
} | ||
setTimeout(() => { | ||
// import('./libffmpeg_264_265.js').then(res=>{}) | ||
self.Module = { | ||
locateFile: function (wasm) { | ||
return wasm; | ||
} | ||
} | ||
var scriptNode = document.createElement('script') | ||
scriptNode.src = './libffmpeg_264_265.js' | ||
document.querySelector('body').appendChild(scriptNode) | ||
Module.onRuntimeInitialized = () => { | ||
var _this = this | ||
this.videoCallback = Module.addFunction(function (addr_y, addr_u, addr_v, stride_y, stride_u, stride_v, width, height, pts, id) { | ||
let size = width * height + (width / 2) * (height / 2) + (width / 2) * (height / 2) | ||
@@ -81,75 +93,127 @@ let data = new Uint8Array(size) | ||
} | ||
// 处理音频 | ||
if(!this.isStart){ | ||
if (!this.isStart) { | ||
this.isStart = true; | ||
this.app.dispatch('startSuccess') | ||
} | ||
_this.displayVideoFrame(obj); | ||
}) | ||
this.modulestart = Module._openDecoder(1, this.videoCallback, 0) | ||
} | ||
} | ||
this.displayVideoFrame(obj); | ||
}.bind(this)); | ||
handleAudio() { | ||
this.audioPlayer.loadNextBuffer(this.bufferArray) | ||
} | ||
playBuffer(videoBuffer) { | ||
// debugger | ||
if (this.modulestart !== 0) { | ||
return | ||
} | ||
// console.log(videoBuffer) | ||
// var typedArray = new Uint8Array(videoBuffer); | ||
var h265Buffer = new ByteArray(videoBuffer) | ||
h265Buffer.offset += 4 | ||
var nalu = h265Buffer.ReadUint16() | ||
// F位 | ||
var F = nalu >> 15 | ||
// console.log('F', F) | ||
// naltype | ||
var naltype = (nalu >> 9) & 127 | ||
// console.log('naltype', naltype) | ||
/** | ||
1 NAL_UNIT_CODED_SLICE_TRAIL_R | ||
19 NAL_UNIT_CODED_SLICE_IDR | ||
32 NAL_UNIT_VPS | ||
33 NAL_UNIT_SPS | ||
34 NAL_UNIT_PPS | ||
39 NAL_UNIT_SEI | ||
*/ | ||
// 如果已经初始化并且是关键帧或非关键帧 | ||
if (this.initialized && (naltype == 1 || naltype == 19)) { | ||
try { | ||
var typedArray = new Uint8Array(videoBuffer); | ||
var size = typedArray.length; | ||
var cacheBuffer = Module._malloc(size); | ||
Module.HEAPU8.set(typedArray, cacheBuffer); | ||
var ret = Module._decodeData(cacheBuffer, size, this.pts++, 1); | ||
} catch { } | ||
if (cacheBuffer != null) { | ||
Module._free(cacheBuffer); | ||
cacheBuffer = null; | ||
} | ||
} else if (naltype !== 1 && naltype != 19) { | ||
// 如果没有初始化 并且不是关键帧或非关键帧 | ||
if (!this.naltypeObj[naltype]) { | ||
this.naltypeObj[naltype] = true | ||
try { | ||
var typedArray = new Uint8Array(videoBuffer); | ||
var size = typedArray.length; | ||
var cacheBuffer = Module._malloc(size); | ||
Module.HEAPU8.set(typedArray, cacheBuffer); | ||
var ret = Module._decodeData(cacheBuffer, size, this.pts++, 1); | ||
} catch { } | ||
if (cacheBuffer != null) { | ||
Module._free(cacheBuffer); | ||
cacheBuffer = null; | ||
} | ||
} | ||
if (Object.keys(this.naltypeObj).length == 4) { | ||
this.initialized = true | ||
} | ||
} | ||
// console.log(nalu) | ||
// debugger | ||
// var size = typedArray.length; | ||
// var cacheBuffer = Module._malloc(size); | ||
// Module.HEAPU8.set(typedArray, cacheBuffer); | ||
// // console.time('decode') | ||
//0 h264 1 h265 | ||
var ret = Module._openDecoder(1, this.videoCallback, 0) | ||
// if(size < CHUNK_SIZE) { | ||
// console.log('Flush frame data') | ||
// Module._flushDecoder(); | ||
// Module._closeDecoder(); | ||
// } | ||
} | ||
// console.log('ret',ret)//0 代表成功 非0 代表失败 | ||
}, 3000); | ||
} | ||
handleAudio() { | ||
this.audioPlayer.loadNextBuffer(this.bufferArray) | ||
} | ||
playBuffer(videoBuffer) { | ||
var typedArray = new Uint8Array(videoBuffer); | ||
var size = typedArray.length; | ||
var cacheBuffer = Module._malloc(size); | ||
Module.HEAPU8.set(typedArray, cacheBuffer); | ||
// console.time('decode') | ||
try { | ||
var ret = Module._decodeData(cacheBuffer, size, this.pts++, 1); | ||
} catch { } | ||
if (cacheBuffer != null) { | ||
Module._free(cacheBuffer); | ||
cacheBuffer = null; | ||
displayVideoFrame(obj) { | ||
var data = new Uint8Array(obj.data); | ||
var width = obj.width; | ||
var height = obj.height; | ||
var yLength = width * height; | ||
var uvLength = (width / 2) * (height / 2); | ||
if (!this.webglPlayer) { | ||
const canvasId = this.canvasId; | ||
var canvas = document.getElementById(canvasId); | ||
this.webglPlayer = new WebGLPlayer(canvas, { | ||
preserveDrawingBuffer: true | ||
}); | ||
} | ||
this.webglPlayer.renderFrame(data, width, height, yLength, uvLength); | ||
} | ||
// if(size < CHUNK_SIZE) { | ||
// console.log('Flush frame data') | ||
// Module._flushDecoder(); | ||
// Module._closeDecoder(); | ||
// } | ||
} | ||
displayVideoFrame(obj) { | ||
var data = new Uint8Array(obj.data); | ||
var width = obj.width; | ||
var height = obj.height; | ||
var yLength = width * height; | ||
var uvLength = (width / 2) * (height / 2); | ||
if (!this.webglPlayer) { | ||
const canvasId = this.canvasId; | ||
var canvas = document.getElementById(canvasId); | ||
this.webglPlayer = new WebGLPlayer(canvas, { | ||
preserveDrawingBuffer: true | ||
}); | ||
localRecord(name) { | ||
this.recoder.startRecord(name) | ||
} | ||
this.webglPlayer.renderFrame(data, width, height, yLength, uvLength); | ||
finishRecord() { | ||
this.recoder.endRecord(); | ||
} | ||
destroy() { | ||
// 清除画布 | ||
this.webglPlayer && this.webglPlayer.clear(); | ||
this.isStart = false; | ||
// this.modulestart | ||
} | ||
muted() { | ||
this.audioPlayer.audioNode.muted = !this.audioPlayer.audioNode.muted; | ||
return this.audioPlayer.audioNode.muted; | ||
} | ||
setVolume(volume) { | ||
this.audioPlayer.audioNode.volume = volume; | ||
} | ||
} | ||
localRecord(name) { | ||
this.recoder.startRecord(name) | ||
} | ||
finishRecord() { | ||
this.recoder.endRecord(); | ||
} | ||
destroy() { | ||
// 清除画布 | ||
this.webglPlayer.clear(); | ||
this.isStart = false | ||
} | ||
} | ||
export default H265CanvasPlayer | ||
export default H265CanvasPlayer |
@@ -27,3 +27,3 @@ function Texture(gl) { | ||
function WebGLPlayer(canvas, options) { | ||
this.gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); | ||
this.gl = canvas.getContext("webgl",options) || canvas.getContext("experimental-webgl",options); | ||
this.initGL(options); | ||
@@ -30,0 +30,0 @@ } |
@@ -237,3 +237,2 @@ import { ExpGolomb } from '../../util/exp-golomb.js'; | ||
var config = H264Parser.readSPS(new Uint8Array(sps)); | ||
this.track.width = config.width; | ||
@@ -243,3 +242,2 @@ this.track.height = config.height; | ||
this.track.codec = 'avc1.'; | ||
let codecarray = new DataView(sps.buffer, sps.byteOffset + 1, 4); | ||
@@ -246,0 +244,0 @@ for (let i = 0; i < 3; ++i) { |
@@ -111,5 +111,12 @@ import Event from './util/event'; | ||
case 'H265': | ||
console.log('实例化h265') | ||
this._h265player = this._h265player || new H265CanvasPlayer(this,this.configs); | ||
this._player = this._h265player | ||
// 判断是否可以实例化h265 | ||
if(this.validateH265()){ | ||
console.log('实例化h265') | ||
this._h265player = this._h265player || new H265CanvasPlayer(this,this.configs); | ||
this._player = this._h265player | ||
}else{ | ||
this.closeVideo('normal') | ||
this.dispatch('error','h265视频仅允许1路') | ||
} | ||
break; | ||
@@ -523,3 +530,3 @@ case 'H264': | ||
videoBufferAdd(videoBuffer) { | ||
//this.H264Mp4Player.playBuffer(videoBuffer); | ||
// this.H264Mp4Player.playBuffer(videoBuffer); | ||
// this.H264CanvasPlayer.playBuffer(videoBuffer); | ||
@@ -534,6 +541,23 @@ if (this.reverse) { | ||
} | ||
/** | ||
* 判断是否是h265 | ||
* @returns Boolean | ||
*/ | ||
isH265(){ | ||
return this._player instanceof H265CanvasPlayer | ||
} | ||
/** | ||
* 判断h265是否可以允许播放,对于多路视频而言h265视频只允许播放一路 | ||
* @returns Boolean | ||
*/ | ||
validateH265(){ | ||
if(this.validateH265out){ | ||
// validateH265out函数通过外部实例化类的时候绑定,如果没有绑定的话返回true | ||
return !this.validateH265out(); | ||
}else{ | ||
return true; | ||
} | ||
} | ||
} | ||
export default Html5Player; |
@@ -63,2 +63,3 @@ export class NALU { | ||
getData() { | ||
// debugger | ||
const result = new Uint8Array(this.getSize()); | ||
@@ -65,0 +66,0 @@ const view = new DataView(result.buffer); |
@@ -158,3 +158,2 @@ import ByteArray from './ByteArray'; | ||
// 验证是否具备h265解码的功能 | ||
this.app.dispatch('onGetVideoCode','H265'); | ||
@@ -161,0 +160,0 @@ this.app.dispatch('h265Info',{ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
7367741
43
25431
4
9