fix: BUG修改
This commit is contained in:
parent
b65edd63f4
commit
84f349d306
@ -134,9 +134,9 @@ const columns: ColumnProps[] = [
|
||||
}
|
||||
},
|
||||
{ prop: "phaseName", label: "智能条线", width: 150 },
|
||||
{ prop: "chargerNumber", label: "节点责任人", width: 150 },
|
||||
{ prop: "chargerPhone", label: "负责人联系方式", width: 180 },
|
||||
// { prop: "chargerName", label: "节点责任人", width: 150 },
|
||||
// { prop: "chargerNumber", label: "节点责任人", width: 150 },
|
||||
// { prop: "chargerPhone", label: "负责人联系方式", width: 180 },
|
||||
{ prop: "chargerName", label: "节点责任人", width: 150 },
|
||||
{
|
||||
prop: "isDeleted",
|
||||
label: "节点失效标记",
|
||||
@ -251,17 +251,15 @@ const formConfig = {
|
||||
{
|
||||
label: "节点负责人",
|
||||
prop: "chargerNumber",
|
||||
type: "select",
|
||||
data: [],
|
||||
clearable: true,
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: "负责人联系方式",
|
||||
prop: "chargerNumber",
|
||||
type: "input",
|
||||
disabled: true
|
||||
}
|
||||
// {
|
||||
// label: "负责人联系方式",
|
||||
// prop: "chargerNumber",
|
||||
// type: "input",
|
||||
// disabled: true
|
||||
// }
|
||||
],
|
||||
rules: {
|
||||
nodeNumber: [
|
||||
|
||||
@ -42,7 +42,6 @@ import { ElMessage, ElMessageBox, ElStep } from "element-plus";
|
||||
import { getVideoQuestionPage, getvideoProTreeList, getvideoEngTreeList, addmonitorQuestion } from "@/api/modules/goverment";
|
||||
import { getpreviewURL, getmanualCaptureL, getpreviewURLS, getConfigInfo } from "@/api/modules/common";
|
||||
import TreeFilter from "@/components/TreeFilter/index.vue";
|
||||
import "./h5player.min.js";
|
||||
|
||||
interface rightFormList {
|
||||
createTime: string;
|
||||
@ -95,17 +94,17 @@ const playVideo = async () => {
|
||||
.JS_Play(
|
||||
url,
|
||||
{
|
||||
url, // 流媒体播放时必传
|
||||
playURL: url, // 流媒体播放时必传
|
||||
mode: 1 // 解码类型:0=普通模式; 1=高级模式 默认为0
|
||||
// 设置直连时的认证参数等
|
||||
// ...
|
||||
},
|
||||
0 //当前窗口下标
|
||||
playIndex.value //当前窗口下标
|
||||
)
|
||||
.then(
|
||||
() => {
|
||||
console.info("JS_Play success");
|
||||
// playIndex.value += 1;
|
||||
playIndex.value += 1;
|
||||
// do you want...
|
||||
},
|
||||
() => {
|
||||
@ -127,8 +126,8 @@ const BeginPlayer = () => {
|
||||
// 初始化插件
|
||||
myPlugin.value = new JSPlugin({
|
||||
szId: "play_window", //需要英文字母开头 必填
|
||||
// szBasePath: "/public/h5player", // 必填,引用H5player.min.js的js相对路径
|
||||
szBasePath: "./h5player.min.js", // 必填,引用H5player.min.js的js相对路径
|
||||
szBasePath: "/public/h5player", // 必填,引用H5player.min.js的js相对路径
|
||||
// szBasePath: "./", // 必填,引用H5player.min.js的js相对路径
|
||||
iWidth: playWndWidth.value + "px",
|
||||
iHeight: playWndHeight.value + "px",
|
||||
iMaxSplit: 4,
|
||||
@ -235,9 +234,11 @@ onMounted(async () => {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "./index.scss";
|
||||
|
||||
:deep(.btn-prev) {
|
||||
border: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
:deep(.btn-next) {
|
||||
border: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
@ -0,0 +1,225 @@
|
||||
/**
|
||||
* Created by wangweijie5 on 2016/12/16.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var __instance = function () {
|
||||
var instance = void 0;
|
||||
return function (newInstance) {
|
||||
if (newInstance) instance = newInstance;
|
||||
return instance;
|
||||
};
|
||||
}();
|
||||
|
||||
var AudioRenderer = function () {
|
||||
function AudioRenderer() {
|
||||
_classCallCheck(this, AudioRenderer);
|
||||
|
||||
if (__instance()) return __instance();
|
||||
|
||||
// 确保只有单例
|
||||
if (AudioRenderer.unique !== undefined) {
|
||||
return AudioRenderer.unique;
|
||||
}
|
||||
|
||||
AudioRenderer.unique = this;
|
||||
|
||||
this.oAudioContext = null;
|
||||
this.currentVolume = 0.8; // 初始音量
|
||||
this.bSetVolume = false;
|
||||
this.gainNode = null;
|
||||
this.iWndNum = -1; // 窗口号
|
||||
this.mVolumes = new Map(); // 用于存储所有音量
|
||||
|
||||
// Init AudioContext
|
||||
var AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||
this.oAudioContext = new AudioContext();
|
||||
|
||||
this.writeString = function (view, offset, string) {
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
view.setUint8(offset + i, string.charCodeAt(i));
|
||||
}
|
||||
};
|
||||
|
||||
this.setBufferToDataview = function (output, offset, input) {
|
||||
for (var i = 0; i < input.length; i++, offset++) {
|
||||
output.setUint8(offset, input[i]);
|
||||
}
|
||||
};
|
||||
|
||||
__instance(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @synopsis 音频播放
|
||||
*
|
||||
* @param dataBuf [IN] 音频缓存
|
||||
* @param dataLen [IN] 缓存长度
|
||||
* @param audioInfo [IN] 音频参数
|
||||
*
|
||||
* @returns 状态码
|
||||
*/
|
||||
|
||||
|
||||
_createClass(AudioRenderer, [{
|
||||
key: 'Play',
|
||||
value: function Play(dataBuf, dataLen, audioInfo) {
|
||||
var bufferData = new ArrayBuffer(44 + dataLen);
|
||||
var viewTalk = new DataView(bufferData);
|
||||
var sampleRates = audioInfo.samplesPerSec;
|
||||
var channels = audioInfo.channels;
|
||||
var bitsPerSample = audioInfo.bitsPerSample;
|
||||
|
||||
//console.log("audiorender sampleRates"+sampleRates+"channels:"+channels+"bitsPerSample:"+bitsPerSample);
|
||||
|
||||
/* RIFF identifier */
|
||||
this.writeString(viewTalk, 0, 'RIFF');
|
||||
/* file length */
|
||||
viewTalk.setUint32(4, 32 + dataLen * 2, true);
|
||||
/* RIFF type */
|
||||
this.writeString(viewTalk, 8, 'WAVE');
|
||||
/* format chunk identifier */
|
||||
this.writeString(viewTalk, 12, 'fmt ');
|
||||
/* format chunk length */
|
||||
viewTalk.setUint32(16, 16, true);
|
||||
/* sample format (raw) */
|
||||
viewTalk.setUint16(20, 1, true);
|
||||
/* channel count */
|
||||
viewTalk.setUint16(22, channels, true);
|
||||
/* sample rate */
|
||||
viewTalk.setUint32(24, sampleRates, true);
|
||||
/* byte rate (sample rate * block align) */
|
||||
viewTalk.setUint32(28, sampleRates * 2, true);
|
||||
/* block align (channel count * bytes per sample)/8 */
|
||||
viewTalk.setUint16(32, channels * bitsPerSample / 8, true);
|
||||
/* bits per sample */
|
||||
viewTalk.setUint16(34, bitsPerSample, true);
|
||||
/* data chunk identifier */
|
||||
this.writeString(viewTalk, 36, 'data');
|
||||
/* data chunk length */
|
||||
viewTalk.setUint32(40, dataLen, true);
|
||||
this.setBufferToDataview(viewTalk, 44, dataBuf);
|
||||
|
||||
var self = this;
|
||||
this.oAudioContext.decodeAudioData(viewTalk.buffer, function (buffer) {
|
||||
|
||||
var bufferSource = self.oAudioContext.createBufferSource();
|
||||
if (bufferSource == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bufferSource.buffer = buffer;
|
||||
bufferSource.start(0);
|
||||
|
||||
if (self.gainNode == null || self.bSetVolume) {
|
||||
self.gainNode = self.oAudioContext.createGain();
|
||||
// self.gainNode.gain.value = self.currentVolume;
|
||||
// // self.currentVolume = self.gainNode.gain.value;
|
||||
// self.gainNode.connect(self.oAudioContext.destination);
|
||||
|
||||
self.bSetVolume = false;
|
||||
}
|
||||
|
||||
self.gainNode.gain.value = self.currentVolume;
|
||||
// self.currentVolume = self.gainNode.gain.value;
|
||||
self.gainNode.connect(self.oAudioContext.destination);
|
||||
|
||||
bufferSource.connect(self.gainNode);
|
||||
}, function (e) {
|
||||
console.log("decode error");
|
||||
return -1;
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @synopsis 停止播放
|
||||
*
|
||||
* @returns 返回音量
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'Stop',
|
||||
value: function Stop() {
|
||||
if (this.gainNode != null) {
|
||||
this.gainNode.disconnect();
|
||||
this.gainNode = null;
|
||||
}
|
||||
|
||||
// this.oAudioContext.close();
|
||||
|
||||
// AudioRenderer.unique = undefined;
|
||||
// __instance() = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @synopsis 设置音量
|
||||
*
|
||||
* @param iVolume [IN] 音量
|
||||
*
|
||||
* @returns 状态码
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'SetVolume',
|
||||
value: function SetVolume(iVolume) {
|
||||
this.bSetVolume = true;
|
||||
this.currentVolume = iVolume;
|
||||
|
||||
// 储存当前窗口设置音量值
|
||||
this.mVolumes.set(this.iWndNum, iVolume);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @synopsis 设置窗口号
|
||||
*
|
||||
* @param iWndNum [IN] 窗口号
|
||||
*
|
||||
* @returns 状态码
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'SetWndNum',
|
||||
value: function SetWndNum(iWndNum) {
|
||||
this.iWndNum = iWndNum;
|
||||
|
||||
// 获取当前窗口设置音量值
|
||||
var iVolume = this.mVolumes.get(iWndNum);
|
||||
if (iVolume == undefined) {
|
||||
iVolume = 0.8; // 默认音量
|
||||
}
|
||||
this.currentVolume = iVolume;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @synopsis 获取音量
|
||||
*
|
||||
* @returns 返回音量
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'GetVolume',
|
||||
value: function GetVolume() {
|
||||
// 获取当前窗口设置音量值
|
||||
var iVolume = this.mVolumes.get(this.iWndNum);
|
||||
if (iVolume == undefined) {
|
||||
iVolume = 0.8; // 默认音量
|
||||
}
|
||||
|
||||
return iVolume;
|
||||
}
|
||||
}]);
|
||||
|
||||
return AudioRenderer;
|
||||
}();
|
||||
//# sourceMappingURL=AudioRenderer.js.map
|
||||
@ -0,0 +1,711 @@
|
||||
/**
|
||||
* Created by wangweijie5 on 2016/12/5.
|
||||
*/
|
||||
(function (event) {
|
||||
const AUDIO_TYPE = 0; // 音频
|
||||
const VIDEO_TYPE = 1; // 视频
|
||||
const PRIVT_TYPE = 2; // 私有帧
|
||||
|
||||
const PLAYM4_AUDIO_FRAME = 100; // 音频帧
|
||||
const PLAYM4_VIDEO_FRAME = 101; // 视频帧
|
||||
|
||||
const PLAYM4_OK = 1;
|
||||
const PLAYM4_DECODE_ERROR = 44 // 解码失败
|
||||
const PLAYM4_NOT_KEYFRAME = 48; // 非关键帧
|
||||
const PLAYM4_NEED_MORE_DATA = 31; // 需要更多数据才能解析
|
||||
const PLAYM4_SYS_NOT_SUPPORT = 16; // 不支持
|
||||
|
||||
const PLAYM4_PARA_ENCODER_ERROR = 71; //音频编码参数错误
|
||||
const PLAYM4_PRECONDITION_ENCODER_ERROR = 72; //不满足音频编码条件错误
|
||||
const PLAYM4_ENCODER_ERROR = 73; //音频编码失败
|
||||
const PLAYM4_CREATE_ENCODER_ERROR = 74; //创建音频编码器失败
|
||||
const PLAYM4_NOSUPPORT_ENCODER_ERROR = 75; //音频编码不支持
|
||||
const PLAYM4_ALLOC_MEMORY_ENCODER_ERROR = 76; //音频编码相关内存申请失败
|
||||
const PLAYM4_BUF_OVER_ENCODER_ERROR = 77; //音频编码相关buffer满
|
||||
const PLAYM4_NEED_MORE_DATA_ENCODER_ERROR = 78; //音频编码需要更多数据进行编码
|
||||
const PLAYM4_CALL_ORDER_ENCODER_ERROR = 79; //音频编码调用顺序错误
|
||||
|
||||
const PLAYM4_ITYPE_DECODE_ERROR =100; //定位后送进来的第一帧I帧解码失败
|
||||
const PLAYM4_FIRST_FRAME_NOT_ICURRENT =101; //定位后送进来的第一帧不是定位帧所在的I帧(Ni>Mp)
|
||||
|
||||
|
||||
importScripts('Decoder.js');
|
||||
Module.addOnPostRun(function () {
|
||||
postMessage({'function': "loaded"});
|
||||
});
|
||||
|
||||
var iStreamMode = 0; // 流模式
|
||||
|
||||
var bOpenMode = false;
|
||||
var bOpenStream = false;
|
||||
|
||||
var funGetFrameData = null;
|
||||
var funGetAudFrameData = null;
|
||||
|
||||
var bWorkerPrintLog=false;//worker层log开关
|
||||
|
||||
onmessage = function (event)
|
||||
{
|
||||
var eventData = event.data;
|
||||
var res = 0;
|
||||
switch (eventData.command)
|
||||
{
|
||||
case "printLog":
|
||||
let downloadFlag=eventData.data;
|
||||
if(downloadFlag===true)
|
||||
{
|
||||
bWorkerPrintLog=true;
|
||||
res = Module._SetPrintLogFlag(downloadFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
bWorkerPrintLog=false;
|
||||
res = Module._SetPrintLogFlag(downloadFlag);
|
||||
}
|
||||
|
||||
if (res !== PLAYM4_OK)
|
||||
{
|
||||
console.log("DecodeWorker.js: PlayerSDK print log failed,res"+res);
|
||||
postMessage({'function': "printLog", 'errorCode': res});
|
||||
}
|
||||
break;
|
||||
case "SetPlayPosition":
|
||||
let nFrameNumOrTime=eventData.data;
|
||||
let enPosType=eventData.type;
|
||||
res = Module._SetPlayPosition(nFrameNumOrTime,enPosType);
|
||||
if (res !== PLAYM4_OK)
|
||||
{
|
||||
postMessage({'function': "SetPlayPosition", 'errorCode': res});
|
||||
return;
|
||||
}
|
||||
//有没有buffer需要清除
|
||||
|
||||
break;
|
||||
case "SetStreamOpenMode":
|
||||
iStreamMode = eventData.data;
|
||||
res = Module._SetStreamOpenMode(iStreamMode);
|
||||
if (res !== PLAYM4_OK)
|
||||
{
|
||||
postMessage({'function': "SetStreamOpenMode", 'errorCode': res});
|
||||
return;
|
||||
}
|
||||
bOpenMode = true;
|
||||
break;
|
||||
|
||||
case "OpenStream":
|
||||
// 接收到的数据
|
||||
var iHeadLen = eventData.dataSize;
|
||||
var pHead = Module._malloc(iHeadLen + 4);
|
||||
if (pHead === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var aHead = Module.HEAPU8.subarray(pHead, pHead + iHeadLen);
|
||||
aHead.set(eventData.data);
|
||||
res = Module._OpenStream(pHead, iHeadLen, eventData.bufPoolSize);
|
||||
postMessage({'function': "OpenStream", 'errorCode': res});
|
||||
if (res !== PLAYM4_OK)
|
||||
{
|
||||
//释放内存
|
||||
Module._free(pHead);
|
||||
pHead = null;
|
||||
return;
|
||||
}
|
||||
bOpenStream = true;
|
||||
|
||||
// 加4字节长度信息
|
||||
var a32 = new Uint32Array([iHeadLen]);
|
||||
var a8 = new Uint8Array(a32.buffer);
|
||||
var tempBuf = new Uint8Array(iHeadLen + 4);
|
||||
tempBuf.set(a8, 0);
|
||||
tempBuf.set(eventData.data, 4);
|
||||
a32 = null;
|
||||
a8 = null;
|
||||
|
||||
aHead = Module.HEAPU8.subarray(pHead, pHead + iHeadLen + 4);
|
||||
aHead.set(tempBuf);
|
||||
tempBuf = null;
|
||||
|
||||
res = Module._InputData(pHead, iHeadLen + 4);
|
||||
if (res !== PLAYM4_OK)
|
||||
{
|
||||
postMessage({'function': "InputData", 'errorCode': res});
|
||||
Module._free(pHead);
|
||||
pHead = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// 释放内存
|
||||
Module._free(pHead);
|
||||
pHead = null;
|
||||
|
||||
if (funGetFrameData === null) {
|
||||
funGetFrameData = Module.cwrap('GetFrameData', 'number');
|
||||
}
|
||||
|
||||
if (iStreamMode === 0) {
|
||||
// Module._GetFrameData();
|
||||
funGetFrameData();
|
||||
}
|
||||
break;
|
||||
|
||||
case "InputData":
|
||||
// 接收到的数据
|
||||
var iLen = eventData.dataSize;
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker: DecodeWorker-InputData iLen:"+iLen);
|
||||
}
|
||||
|
||||
if (iLen > 0)
|
||||
{
|
||||
var pInputData = Module._malloc(iLen);
|
||||
if (pInputData === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var inputData = new Uint8Array(eventData.data);
|
||||
// var aInputData = Module.HEAPU8.subarray(pInputData, pInputData + iLen);
|
||||
// aInputData.set(inputData);
|
||||
Module.writeArrayToMemory(inputData, pInputData);
|
||||
inputData = null;
|
||||
res = Module._InputData(pInputData, iLen);
|
||||
//console.log("DecodeWorker-InputData-ret:%d", res);
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker:InputData result:"+ +res);
|
||||
}
|
||||
|
||||
if (res !== PLAYM4_OK)
|
||||
{
|
||||
if (res === 98)
|
||||
{
|
||||
res = 1;
|
||||
}
|
||||
postMessage({'function': "InputData", 'errorCode': res});
|
||||
}
|
||||
Module._free(pInputData);
|
||||
pInputData = null;
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
if (funGetFrameData === null)
|
||||
{
|
||||
funGetFrameData = Module.cwrap('GetFrameData', 'number');
|
||||
}
|
||||
|
||||
while (bOpenMode && bOpenStream)
|
||||
{
|
||||
|
||||
var ret = getFrameData(funGetFrameData);
|
||||
// 直到获取视频帧或数据不足为止
|
||||
if (PLAYM4_VIDEO_FRAME === ret || PLAYM4_NEED_MORE_DATA === ret)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "SetSecretKey":
|
||||
var keyLen = eventData.nKeyLen;
|
||||
var pKeyData = Module._malloc(keyLen);
|
||||
if (pKeyData === null) {
|
||||
return;
|
||||
}
|
||||
var nKeySize = eventData.data.length
|
||||
var bufData = stringToBytes (eventData.data);
|
||||
var aKeyData = Module.HEAPU8.subarray(pKeyData, pKeyData + keyLen);
|
||||
aKeyData.set(new Uint8Array(bufData));
|
||||
|
||||
res = Module._SetSecretKey(eventData.nKeyType, pKeyData, keyLen, nKeySize);
|
||||
if (res !== PLAYM4_OK) {
|
||||
postMessage({'function': "SetSecretKey", 'errorCode': res});
|
||||
Module._free(pKeyData);
|
||||
pKeyData = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Module._free(pKeyData);
|
||||
pKeyData = null;
|
||||
break;
|
||||
|
||||
case "GetBMP":
|
||||
var nBMPWidth = eventData.width;
|
||||
var nBMPHeight = eventData.height;
|
||||
var pYUVData = eventData.data;
|
||||
var nYUVSize = nBMPWidth * nBMPHeight * 3 / 2;
|
||||
var oBMPCropRect = eventData.rect;
|
||||
|
||||
var pDataYUV = Module._malloc(nYUVSize);
|
||||
if (pDataYUV === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Module.writeArrayToMemory(new Uint8Array(pYUVData, 0, nYUVSize), pDataYUV);
|
||||
|
||||
// 分配BMP空间
|
||||
var nBmpSize = nBMPWidth * nBMPHeight * 4 + 60;
|
||||
var pBmpData = Module._malloc(nBmpSize);
|
||||
var pBmpSize = Module._malloc(4);
|
||||
if (pBmpData === null || pBmpSize === null) {
|
||||
Module._free(pDataYUV);
|
||||
pDataYUV = null;
|
||||
|
||||
if (pBmpData != null) {
|
||||
Module._free(pBmpData);
|
||||
pBmpData = null;
|
||||
}
|
||||
|
||||
if (pBmpSize != null) {
|
||||
Module._free(pBmpSize);
|
||||
pBmpSize = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Module._memset(pBmpSize, nBmpSize, 4); // 防止bmp截图出现输入数据过大的错误码
|
||||
Module.setValue(pBmpSize, nBmpSize, "i32");
|
||||
res = Module._GetBMP(pDataYUV, nYUVSize, pBmpData, pBmpSize,
|
||||
oBMPCropRect.left, oBMPCropRect.top, oBMPCropRect.right, oBMPCropRect.bottom);
|
||||
if (res !== PLAYM4_OK) {
|
||||
postMessage({'function': "GetBMP", 'errorCode': res});
|
||||
Module._free(pDataYUV);
|
||||
pDataYUV = null;
|
||||
Module._free(pBmpData);
|
||||
pBmpData = null;
|
||||
Module._free(pBmpSize);
|
||||
pBmpSize = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取BMP图片大小
|
||||
var nBmpDataSize = Module.getValue(pBmpSize, "i32");
|
||||
|
||||
// 获取BMP图片数据
|
||||
var aBmpData = new Uint8Array(nBmpDataSize);
|
||||
aBmpData.set(Module.HEAPU8.subarray(pBmpData, pBmpData + nBmpDataSize));
|
||||
|
||||
postMessage({'function': "GetBMP", 'data': aBmpData, 'errorCode': res}, [aBmpData.buffer]);
|
||||
aBmpData=null;
|
||||
if (pDataYUV != null) {
|
||||
Module._free(pDataYUV);
|
||||
pDataYUV = null;
|
||||
}
|
||||
if (pBmpData != null) {
|
||||
Module._free(pBmpData);
|
||||
pBmpData = null;
|
||||
}
|
||||
if (pBmpSize != null) {
|
||||
Module._free(pBmpSize);
|
||||
pBmpSize = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case "GetJPEG":
|
||||
var nJpegWidth = eventData.width;
|
||||
var nJpegHeight = eventData.height;
|
||||
var pYUVData1 = eventData.data;
|
||||
var nYUVSize1 = nJpegWidth * nJpegHeight * 3 / 2;
|
||||
var oJpegCropRect = eventData.rect;
|
||||
|
||||
var pDataYUV1 = Module._malloc(nYUVSize1);
|
||||
if (pDataYUV1 === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Module.writeArrayToMemory(new Uint8Array(pYUVData1, 0, nYUVSize1), pDataYUV1);
|
||||
|
||||
// 分配JPEG空间
|
||||
var pJpegData = Module._malloc(nYUVSize1);
|
||||
var pJpegSize = Module._malloc(4);
|
||||
if (pJpegData === null || pJpegSize === null) {
|
||||
if (pJpegData != null) {
|
||||
Module._free(pJpegData);
|
||||
pJpegData = null;
|
||||
}
|
||||
|
||||
if (pJpegSize != null) {
|
||||
Module._free(pJpegSize);
|
||||
pJpegSize = null;
|
||||
}
|
||||
|
||||
if (pDataYUV1 != null) {
|
||||
Module._free(pDataYUV1);
|
||||
pDataYUV1 = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Module.setValue(pJpegSize, nJpegWidth * nJpegHeight * 2, "i32"); // JPEG抓图,输入缓冲长度不小于当前帧YUV大小
|
||||
|
||||
res = Module._GetJPEG(pDataYUV1, nYUVSize1, pJpegData, pJpegSize,
|
||||
oJpegCropRect.left, oJpegCropRect.top, oJpegCropRect.right, oJpegCropRect.bottom);
|
||||
if (res !== PLAYM4_OK) {
|
||||
postMessage({'function': "GetJPEG", 'errorCode': res});
|
||||
if (pJpegData != null) {
|
||||
Module._free(pJpegData);
|
||||
pJpegData = null;
|
||||
}
|
||||
|
||||
if (pJpegSize != null) {
|
||||
Module._free(pJpegSize);
|
||||
pJpegSize = null;
|
||||
}
|
||||
|
||||
if (pDataYUV1 != null) {
|
||||
Module._free(pDataYUV1);
|
||||
pDataYUV1 = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取JPEG图片大小
|
||||
var nJpegSize = Module.getValue(pJpegSize, "i32");
|
||||
|
||||
// 获取JPEG图片数据
|
||||
var aJpegData = new Uint8Array(nJpegSize);
|
||||
aJpegData.set(Module.HEAPU8.subarray(pJpegData, pJpegData + nJpegSize));
|
||||
|
||||
postMessage({'function': "GetJPEG", 'data': aJpegData, 'errorCode': res}, [aJpegData.buffer]);
|
||||
|
||||
nJpegSize = null;
|
||||
aJpegData = null;
|
||||
|
||||
if (pDataYUV1 != null) {
|
||||
Module._free(pDataYUV1);
|
||||
pDataYUV1 = null;
|
||||
}
|
||||
if (pJpegData != null) {
|
||||
Module._free(pJpegData);
|
||||
pJpegData = null;
|
||||
}
|
||||
if (pJpegSize != null) {
|
||||
Module._free(pJpegSize);
|
||||
pJpegSize = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case "SetDecodeFrameType":
|
||||
var nFrameType = eventData.data;
|
||||
res = Module._SetDecodeFrameType(nFrameType);
|
||||
if (res !== PLAYM4_OK) {
|
||||
postMessage({'function': "SetDecodeFrameType", 'errorCode': res});
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case "DisplayRegion":
|
||||
var nRegionNum = eventData.nRegionNum;
|
||||
var srcRect = eventData.srcRect;
|
||||
var hDestWnd = eventData.hDestWnd;
|
||||
var bEnable = eventData.bEnable;
|
||||
|
||||
res = Module._SetDisplayRegion(nRegionNum, srcRect, hDestWnd, bEnable);
|
||||
if (res !== PLAYM4_OK) {
|
||||
postMessage({'function': "DisplayRegion", 'errorCode': res});
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case "CloseStream":
|
||||
res = Module._CloseStream();
|
||||
if (res !== PLAYM4_OK) {
|
||||
postMessage({'function': "CloseStream", 'errorCode': res});
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case "SetIFrameDecInterval":
|
||||
Module._SetIFrameDecInterval(eventData.data);
|
||||
break;
|
||||
case "SetLostFrameMode":
|
||||
Module._SetLostFrameMode(eventData.data);
|
||||
break;
|
||||
|
||||
/*******************************************worker音频编码相关接口实现**********************************************************/
|
||||
case "CreateAudEncode":
|
||||
|
||||
res = Module._CreateAudEncode(eventData.encodertype);
|
||||
|
||||
postMessage({'function':"CreateAudEncode",'errorCode':res});
|
||||
break;
|
||||
case "SetAudEncodeParam":
|
||||
|
||||
res = Module._SetAudEncodeParam(eventData.samplerate, eventData.channel, eventData.bitrate, eventData.bitwidth);
|
||||
|
||||
postMessage({'function':"SetAudEncodeParam",'errorCode':res});
|
||||
break;
|
||||
case "DestroyAudEncode":
|
||||
|
||||
res = Module._DestroyAudEncode();
|
||||
|
||||
postMessage({'function':"DestroyAudEncode",'errorCode':res});
|
||||
break;
|
||||
case "InputAudEncodeData":
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker: 20200113 DecodeWorker-InputAudEncodeData 1");
|
||||
}
|
||||
|
||||
var iLen = eventData.dataSize;
|
||||
if(iLen > 0)
|
||||
{
|
||||
|
||||
var pAudInputData = Module._malloc(iLen);
|
||||
if (pAudInputData === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var audinputData = new Uint8Array(eventData.data);
|
||||
Module.writeArrayToMemory(audinputData, pAudInputData);
|
||||
audinputData = null;
|
||||
res = Module._InputAudEncodeData(pAudInputData, iLen);
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker: 20200113 DecodeWorker-InputAudEncodeData 2 res:"+res);
|
||||
}
|
||||
|
||||
if(res == PLAYM4_OK) //接口返回成功,表明已编码好一帧音频数据
|
||||
{
|
||||
|
||||
if (funGetAudFrameData === null)
|
||||
{
|
||||
funGetAudFrameData = Module.cwrap('GetAudFrameData', 'number');
|
||||
}
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker: 20200113 DecodeWorker-InputAudEncodeData 2-1 succ");
|
||||
}
|
||||
//调用C++ GetAudFrameData
|
||||
var ret = getAudFrameData(funGetAudFrameData);
|
||||
}
|
||||
Module._free(pAudInputData);
|
||||
pAudInputData = null;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
function getOSDTime(oFrameInfo) {
|
||||
var iYear = oFrameInfo.year;
|
||||
var iMonth = oFrameInfo.month;
|
||||
var iDay = oFrameInfo.day;
|
||||
var iHour = oFrameInfo.hour;
|
||||
var iMinute = oFrameInfo.minute;
|
||||
var iSecond = oFrameInfo.second;
|
||||
|
||||
if (iMonth < 10) {
|
||||
iMonth = "0" + iMonth;
|
||||
}
|
||||
if (iDay < 10) {
|
||||
iDay = "0" + iDay;
|
||||
}
|
||||
if (iHour < 10) {
|
||||
iHour = "0" + iHour;
|
||||
}
|
||||
if (iMinute < 10) {
|
||||
iMinute = "0" + iMinute;
|
||||
}
|
||||
if (iSecond < 10) {
|
||||
iSecond = "0" + iSecond;
|
||||
}
|
||||
|
||||
return iYear + "-" + iMonth + "-" + iDay + " " + iHour + ":" + iMinute + ":" + iSecond;
|
||||
}
|
||||
|
||||
function getAudFrameData(fun)
|
||||
{
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker: DecodeWorker-getAudFrameData 1");
|
||||
}
|
||||
|
||||
var res = fun(); // 调用C++GetAudFrameData函数
|
||||
if(res === PLAYM4_OK)
|
||||
{
|
||||
var oFrameInfo = Module._GetAudFrameInfo();
|
||||
var iSize = oFrameInfo.frameSize;
|
||||
if (0 === iSize)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var pEncodeAud = Module._GetAudFrameBuffer();
|
||||
if(pEncodeAud == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var aEncodeAudData = new Uint8Array(iSize);
|
||||
aEncodeAudData.set(Module.HEAPU8.subarray(pEncodeAud, pEncodeAud + iSize));
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker: DecodeWorker-getAudFrameData 2");
|
||||
}
|
||||
|
||||
//获取到音频编码帧数据通过worker返回
|
||||
postMessage({'function':"GetAudEncodeData",'data':aEncodeAudData.buffer,'dataSize':iSize, 'errorCode': res});
|
||||
}
|
||||
else
|
||||
{
|
||||
postMessage({'function':"GetAudEncodeData",'data':null,'dataSize':-1, 'errorCode': res});
|
||||
}
|
||||
oFrameInfo=null;
|
||||
pEncodeAud=null;
|
||||
aEncodeAudData=null;
|
||||
return res;
|
||||
}
|
||||
|
||||
// 获取帧数据
|
||||
function getFrameData(fun)
|
||||
{
|
||||
// function getFrameData() {
|
||||
// 获取帧数据
|
||||
// var res = Module._GetFrameData();
|
||||
var res = fun();
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker: getFrameData Result:"+res);
|
||||
}
|
||||
|
||||
if (res === PLAYM4_OK)
|
||||
{
|
||||
var oFrameInfo = Module._GetFrameInfo();
|
||||
switch (oFrameInfo.frameType)
|
||||
{
|
||||
case AUDIO_TYPE:
|
||||
var iSize = oFrameInfo.frameSize;
|
||||
if (0 === iSize)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
var pPCM = Module._GetFrameBuffer();
|
||||
// var audioBuf = new ArrayBuffer(iSize);
|
||||
var aPCMData = new Uint8Array(iSize);
|
||||
aPCMData.set(Module.HEAPU8.subarray(pPCM, pPCM + iSize));
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker: audio media Info: nSise:"+ oFrameInfo.frameSize+",nSampleRate:"+oFrameInfo.samplesPerSec+',channel:'+oFrameInfo.channels+',bitsPerSample:'+oFrameInfo.bitsPerSample);
|
||||
}
|
||||
postMessage({
|
||||
'function': "GetFrameData", 'type': "audioType", 'data': aPCMData.buffer,
|
||||
'frameInfo': oFrameInfo, 'errorCode': res
|
||||
}, [aPCMData.buffer]);
|
||||
|
||||
oFrameInfo = null;
|
||||
pPCM = null;
|
||||
aPCMData = null;
|
||||
return PLAYM4_AUDIO_FRAME;
|
||||
|
||||
case VIDEO_TYPE:
|
||||
var szOSDTime = getOSDTime(oFrameInfo);
|
||||
|
||||
var iWidth = oFrameInfo.width;
|
||||
var iHeight = oFrameInfo.height;
|
||||
|
||||
var iYUVSize = iWidth * iHeight * 3 / 2;
|
||||
if (0 === iYUVSize)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var pYUV = Module._GetFrameBuffer();
|
||||
|
||||
// 图像数据渲染后压回,若从主码流切到子码流,存在数组大小与图像大小不匹配现象
|
||||
var aYUVData = new Uint8Array(iYUVSize);
|
||||
aYUVData.set(Module.HEAPU8.subarray(pYUV, pYUV + iYUVSize));
|
||||
if(bWorkerPrintLog)
|
||||
{
|
||||
console.log("<<<Worker: InputData-getFrameData Video: Width:"+ oFrameInfo.width+",Height:"+oFrameInfo.height+",timeStamp:"+oFrameInfo.timeStamp);
|
||||
}
|
||||
|
||||
postMessage({
|
||||
'function': "GetFrameData", 'type': "videoType", 'data': aYUVData.buffer,
|
||||
'dataLen': aYUVData.length,'osd': szOSDTime, 'frameInfo': oFrameInfo, 'errorCode': res
|
||||
}, [aYUVData.buffer]);
|
||||
|
||||
oFrameInfo = null;
|
||||
pYUV = null;
|
||||
aYUVData = null;
|
||||
return PLAYM4_VIDEO_FRAME;
|
||||
|
||||
case PRIVT_TYPE:
|
||||
postMessage({
|
||||
'function': "GetFrameData", 'type': "", 'data': null,
|
||||
'dataLen': -1, 'osd': 0, 'frameInfo': null, 'errorCode': PLAYM4_SYS_NOT_SUPPORT
|
||||
});
|
||||
return PLAYM4_SYS_NOT_SUPPORT;
|
||||
|
||||
default:
|
||||
postMessage({
|
||||
'function': "GetFrameData", 'type': "", 'data': null,
|
||||
'dataLen': -1, 'osd': 0, 'frameInfo': null, 'errorCode': PLAYM4_SYS_NOT_SUPPORT
|
||||
});
|
||||
return PLAYM4_SYS_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//解码失败返回裸数据
|
||||
if(PLAYM4_DECODE_ERROR===res)
|
||||
{
|
||||
var rawInfo=Module._GetRawDataInfo();
|
||||
var pRawData = Module._GetRawDataBuffer();
|
||||
var aRawData = new Uint8Array(rawInfo.isize);
|
||||
aRawData.set(Module.HEAPU8.subarray(pRawData, pRawData + rawInfo.isize));
|
||||
postMessage({
|
||||
'function': "GetRawData", 'type': "", 'data':aRawData.buffer,
|
||||
'rawDataLen': rawInfo.isize, 'osd': 0, 'frameInfo': null, 'errorCode': res
|
||||
});
|
||||
rawInfo=null;
|
||||
pRawData=null;
|
||||
aRawData=null;
|
||||
}
|
||||
//定位返回的错误
|
||||
if(PLAYM4_FIRST_FRAME_NOT_ICURRENT===res|| PLAYM4_ITYPE_DECODE_ERROR===res)
|
||||
{
|
||||
postMessage({
|
||||
'function': "GetFrameData", 'type': "", 'data': null,
|
||||
'dataLen': -1, 'osd': 0, 'frameInfo': null, 'errorCode': res
|
||||
});
|
||||
}
|
||||
//需要更多数据
|
||||
if (PLAYM4_NEED_MORE_DATA === res || PLAYM4_SYS_NOT_SUPPORT === res || PLAYM4_NOT_KEYFRAME === res){
|
||||
postMessage({
|
||||
'function': "GetFrameData", 'type': "", 'data': null,
|
||||
'dataLen': -1, 'osd': 0, 'frameInfo': null, 'errorCode': res
|
||||
});
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// 开始计算时间
|
||||
function startTime() {
|
||||
return new Date().getTime();
|
||||
}
|
||||
|
||||
// 结束计算时间
|
||||
function endTime() {
|
||||
return new Date().getTime();
|
||||
}
|
||||
|
||||
// 字母字符串转byte数组
|
||||
function stringToBytes ( str ) {
|
||||
var ch, st, re = [];
|
||||
for (var i = 0; i < str.length; i++ ) {
|
||||
ch = str.charCodeAt(i); // get char
|
||||
st = []; // set up "stack"
|
||||
do {
|
||||
st.push( ch & 0xFF ); // push byte to stack
|
||||
ch = ch >> 8; // shift value down by 1 byte
|
||||
}
|
||||
while ( ch );
|
||||
// add stack contents to result
|
||||
// done because chars have "wrong" endianness
|
||||
re = re.concat( st.reverse() );
|
||||
}
|
||||
// return an array of bytes
|
||||
return re;
|
||||
}
|
||||
})();
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,396 @@
|
||||
"use strict";
|
||||
//顶点着色器
|
||||
//attribute修饰符用于声明由浏览器(javascript)传输给顶点着色器的变量值;
|
||||
// vertexPos即我们定义的顶点坐标;
|
||||
// gl_Position是一个内建的传出变量。
|
||||
var vertexYUVShader = [
|
||||
'attribute vec4 vertexPos;',
|
||||
'attribute vec2 texturePos;',
|
||||
'varying vec2 textureCoord;',
|
||||
|
||||
'void main()',
|
||||
'{',
|
||||
'gl_Position = vertexPos;',
|
||||
'textureCoord = texturePos;',
|
||||
'}'
|
||||
].join('\n');
|
||||
//像素着色器(yuv->rgb)
|
||||
var fragmentYUVShader = [
|
||||
'precision highp float;',
|
||||
'varying highp vec2 textureCoord;',
|
||||
'uniform sampler2D ySampler;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'uniform sampler2D vSampler;',
|
||||
'const mat4 YUV2RGB = mat4',
|
||||
'(',
|
||||
'1.1643828125, 0, 1.59602734375, -.87078515625,',
|
||||
'1.1643828125, -.39176171875, -.81296875, .52959375,',
|
||||
'1.1643828125, 2.017234375, 0, -1.081390625,',
|
||||
'0, 0, 0, 1',
|
||||
');',
|
||||
|
||||
'void main(void) {',
|
||||
'highp float y = texture2D(ySampler, textureCoord).r;',
|
||||
'highp float u = texture2D(uSampler, textureCoord).r;',
|
||||
'highp float v = texture2D(vSampler, textureCoord).r;',
|
||||
'gl_FragColor = vec4(y, u, v, 1) * YUV2RGB;',
|
||||
'}'
|
||||
].join('\n');
|
||||
|
||||
(function (root, factory) {
|
||||
root.SuperRender = factory();
|
||||
}(this, function () {
|
||||
|
||||
function RenderManager(canvas) {
|
||||
|
||||
this.canvasElement = document.getElementById(canvas);
|
||||
|
||||
this.initContextGL();
|
||||
|
||||
if(this.contextGL) {
|
||||
this.YUVProgram = this.initProgram(vertexYUVShader, fragmentYUVShader);
|
||||
this.initBuffers();
|
||||
this.initTextures();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化WebGL上下文
|
||||
*/
|
||||
RenderManager.prototype.initContextGL = function() {
|
||||
|
||||
var canvas = this.canvasElement;
|
||||
|
||||
var gl = null;
|
||||
|
||||
try {
|
||||
gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
|
||||
} catch (e) {
|
||||
gl = null;
|
||||
}
|
||||
|
||||
if(!gl || typeof gl.getParameter !== "function") {
|
||||
gl = null;
|
||||
}
|
||||
|
||||
this.contextGL = gl;
|
||||
|
||||
console.log("WebGL1.0");
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化着色器程序
|
||||
* @param vertexShaderScript 顶点着色器脚本
|
||||
* @param fragmentShaderScript 片段着色器脚本
|
||||
*/
|
||||
RenderManager.prototype.initProgram = function(vertexShaderScript, fragmentShaderScript) {
|
||||
|
||||
var gl = this.contextGL;
|
||||
|
||||
var vertexShader = gl.createShader(gl.VERTEX_SHADER); //创建定点着色器
|
||||
gl.shaderSource(vertexShader, vertexShaderScript);
|
||||
gl.compileShader(vertexShader);
|
||||
if(!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
|
||||
console.log('Vertex shader failed to compile: ' + gl.getShaderInfoLog(vertexShader));
|
||||
}
|
||||
|
||||
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
||||
gl.shaderSource(fragmentShader, fragmentShaderScript);
|
||||
gl.compileShader(fragmentShader);
|
||||
if(!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
|
||||
console.log('Fragment shader failed to compile: ' + gl.getShaderInfoLog(fragmentShader));
|
||||
}
|
||||
|
||||
var program = gl.createProgram();
|
||||
gl.attachShader(program, vertexShader);
|
||||
gl.attachShader(program, fragmentShader);
|
||||
gl.linkProgram(program);
|
||||
if(!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
||||
console.log('Program failed to compile: ' + gl.getProgramInfoLog(program));
|
||||
}
|
||||
|
||||
gl.deleteShader(vertexShader);
|
||||
gl.deleteShader(fragmentShader);
|
||||
|
||||
return program;
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化数据缓存
|
||||
*/
|
||||
RenderManager.prototype.initBuffers = function() {
|
||||
|
||||
var gl = this.contextGL;
|
||||
|
||||
var vertexPosBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 1, -1, 1, 1, -1, -1, -1]), gl.STATIC_DRAW);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
|
||||
var texturePosBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 0, 0, 0, 1, 1, 0, 1]), gl.DYNAMIC_DRAW);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
|
||||
this.vertexPosBuffer = vertexPosBuffer;
|
||||
this.texturePosBuffer = texturePosBuffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建纹理
|
||||
*/
|
||||
RenderManager.prototype.initTexture = function() {
|
||||
|
||||
var gl = this.contextGL;
|
||||
|
||||
var textureRef = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, textureRef);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
|
||||
return textureRef;
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化YUV纹理
|
||||
*/
|
||||
RenderManager.prototype.initTextures = function() {
|
||||
|
||||
var gl = this.contextGL;
|
||||
|
||||
var program = this.YUVProgram;
|
||||
gl.useProgram(program);
|
||||
|
||||
var yTextureRef = this.initTexture();
|
||||
var ySamplerRef = gl.getUniformLocation(program, 'ySampler');
|
||||
gl.uniform1i(ySamplerRef, 0);
|
||||
this.yTextureRef = yTextureRef;
|
||||
|
||||
var uTextureRef = this.initTexture();
|
||||
var uSamplerRef = gl.getUniformLocation(program, 'uSampler');
|
||||
gl.uniform1i(uSamplerRef, 1);
|
||||
this.uTextureRef = uTextureRef;
|
||||
|
||||
var vTextureRef = this.initTexture();
|
||||
var vSamplerRef = gl.getUniformLocation(program, 'vSampler');
|
||||
gl.uniform1i(vSamplerRef, 2);
|
||||
this.vTextureRef = vTextureRef;
|
||||
|
||||
gl.useProgram(null);
|
||||
};
|
||||
|
||||
/**
|
||||
* 显示帧数据
|
||||
* @param nWidth 宽度
|
||||
* @param nHeight 高度
|
||||
* @param nHeight 帧数据
|
||||
*/
|
||||
RenderManager.prototype.SR_DisplayFrameData = function(nWidth, nHeight, pData,dWidth,dHeight) {
|
||||
|
||||
if(nWidth <= 0 || nHeight <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var gl = this.contextGL;
|
||||
|
||||
if(null == pData)
|
||||
{
|
||||
gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
return;
|
||||
}
|
||||
|
||||
var canvas = this.canvasElement;
|
||||
|
||||
this.nWindowWidth = canvas.width;
|
||||
this.nWindowHeight = canvas.height;
|
||||
|
||||
var nWindowWidth = this.nWindowWidth;
|
||||
var nWindowHeight = this.nWindowHeight;
|
||||
|
||||
gl.clearColor(0.8, 0.8, 1.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
gl.viewport(0, 0, nWindowWidth, nWindowHeight);
|
||||
|
||||
this.updateFrameData(nWidth, nHeight, pData,dWidth,dHeight);
|
||||
|
||||
var program = this.YUVProgram;
|
||||
gl.useProgram(program);
|
||||
|
||||
var vertexPosBuffer = this.vertexPosBuffer;
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
|
||||
var vertexPosRef = gl.getAttribLocation(program, 'vertexPos');
|
||||
gl.enableVertexAttribArray(vertexPosRef);
|
||||
gl.vertexAttribPointer(vertexPosRef, 2, gl.FLOAT, false, 0, 0);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
|
||||
var texturePosBuffer = this.texturePosBuffer;
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
|
||||
var texturePosRef = gl.getAttribLocation(program, 'texturePos');
|
||||
gl.enableVertexAttribArray(texturePosRef);
|
||||
gl.vertexAttribPointer(texturePosRef, 2, gl.FLOAT, false, 0, 0);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
gl.disableVertexAttribArray(vertexPosRef);
|
||||
gl.disableVertexAttribArray(texturePosRef);
|
||||
|
||||
gl.useProgram(null);
|
||||
};
|
||||
|
||||
/**
|
||||
* 上传YUV数据到纹理
|
||||
* @param nWidth 宽度
|
||||
* @param nHeight 高度
|
||||
* @param nHeight 帧数据
|
||||
*/
|
||||
RenderManager.prototype.updateFrameData = function(width, height, data,dWidth,dHeight) {
|
||||
|
||||
var gl = this.contextGL;
|
||||
|
||||
var yTextureRef = this.yTextureRef;
|
||||
var uTextureRef = this.uTextureRef;
|
||||
var vTextureRef = this.vTextureRef;
|
||||
|
||||
var i420Data = data;
|
||||
// debugger;
|
||||
if(width == dWidth && height == dHeight)
|
||||
{
|
||||
var yDataLength = width * height;
|
||||
var yData = i420Data.subarray(0, yDataLength);
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, yTextureRef);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width, height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, yData);
|
||||
|
||||
var cbDataLength = width/2 * height/2;
|
||||
var cbData = i420Data.subarray(width*height, width*height + cbDataLength);
|
||||
gl.activeTexture(gl.TEXTURE1);
|
||||
gl.bindTexture(gl.TEXTURE_2D, uTextureRef);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width/2, height/2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, cbData);
|
||||
|
||||
var crDataLength = cbDataLength;
|
||||
var crData = i420Data.subarray(width*height + width*height/4, width*height + width*height/4 + crDataLength);
|
||||
gl.activeTexture(gl.TEXTURE2);
|
||||
gl.bindTexture(gl.TEXTURE_2D, vTextureRef);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width/2, height/2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, crData);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// //裁剪宽
|
||||
var yDataLength = dWidth * dHeight;
|
||||
var yData=new Uint8Array(yDataLength) ;
|
||||
for(var i=0;i<dHeight;i++)
|
||||
{
|
||||
//var ySonData=new Uint8Array(dWidth) ;
|
||||
var ySonData = i420Data.subarray(i*width, i*width+dWidth);
|
||||
for (var j = 0; j < dWidth; j++) {
|
||||
yData[i*dWidth + j] = ySonData[j];
|
||||
}
|
||||
}
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, yTextureRef);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, dWidth, dHeight, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, yData);
|
||||
yData=null;
|
||||
ySonData=null;
|
||||
|
||||
var cbDataLength = dWidth/2 * dHeight/2;
|
||||
var cbData =new Uint8Array(cbDataLength);
|
||||
//var cbSonData=new Uint8Array(dWidth/2) ;
|
||||
for(var i=0;i<dHeight/2;i++)
|
||||
{
|
||||
var cbSonData = i420Data.subarray(width*height+i*width/2, width*height+i*width/2+dWidth/2);
|
||||
for (var j = 0; j < dWidth/2; j++) {
|
||||
cbData[i*dWidth/2 + j] = cbSonData[j];
|
||||
}
|
||||
}
|
||||
gl.activeTexture(gl.TEXTURE1);
|
||||
gl.bindTexture(gl.TEXTURE_2D, uTextureRef);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, dWidth/2, dHeight/2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, cbData);
|
||||
cbData=null;
|
||||
cbSonData=null;
|
||||
|
||||
var crDataLength = cbDataLength;
|
||||
var crData = new Uint8Array(crDataLength);
|
||||
for(var i=0;i<dHeight/2;i++)
|
||||
{
|
||||
var crSonData = i420Data.subarray(width*height*5/4+i*width/2, width*height*5/4+i*width/2+dWidth/2);
|
||||
for (var j = 0; j < dWidth/2; j++) {
|
||||
crData[i*dWidth/2 + j] = crSonData[j];
|
||||
}
|
||||
}
|
||||
gl.activeTexture(gl.TEXTURE2);
|
||||
gl.bindTexture(gl.TEXTURE_2D, vTextureRef);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, dWidth/2, dHeight/2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, crData);
|
||||
crData=null;
|
||||
crSonData=null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置显示区域
|
||||
* @param stDisplayRect 显示区域
|
||||
*/
|
||||
RenderManager.prototype.SR_SetDisplayRect = function(stDisplayRect) {
|
||||
|
||||
var gl = this.contextGL;
|
||||
|
||||
var nWindowWidth = this.nWindowWidth;
|
||||
var nWindowHeight = this.nWindowHeight;
|
||||
|
||||
var texturePosValues = null;
|
||||
|
||||
if(stDisplayRect && nWindowWidth > 0 && nWindowHeight > 0) {
|
||||
var fLeft = stDisplayRect.left / nWindowWidth;
|
||||
var fTop = stDisplayRect.top / nWindowHeight;
|
||||
var fRight = stDisplayRect.right / nWindowWidth;
|
||||
var fBottom = stDisplayRect.bottom / nWindowHeight;
|
||||
|
||||
texturePosValues = new Float32Array([fRight, fTop, fLeft, fTop, fRight, fBottom, fLeft, fBottom]);
|
||||
}
|
||||
else {
|
||||
texturePosValues = new Float32Array([1, 0, 0, 0, 1, 1, 0, 1]);
|
||||
}
|
||||
|
||||
var texturePosBuffer = this.texturePosBuffer;
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, texturePosValues);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
};
|
||||
|
||||
/**
|
||||
* 释放显示资源
|
||||
*/
|
||||
RenderManager.prototype.SR_Destroy = function() {
|
||||
|
||||
var gl = this.contextGL;
|
||||
|
||||
var YUVProgram = this.YUVProgram;
|
||||
gl.deleteProgram(YUVProgram);
|
||||
|
||||
var vertexPosBuffer = this.vertexPosBuffer;
|
||||
var texturePosBuffer = this.texturePosBuffer;
|
||||
|
||||
gl.deleteBuffer(vertexPosBuffer);
|
||||
gl.deleteBuffer(texturePosBuffer);
|
||||
|
||||
var yTextureRef = this.yTextureRef;
|
||||
var uTextureRef = this.uTextureRef;
|
||||
var vTextureRef = this.vTextureRef;
|
||||
gl.deleteTexture(yTextureRef);
|
||||
gl.deleteTexture(uTextureRef);
|
||||
gl.deleteTexture(vTextureRef);
|
||||
//gl.getExtension('WEBGL_lose_context').loseContext();
|
||||
};
|
||||
|
||||
return RenderManager;
|
||||
|
||||
}));
|
||||
Loading…
x
Reference in New Issue
Block a user