first commit

This commit is contained in:
huxin02 2025-02-14 16:04:21 +08:00
commit 6285b128f9
56 changed files with 18634 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/zhzf.iml" filepath="$PROJECT_DIR$/.idea/zhzf.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

9
.idea/zhzf.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

11
client/public/favicon.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

1
client/public/js/h5player.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,705 @@
/**
* 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_ORDER_ERROR = 2;
const PLAYM4_DECODE_ERROR = 44 // 解码失败
const PLAYM4_NOT_KEYFRAME = 48; // 非关键帧
const PLAYM4_NEED_MORE_DATA = 31; // 需要更多数据才能解析
const PLAYM4_NEED_NEET_LOOP = 35; //丢帧需要下个循环
const PLAYM4_SYS_NOT_SUPPORT = 16; // 不支持
// 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开关
var g_nPort = -1;
var pInputData = null;
var inputBufferSize = 40960;
self.JSPlayM4_RunTimeInfoCallBack = function (nPort, pstRunTimeInfo, pUser) {
let port = nPort;
let user = pUser;
let nRunTimeModule = Module.HEAP32[pstRunTimeInfo >> 2];
let nStrVersion = Module.HEAP32[pstRunTimeInfo + 4 >> 2];
let nFrameTimeStamp = Module.HEAP32[pstRunTimeInfo + 8 >> 2];
let nFrameNum = Module.HEAP32[pstRunTimeInfo + 12 >> 2];
let nErrorCode = Module.HEAP32[pstRunTimeInfo + 16 >> 2];
// console.log("nRunTimeModule:"+nRunTimeModule+",nFrameNum:"+nFrameNum+",nErrorCode:"+nErrorCode);
postMessage({ 'function': "RunTimeInfoCallBack", 'nRunTimeModule': nRunTimeModule, 'nStrVersion': nStrVersion, 'nFrameTimeStamp': nFrameTimeStamp, 'nFrameNum': nFrameNum, 'nErrorCode': nErrorCode });
}
self.JSPlayM4_StreamInfoCallBack = function (nPort, pstStreamInfo, pUser)
{
let port = nPort;
let user = pUser;
let nSystemformat = Module.HEAP16[pstStreamInfo >> 1]; //封装类型
let nVideoformat = Module.HEAP16[pstStreamInfo + 2 >> 1];//视频编码类型
let nAudioformat = Module.HEAP16[pstStreamInfo + 4 >> 1];//音频编码类型
let nAudiochannels = Module.HEAP16[pstStreamInfo + 6 >> 1]; //音频通道数
let nAudiobitspersample = Module.HEAP32[pstStreamInfo + 8 >> 2];//音频样位率
let nAudiosamplesrate = Module.HEAP32[pstStreamInfo + 12 >> 2];//音频采样率
let nAudiobitrate = Module.HEAP32[pstStreamInfo + 16 >> 2];//音频比特率,单位bit
//console.log("nSystemformat:" + nSystemformat + ",nVideoformat:" + nVideoformat + ",nAudioformat:" + nAudioformat + ",nAudiochannels:" + nAudiochannels + ",nAudiobitspersample:" + nAudiobitspersample + ",nAudiosamplesrate:" + nAudiosamplesrate + ",nAudiobitrate:" + nAudiobitrate);
postMessage({ 'function': "StreamInfoCallBack", 'nSystemformat': nSystemformat, 'nVideoformat': nVideoformat, 'nAudioformat': nAudioformat, 'nAudiochannels': nAudiochannels, 'nAudiobitspersample': nAudiobitspersample, 'nAudiosamplesrate': nAudiosamplesrate, 'nAudiobitrate': nAudiobitrate});
}
onmessage = function (event) {
var eventData = event.data;
var res = 0;
switch (eventData.command) {
case "importScripts":
const decodebase = eventData.data + "Decoder.js"
importScripts(decodebase);
Module.addOnPostRun(function () {
postMessage({ 'function': "loaded" });
});
break;
case "printLog":
let downloadFlag = eventData.data;
if (downloadFlag === true) {
bWorkerPrintLog = true;
res = Module._SetPrintLogFlag(g_nPort, downloadFlag);
}
else {
bWorkerPrintLog = false;
res = Module._SetPrintLogFlag(g_nPort, 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":
//获取端口号
g_nPort = Module._GetPort();
//设置流打开模式
iStreamMode = eventData.data;
res = Module._SetStreamOpenMode(g_nPort, 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(new Uint8Array(eventData.data));
res = Module._OpenStream(g_nPort, pHead, iHeadLen, eventData.bufPoolSize);
postMessage({ 'function': "OpenStream", 'errorCode': res });
if (res !== PLAYM4_OK) {
//释放内存
Module._free(pHead);
pHead = null;
return;
}
bOpenStream = true;
break;
case "Play":
let resP = Module._Play(g_nPort);
if (resP !== PLAYM4_OK) {
return;
}
break;
case "InputData":
// 接收到的数据
var iLen = eventData.dataSize;
if (iLen > 0) {
if (pInputData == null || iLen > inputBufferSize) {
if (pInputData != null) {
Module._free(pInputData);
pInputData = null;
}
if (iLen > inputBufferSize) {
inputBufferSize = iLen;
}
pInputData = Module._malloc(inputBufferSize);
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(g_nPort, pInputData, iLen);
if (res !== PLAYM4_OK) {
let errorCode = Module._GetLastError(g_nPort);
let sourceRemain = Module._GetSourceBufferRemain(g_nPort);
postMessage({ 'function': "InputData", 'errorCode': errorCode, "sourceRemain": sourceRemain });
}
//Module._free(pInputData);
//pInputData = null;
} else {
let sourceRemain = Module._GetSourceBufferRemain(g_nPort);
if (sourceRemain == 0) {
postMessage({ 'function': "InputData", 'errorCode': PLAYM4_NEED_MORE_DATA });
return;
}
}
/////////////////////
// if (funGetFrameData === null) {
// funGetFrameData = Module.cwrap('GetFrameData', 'number');
// }
while (bOpenMode && bOpenStream) {
var ret = getFrameData();
// 直到获取视频帧或数据不足为止
if (PLAYM4_VIDEO_FRAME === ret || PLAYM4_NEED_MORE_DATA === ret || PLAYM4_ORDER_ERROR === ret)//PLAYM4_VIDEO_FRAME === ret || || PLAYM4_NEED_NEET_LOOP === 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);
let u8array = new Uint8Array(keyLen);
aKeyData.set(u8array, 0);
aKeyData.set(new Uint8Array(bufData));
aKeyData = null;
u8array = null;
res = Module._SetSecretKey(g_nPort, 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 = {
left: eventData.left,
top: eventData.top,
right: eventData.right,
bottom: eventData.bottom
};
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(g_nPort, 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 = {
left: eventData.left,
top: eventData.top,
right: eventData.right,
bottom: eventData.bottom
};
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(g_nPort, 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(g_nPort, nFrameType);
if (res !== PLAYM4_OK) {
postMessage({ 'function': "SetDecodeFrameType", 'errorCode': res });
return;
}
break;
case "CloseStream":
//stop
let resS = Module._Stop(g_nPort);
if (resS !== PLAYM4_OK) {
postMessage({ 'function': "Stop", 'errorCode': res });
return;
}
//closeStream
res = Module._CloseStream(g_nPort);
if (res !== PLAYM4_OK) {
postMessage({ 'function': "CloseStream", 'errorCode': res });
return;
}
//freePort
let resF = Module._FreePort(g_nPort);
if (resF !== PLAYM4_OK) {
postMessage({ 'function': "FreePort", 'errorCode': res });
return;
}
if (pInputData != null) {
Module._free(pInputData);
pInputData = null;
}
break;
case "PlaySound":
let resPS = Module._PlaySound(g_nPort);
if (resPS !== PLAYM4_OK) {
console.log("PlaySound failed");
return;
}
break;
case "StopSound":
let resSS = Module._StopSound();
if (resSS !== PLAYM4_OK) {
console.log("StopSound failed");
return;
}
break;
case "SetVolume":
let resSV = Module._SetVolume(g_nPort, eventData.volume);
if (resSV !== PLAYM4_OK) {
console.log("Audio SetVolume failed");
return;
}
break;
case "GetVolume":
let volume = Module._GetVolume();
if (volume > 0) {
postMessage({ 'function': "GetVolume", 'volume': volume });
}
else {
console.log("Audio GetVolume failed");
return;
}
break;
case "OnlyPlaySound":
let resOPS = Module._OnlyPlaySound(g_nPort);
if (resOPS !== PLAYM4_OK) {
console.log("OnlyPlaySound failed");
return;
}
break;
case "Pause":
let resPa = Module._Pause(g_nPort, eventData.bPlay);
if (resPa !== PLAYM4_OK) {
console.log("Pause failed");
return;
}
case "PlayRate":
Module._SetPlayRate(g_nPort, eventData.playRate);
break;
case "SetIFrameDecInterval":
Module._SetIFrameDecInterval(g_nPort, eventData.data);
break;
case "SetLostFrameMode":
Module._SetLostFrameMode(g_nPort, eventData.data, 0);
break;
case "SetDemuxModel":
let resSDM = Module._SetDemuxModel(g_nPort, eventData.nIdemuxType, eventData.bTrue);
break;
case "SkipErrorData":
Module._SkipErrorData(g_nPort, eventData.bSkip);
break;
case "SetDecodeERC":
Module._SetDecodeERC(g_nPort, eventData.nLevel);
break;
case "SetANRParam":
Module._SetANRParam(g_nPort, eventData.nEnable, eventData.nANRLevel);
break;
case "SetResampleValue":
Module._SetResampleValue(g_nPort, eventData.nEnable, eventData.resampleValue);
break;
case "GetLastError":
let errorCode = Module._GetLastError(g_nPort);
postMessage({ 'function': "GetLastError", 'errorCode': errorCode });
break;
case "SetGlobalBaseTime":
Module._SetGlobalBaseTime(g_nPort, eventData.year, eventData.month, eventData.day, eventData.hour, eventData.min, eventData.sec, eventData.ms);
break;
case "SetRunTimeInfoCB":
Module._SetRunTimeInfoCallBackEx(g_nPort, eventData.nModuleType, 0);
break;
case "SetStreamInfoCB":
Module._SetStreamInfoCallBack(g_nPort, eventData.nType, 0);
break;
case "ResetBuffer":
Module._JSPlayM4_ResetBuffer(g_nPort, eventData.type);
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;
var iMiSecond = oFrameInfo.misecond
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;
}
let osdTime = {};
osdTime.year = iYear;
osdTime.month = iMonth;
osdTime.week = 0;
osdTime.day = iDay;
osdTime.hour = iHour;
osdTime.minute = iMinute;
osdTime.second = iSecond;
osdTime.milliseconds = iMiSecond;
return osdTime;
//return iYear + "-" + iMonth + "-" + iDay + " " + iHour + ":" + iMinute + ":" + iSecond;
}
// 获取帧数据
function getFrameData() {
// function getFrameData() {
// 获取帧数据
var res = Module._GetFrameData();
//var res = fun();
if (res === PLAYM4_OK) {
var iFrameInfo = Module._GetFrameInfo();
let oFrameInfo = {};
oFrameInfo.frameType = Module.HEAP32[iFrameInfo >> 2];
oFrameInfo.frameSize = Module.HEAP32[iFrameInfo + 4 >> 2];
oFrameInfo.width = Module.HEAP32[iFrameInfo + 8 >> 2];
oFrameInfo.height = Module.HEAP32[iFrameInfo + 12 >> 2];
oFrameInfo.timeStamp = Module.HEAP32[iFrameInfo + 16 >> 2];
oFrameInfo.frameRate = Module.HEAP32[iFrameInfo + 20 >> 2];
oFrameInfo.bitsPerSample = Module.HEAP32[iFrameInfo + 24 >> 2];
oFrameInfo.samplesPerSec = Module.HEAP32[iFrameInfo + 28 >> 2];
oFrameInfo.channels = Module.HEAP32[iFrameInfo + 32 >> 2];
oFrameInfo.frameNum = Module.HEAP32[iFrameInfo + 36 >> 2];
oFrameInfo.cropLeft = Module.HEAP32[iFrameInfo + 40 >> 2];
oFrameInfo.cropRight = Module.HEAP32[iFrameInfo + 44 >> 2];
oFrameInfo.cropTop = Module.HEAP32[iFrameInfo + 48 >> 2];
oFrameInfo.cropBottom = Module.HEAP32[iFrameInfo + 52 >> 2];
oFrameInfo.year = Module.HEAP16[iFrameInfo + 64 >> 1];
oFrameInfo.month = Module.HEAP16[iFrameInfo + 66 >> 1];
oFrameInfo.day = Module.HEAP16[iFrameInfo + 68 >> 1];
oFrameInfo.hour = Module.HEAP16[iFrameInfo + 70 >> 1];
oFrameInfo.minute = Module.HEAP16[iFrameInfo + 72 >> 1];
oFrameInfo.second = Module.HEAP16[iFrameInfo + 74 >> 1];
oFrameInfo.misecond = Module.HEAP16[iFrameInfo + 76 >> 1];
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: video media Info: 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 {
let errorCode = Module._GetLastError(g_nPort);
//解码失败返回裸数据
if (PLAYM4_DECODE_ERROR === errorCode) {
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': errorCode
});
rawInfo = null;
pRawData = null;
aRawData = null;
}
//需要更多数据
if (PLAYM4_NEED_MORE_DATA === errorCode || PLAYM4_SYS_NOT_SUPPORT === errorCode || PLAYM4_NEED_NEET_LOOP === errorCode) {
postMessage({
'function': "GetFrameData", 'type': "", 'data': null,
'dataLen': -1, 'osd': 0, 'frameInfo': null, 'errorCode': errorCode
});
}
return errorCode;
}
}
// 开始计算时间
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

View File

@ -0,0 +1,705 @@
/**
* 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_ORDER_ERROR = 2;
const PLAYM4_DECODE_ERROR = 44 // 解码失败
const PLAYM4_NOT_KEYFRAME = 48; // 非关键帧
const PLAYM4_NEED_MORE_DATA = 31; // 需要更多数据才能解析
const PLAYM4_NEED_NEET_LOOP = 35; //丢帧需要下个循环
const PLAYM4_SYS_NOT_SUPPORT = 16; // 不支持
// 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开关
var g_nPort = -1;
var pInputData = null;
var inputBufferSize = 40960;
self.JSPlayM4_RunTimeInfoCallBack = function (nPort, pstRunTimeInfo, pUser) {
let port = nPort;
let user = pUser;
let nRunTimeModule = Module.HEAP32[pstRunTimeInfo >> 2];
let nStrVersion = Module.HEAP32[pstRunTimeInfo + 4 >> 2];
let nFrameTimeStamp = Module.HEAP32[pstRunTimeInfo + 8 >> 2];
let nFrameNum = Module.HEAP32[pstRunTimeInfo + 12 >> 2];
let nErrorCode = Module.HEAP32[pstRunTimeInfo + 16 >> 2];
// console.log("nRunTimeModule:"+nRunTimeModule+",nFrameNum:"+nFrameNum+",nErrorCode:"+nErrorCode);
postMessage({ 'function': "RunTimeInfoCallBack", 'nRunTimeModule': nRunTimeModule, 'nStrVersion': nStrVersion, 'nFrameTimeStamp': nFrameTimeStamp, 'nFrameNum': nFrameNum, 'nErrorCode': nErrorCode });
}
self.JSPlayM4_StreamInfoCallBack = function (nPort, pstStreamInfo, pUser)
{
let port = nPort;
let user = pUser;
let nSystemformat = Module.HEAP16[pstStreamInfo >> 1]; //封装类型
let nVideoformat = Module.HEAP16[pstStreamInfo + 2 >> 1];//视频编码类型
let nAudioformat = Module.HEAP16[pstStreamInfo + 4 >> 1];//音频编码类型
let nAudiochannels = Module.HEAP16[pstStreamInfo + 6 >> 1]; //音频通道数
let nAudiobitspersample = Module.HEAP32[pstStreamInfo + 8 >> 2];//音频样位率
let nAudiosamplesrate = Module.HEAP32[pstStreamInfo + 12 >> 2];//音频采样率
let nAudiobitrate = Module.HEAP32[pstStreamInfo + 16 >> 2];//音频比特率,单位bit
//console.log("nSystemformat:" + nSystemformat + ",nVideoformat:" + nVideoformat + ",nAudioformat:" + nAudioformat + ",nAudiochannels:" + nAudiochannels + ",nAudiobitspersample:" + nAudiobitspersample + ",nAudiosamplesrate:" + nAudiosamplesrate + ",nAudiobitrate:" + nAudiobitrate);
postMessage({ 'function': "StreamInfoCallBack", 'nSystemformat': nSystemformat, 'nVideoformat': nVideoformat, 'nAudioformat': nAudioformat, 'nAudiochannels': nAudiochannels, 'nAudiobitspersample': nAudiobitspersample, 'nAudiosamplesrate': nAudiosamplesrate, 'nAudiobitrate': nAudiobitrate});
}
onmessage = function (event) {
var eventData = event.data;
var res = 0;
switch (eventData.command) {
case "importScripts":
const decodebase = eventData.data + "Decoder.js"
importScripts(decodebase);
Module.addOnPostRun(function () {
postMessage({ 'function': "loaded" });
});
break;
case "printLog":
let downloadFlag = eventData.data;
if (downloadFlag === true) {
bWorkerPrintLog = true;
res = Module._SetPrintLogFlag(g_nPort, downloadFlag);
}
else {
bWorkerPrintLog = false;
res = Module._SetPrintLogFlag(g_nPort, 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":
//获取端口号
g_nPort = Module._GetPort();
//设置流打开模式
iStreamMode = eventData.data;
res = Module._SetStreamOpenMode(g_nPort, 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(new Uint8Array(eventData.data));
res = Module._OpenStream(g_nPort, pHead, iHeadLen, eventData.bufPoolSize);
postMessage({ 'function': "OpenStream", 'errorCode': res });
if (res !== PLAYM4_OK) {
//释放内存
Module._free(pHead);
pHead = null;
return;
}
bOpenStream = true;
break;
case "Play":
let resP = Module._Play(g_nPort);
if (resP !== PLAYM4_OK) {
return;
}
break;
case "InputData":
// 接收到的数据
var iLen = eventData.dataSize;
if (iLen > 0) {
if (pInputData == null || iLen > inputBufferSize) {
if (pInputData != null) {
Module._free(pInputData);
pInputData = null;
}
if (iLen > inputBufferSize) {
inputBufferSize = iLen;
}
pInputData = Module._malloc(inputBufferSize);
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(g_nPort, pInputData, iLen);
if (res !== PLAYM4_OK) {
let errorCode = Module._GetLastError(g_nPort);
let sourceRemain = Module._GetSourceBufferRemain(g_nPort);
postMessage({ 'function': "InputData", 'errorCode': errorCode, "sourceRemain": sourceRemain });
}
//Module._free(pInputData);
//pInputData = null;
} else {
let sourceRemain = Module._GetSourceBufferRemain(g_nPort);
if (sourceRemain == 0) {
postMessage({ 'function': "InputData", 'errorCode': PLAYM4_NEED_MORE_DATA });
return;
}
}
/////////////////////
// if (funGetFrameData === null) {
// funGetFrameData = Module.cwrap('GetFrameData', 'number');
// }
while (bOpenMode && bOpenStream) {
var ret = getFrameData();
// 直到获取视频帧或数据不足为止
if (PLAYM4_VIDEO_FRAME === ret || PLAYM4_NEED_MORE_DATA === ret || PLAYM4_ORDER_ERROR === ret)//PLAYM4_VIDEO_FRAME === ret || || PLAYM4_NEED_NEET_LOOP === 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);
let u8array = new Uint8Array(keyLen);
aKeyData.set(u8array, 0);
aKeyData.set(new Uint8Array(bufData));
aKeyData = null;
u8array = null;
res = Module._SetSecretKey(g_nPort, 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 = {
left: eventData.left,
top: eventData.top,
right: eventData.right,
bottom: eventData.bottom
};
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(g_nPort, 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 = {
left: eventData.left,
top: eventData.top,
right: eventData.right,
bottom: eventData.bottom
};
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(g_nPort, 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(g_nPort, nFrameType);
if (res !== PLAYM4_OK) {
postMessage({ 'function': "SetDecodeFrameType", 'errorCode': res });
return;
}
break;
case "CloseStream":
//stop
let resS = Module._Stop(g_nPort);
if (resS !== PLAYM4_OK) {
postMessage({ 'function': "Stop", 'errorCode': res });
return;
}
//closeStream
res = Module._CloseStream(g_nPort);
if (res !== PLAYM4_OK) {
postMessage({ 'function': "CloseStream", 'errorCode': res });
return;
}
//freePort
let resF = Module._FreePort(g_nPort);
if (resF !== PLAYM4_OK) {
postMessage({ 'function': "FreePort", 'errorCode': res });
return;
}
if (pInputData != null) {
Module._free(pInputData);
pInputData = null;
}
break;
case "PlaySound":
let resPS = Module._PlaySound(g_nPort);
if (resPS !== PLAYM4_OK) {
console.log("PlaySound failed");
return;
}
break;
case "StopSound":
let resSS = Module._StopSound();
if (resSS !== PLAYM4_OK) {
console.log("StopSound failed");
return;
}
break;
case "SetVolume":
let resSV = Module._SetVolume(g_nPort, eventData.volume);
if (resSV !== PLAYM4_OK) {
console.log("Audio SetVolume failed");
return;
}
break;
case "GetVolume":
let volume = Module._GetVolume();
if (volume > 0) {
postMessage({ 'function': "GetVolume", 'volume': volume });
}
else {
console.log("Audio GetVolume failed");
return;
}
break;
case "OnlyPlaySound":
let resOPS = Module._OnlyPlaySound(g_nPort);
if (resOPS !== PLAYM4_OK) {
console.log("OnlyPlaySound failed");
return;
}
break;
case "Pause":
let resPa = Module._Pause(g_nPort, eventData.bPlay);
if (resPa !== PLAYM4_OK) {
console.log("Pause failed");
return;
}
case "PlayRate":
Module._SetPlayRate(g_nPort, eventData.playRate);
break;
case "SetIFrameDecInterval":
Module._SetIFrameDecInterval(g_nPort, eventData.data);
break;
case "SetLostFrameMode":
Module._SetLostFrameMode(g_nPort, eventData.data, 0);
break;
case "SetDemuxModel":
let resSDM = Module._SetDemuxModel(g_nPort, eventData.nIdemuxType, eventData.bTrue);
break;
case "SkipErrorData":
Module._SkipErrorData(g_nPort, eventData.bSkip);
break;
case "SetDecodeERC":
Module._SetDecodeERC(g_nPort, eventData.nLevel);
break;
case "SetANRParam":
Module._SetANRParam(g_nPort, eventData.nEnable, eventData.nANRLevel);
break;
case "SetResampleValue":
Module._SetResampleValue(g_nPort, eventData.nEnable, eventData.resampleValue);
break;
case "GetLastError":
let errorCode = Module._GetLastError(g_nPort);
postMessage({ 'function': "GetLastError", 'errorCode': errorCode });
break;
case "SetGlobalBaseTime":
Module._SetGlobalBaseTime(g_nPort, eventData.year, eventData.month, eventData.day, eventData.hour, eventData.min, eventData.sec, eventData.ms);
break;
case "SetRunTimeInfoCB":
Module._SetRunTimeInfoCallBackEx(g_nPort, eventData.nModuleType, 0);
break;
case "SetStreamInfoCB":
Module._SetStreamInfoCallBack(g_nPort, eventData.nType, 0);
break;
case "ResetBuffer":
Module._JSPlayM4_ResetBuffer(g_nPort, eventData.type);
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;
var iMiSecond = oFrameInfo.misecond
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;
}
let osdTime = {};
osdTime.year = iYear;
osdTime.month = iMonth;
osdTime.week = 0;
osdTime.day = iDay;
osdTime.hour = iHour;
osdTime.minute = iMinute;
osdTime.second = iSecond;
osdTime.milliseconds = iMiSecond;
return osdTime;
//return iYear + "-" + iMonth + "-" + iDay + " " + iHour + ":" + iMinute + ":" + iSecond;
}
// 获取帧数据
function getFrameData() {
// function getFrameData() {
// 获取帧数据
var res = Module._GetFrameData();
//var res = fun();
if (res === PLAYM4_OK) {
var iFrameInfo = Module._GetFrameInfo();
let oFrameInfo = {};
oFrameInfo.frameType = Module.HEAP32[iFrameInfo >> 2];
oFrameInfo.frameSize = Module.HEAP32[iFrameInfo + 4 >> 2];
oFrameInfo.width = Module.HEAP32[iFrameInfo + 8 >> 2];
oFrameInfo.height = Module.HEAP32[iFrameInfo + 12 >> 2];
oFrameInfo.timeStamp = Module.HEAP32[iFrameInfo + 16 >> 2];
oFrameInfo.frameRate = Module.HEAP32[iFrameInfo + 20 >> 2];
oFrameInfo.bitsPerSample = Module.HEAP32[iFrameInfo + 24 >> 2];
oFrameInfo.samplesPerSec = Module.HEAP32[iFrameInfo + 28 >> 2];
oFrameInfo.channels = Module.HEAP32[iFrameInfo + 32 >> 2];
oFrameInfo.frameNum = Module.HEAP32[iFrameInfo + 36 >> 2];
oFrameInfo.cropLeft = Module.HEAP32[iFrameInfo + 40 >> 2];
oFrameInfo.cropRight = Module.HEAP32[iFrameInfo + 44 >> 2];
oFrameInfo.cropTop = Module.HEAP32[iFrameInfo + 48 >> 2];
oFrameInfo.cropBottom = Module.HEAP32[iFrameInfo + 52 >> 2];
oFrameInfo.year = Module.HEAP16[iFrameInfo + 64 >> 1];
oFrameInfo.month = Module.HEAP16[iFrameInfo + 66 >> 1];
oFrameInfo.day = Module.HEAP16[iFrameInfo + 68 >> 1];
oFrameInfo.hour = Module.HEAP16[iFrameInfo + 70 >> 1];
oFrameInfo.minute = Module.HEAP16[iFrameInfo + 72 >> 1];
oFrameInfo.second = Module.HEAP16[iFrameInfo + 74 >> 1];
oFrameInfo.misecond = Module.HEAP16[iFrameInfo + 76 >> 1];
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: video media Info: 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 {
let errorCode = Module._GetLastError(g_nPort);
//解码失败返回裸数据
if (PLAYM4_DECODE_ERROR === errorCode) {
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': errorCode
});
rawInfo = null;
pRawData = null;
aRawData = null;
}
//需要更多数据
if (PLAYM4_NEED_MORE_DATA === errorCode || PLAYM4_SYS_NOT_SUPPORT === errorCode || PLAYM4_NEED_NEET_LOOP === errorCode) {
postMessage({
'function': "GetFrameData", 'type': "", 'data': null,
'dataLen': -1, 'osd': 0, 'frameInfo': null, 'errorCode': errorCode
});
}
return errorCode;
}
}
// 开始计算时间
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

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1 @@
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1 @@
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,126 @@
importScripts('libSystemTransform.js');
const RECORDRTP = 0; //录制一份未经过转封装的码流原始数据,用于定位问题
let dataType = 1;
// 转封装库回调函数
self.STCallBack = function (fileIndex,indexLen, data, dataLen)
{
//stFrameInfo的类型见DETAIL_FRAME_INFO
let stFrameInfo = Module._GetDetialFrameInfo();
let nIsMp4Index = stFrameInfo.nIsMp4Index;
//console.log("FrameType is " , stFrameInfo);
//console.log("nIsMp4Index is " + nIsMp4Index);
//debugger
var pData = null;
pData = new Uint8Array(dataLen);
pData.set(Module.HEAPU8.subarray(data, data + dataLen));
if (dataType === 1) {
if (pData[0] == 0x49 && pData[1] == 0x4d && pData[2] == 0x4b && pData[3] == 0x48) {//码流头丢掉
return;
}
postMessage({type: "outputData", buf: pData, dType: 1});
dataType = 2;
} else {
if (nIsMp4Index) {
postMessage({type: "outputData", buf: pData, dType: 6}); //6索引类型
} else {
postMessage({type: "outputData", buf: pData, dType: 2}); //2:码流
}
}
//stFrameInfo的类型见DETAIL_FRAME_INFO
//let stFrameInfo = Module._GetDetialFrameInfo();
//let stFrameType = stFrameInfo.nFrameType;
//let nFrameNum = stFrameInfo.nFrameNum;
//let nTimeStamp = stFrameInfo.nTimeStamp;
//let nIsMp4Index = stFrameInfo.nIsMp4Index;
//console.log("FrameType is " + stFrameType);
//console.log("nIsMp4Index is " + nIsMp4Index);
}
// self.Module = { memoryInitializerRequest: loadMemInitFile(), TOTAL_MEMORY: 128*1024*1024 };
// importScripts('SystemTransform.js');
self.Module['onRuntimeInitialized'] = function (){
postMessage({type: "loaded"});
}
onmessage = function (e) {
var data = e.data;
if ("create" === data.type) {
if (RECORDRTP) {
postMessage({type: "created"});
postMessage({type: "outputData", buf: data.buf, dType: 1});
} else {
var iHeadLen = data.len;
var pHead = Module._malloc(iHeadLen);
self.writeArrayToMemory(new Uint8Array(data.buf), pHead);
var iTransType = data.packType;//目标格式
var iRet = Module._CreatHandle(pHead, iTransType, 4096);
if (iRet != 0) {
console.log("_CreatHandle failed!" + iRet);
} else {
iRet = Module._SysTransRegisterDataCallBack();
if(iRet != 0)
{
console.log("_SysTransRegisterDataCallBack Failed:" + iRet);
}
if (iTransType === 5) {//转mp4支持私有帧打入
iRet = Module._SysTransEnableCapacity(7)
if(iRet != 0)
{
console.log("_SysTransSetGlobalTime Failed:" + iRet);
}
}
iRet = Module._SysTransStart(null, null);
if(iRet != 0)
{
console.log("_SysTransStart Failed:" + iRet);
}
postMessage({type: "created"});
}
}
} else if ("inputData" === data.type) {
if (RECORDRTP) {
var aFileData = new Uint8Array(data.buf); // 拷贝一份
var iBufferLen = aFileData.length;
var szBufferLen = iBufferLen.toString(16);
if (szBufferLen.length === 1) {
szBufferLen = "000" + szBufferLen;
} else if (szBufferLen.length === 2) {
szBufferLen = "00" + szBufferLen;
} else if (szBufferLen.length === 3) {
szBufferLen = "0" + szBufferLen;
}
var aData = [0, 0, parseInt(szBufferLen.substring(0, 2), 16), parseInt(szBufferLen.substring(2, 4), 16)];
for(var iIndex = 0, iDataLength = aFileData.length; iIndex < iDataLength; iIndex++) {
aData[iIndex + 4] = aFileData[iIndex]
}
var dataUint8 = new Uint8Array(aData);
postMessage({type: "outputData", buf: dataUint8.buffer, dType: 2});
} else {
let pInputDataBuf = Module._malloc(data.len);
var idataLen = data.len;
self.writeArrayToMemory(new Uint8Array(data.buf), pInputDataBuf);
// 输入数据每次最多2m
let pp = Module._SysTransInputData(0, pInputDataBuf, idataLen);
if(pp != 0) {
//console.log("InputData Failed:" + pp);
}
Module._free(pInputDataBuf);
}
} else if ("release" === data.type) {
var iRet = Module._SysTransStop();
if (iRet != 0) {
console.log("_SysTransStop Failed:", iRet);
}
Module._SysTransRelease();
if (iRet != 0) {
console.log("_SysTransRelease Failed:", iRet);
}
close();
}
};

389
client/public/js/webrtc.js Normal file
View File

@ -0,0 +1,389 @@
class Webrtc {
/*******
* @name:
* @description:
* @param {object} InitialData 以下数据的对象
* @param {string} element 标签dom
* @param {boolean} debug 是否打印日志
* @param {string} zlmsdpUrl 流地址
* @param {boolean} simulcast 无线电和电视同步播放
* @param {boolean} useCamera 是否使用摄像头
* @param {boolean} audioEnable 音频数据
* @param {boolean} videoEnable 视频数据
* @param {boolean} recvOnly true是拉流 false是推流
* @param {object} resolution { w: 3840, h: 2160 } 分辨率
* @param {boolean} usedatachannel //数据通道
* @param {*} player webrtc实例
* @return {*}
* @author:
*/
/*
let InitialData = {
element:element,
debug:debug,
zlmsdpUrl:zlmsdpUrl,
simulcast:simulcast,
useCamera:useCamera,
audioEnable:audioEnable,
videoEnable:videoEnable,
recvOnly:recvOnly,
resolution:resolution,
usedatachannel:usedatachannel,
}
*/
constructor(InitialData) {
this.element = InitialData.element
this.debug = InitialData.debug
this.zlmsdpUrl = InitialData.zlmsdpUrl
this.simulcast = InitialData.simulcast
this.useCamera = InitialData.useCamera
this.audioEnable = InitialData.audioEnable
this.videoEnable = InitialData.videoEnable
this.recvOnly = InitialData.recvOnly
this.resolution = InitialData.resolution
this.usedatachannel = InitialData.usedatachannel
this.player = null
this.eventHandlers = {}
}
// 检测摄像头分辨率
detection() {
return new Promise((resolve, reject) => {
navigator.mediaDevices.enumerateDevices().then(devices => {
devices = devices.filter(d => d.kind === 'videoinput')
let creamData = devices[0].getCapabilities()
console.log(creamData, 'creamData')
let resolution = {}
resolution.w = creamData.width.max
resolution.h = creamData.height.max
resolve(resolution)
// this.resolution = resolution
}).catch((err) => {
console.log(err)
reject(err)
// this.resolution = resolution
})
})
}
// 拉流
start_play() {
return new Promise((resolve, reject) => {
let this_ = this
this.push_url = null
this.pull_url = null
let ZLMRTCClient = ZLMRTCClient_({})
if (this.useCamera) {
this.detection().then((resolution) => {
this.player = new ZLMRTCClient.Endpoint({
element: this.element,
debug: this.debug,
zlmsdpUrl: this.zlmsdpUrl,
simulcast: this.simulcast,
useCamera: this.useCamera,
audioEnable: this.audioEnable,
videoEnable: this.videoEnable,
recvOnly: this.recvOnly,
resolution: resolution,
usedatachannel: this.usedatachannel,
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR, function (e) { // ICE 协商出错
console.log('ICE 协商出错')
reject()
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS, function (e) { //获取到了远端流,可以播放
console.log('播放成功', e.streams, e, this_.zlmsdpUrl)
this_.pull_url = e.streams[0]
// resolve(e.streams[0])
})
this.player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, function (e) { // offer anwser 交换失败
console.log('offer anwser 交换失败', e)
this_.stop_play(reject, 'offer anwser 交换失败')
})
// WEBRTC_IS_H265
this.player.on(ZLMRTCClient.Events.WEBRTC_IS_H265, function (e) { // offer anwser 交换失败
console.log('H265视频格式', e)
this_.stop_play(reject, '右上角设置打开插件模式以支持H265')
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM, function (s) { // 获取到了本地流
console.log('获取到了本地流')
this_.push_url = s
// resolve(s)
})
this.player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED, function (s) { // 获取本地流失败
console.log('获取本地流失败', s)
this_.stop_play(reject, '获取本地流失败')
})
/**
*new表示刚创建一个新的 WebRTC 对象
connecting表示正在建立连接
connected表示已经成功建立连接
disconnected表示连接已经中断
failed表示连接失败
closed表示连接已经关闭
have-local-offer表示本地已经创建了一个 offer
have-remote-offer表示远程端已经创建了一个 offer
stable表示连接已经稳定
have-local-pranswer表示本地已经创建了一个 pranswer
have-remote-pranswer表示远程端已经创建了一个 pranswer
* */
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE, function (state) { // RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
console.log('当前状态==>', state)
if (state == 'connected') {
if (this_.push_url) {
resolve(this_.push_url)
} else if (this_.pull_url) {
resolve(this_.pull_url)
}
} else {
this_.triggerEvent(state)
}
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_OPEN, function (event) {
console.log('rtc datachannel 打开 :', event)
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_MSG, function (event) {
console.log('rtc datachannel 消息 :', event.data)
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_ERR, function (event) {
console.log('rtc datachannel 错误 :', event)
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_CLOSE, function (event) {
console.log('rtc datachannel 关闭 :', event)
})
}).catch(() => {
this.player = new ZLMRTCClient.Endpoint({
element: this.element,
debug: this.debug,
zlmsdpUrl: this.zlmsdpUrl,
simulcast: this.simulcast,
useCamera: this.useCamera,
audioEnable: this.audioEnable,
videoEnable: this.videoEnable,
recvOnly: this.recvOnly,
resolution: this.resolution,
usedatachannel: this.usedatachannel,
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR, function (e) { // ICE 协商出错
console.log('ICE 协商出错')
reject()
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS, function (e) { //获取到了远端流,可以播放
console.log('播放成功', e.streams, e, this_.zlmsdpUrl)
this_.pull_url = e.streams[0]
// resolve(e.streams[0])
})
this.player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, function (e) { // offer anwser 交换失败
console.log('offer anwser 交换失败', e)
this_.stop_play(reject, 'offer anwser 交换失败')
})
// WEBRTC_IS_H265
this.player.on(ZLMRTCClient.Events.WEBRTC_IS_H265, function (e) { // offer anwser 交换失败
console.log('H265视频格式', e)
this_.stop_play(reject, '右上角设置打开插件模式以支持H265')
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM, function (s) { // 获取到了本地流
console.log('获取到了本地流')
this_.push_url = s
// resolve(s)
})
this.player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED, function (s) { // 获取本地流失败
console.log('获取本地流失败', s)
this_.stop_play(reject, '获取本地流失败')
})
/**
*new表示刚创建一个新的 WebRTC 对象
connecting表示正在建立连接
connected表示已经成功建立连接
disconnected表示连接已经中断
failed表示连接失败
closed表示连接已经关闭
have-local-offer表示本地已经创建了一个 offer
have-remote-offer表示远程端已经创建了一个 offer
stable表示连接已经稳定
have-local-pranswer表示本地已经创建了一个 pranswer
have-remote-pranswer表示远程端已经创建了一个 pranswer
* */
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE, function (state) { // RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
console.log('当前状态==>', state)
if (state == 'connected') {
if (this_.push_url) {
resolve(this_.push_url)
} else if (this_.pull_url) {
resolve(this_.pull_url)
}
} else {
this_.triggerEvent(state)
}
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_OPEN, function (event) {
console.log('rtc datachannel 打开 :', event)
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_MSG, function (event) {
console.log('rtc datachannel 消息 :', event.data)
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_ERR, function (event) {
console.log('rtc datachannel 错误 :', event)
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_CLOSE, function (event) {
console.log('rtc datachannel 关闭 :', event)
})
})
} else {
this.player = new ZLMRTCClient.Endpoint({
element: this.element,
debug: this.debug,
zlmsdpUrl: this.zlmsdpUrl,
simulcast: this.simulcast,
useCamera: this.useCamera,
audioEnable: this.audioEnable,
videoEnable: this.videoEnable,
recvOnly: this.recvOnly,
resolution: this.resolution,
usedatachannel: this.usedatachannel,
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR, function (e) { // ICE 协商出错
console.log('ICE 协商出错')
reject()
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS, function (e) { //获取到了远端流,可以播放
console.log('播放成功', e.streams, e, this_.zlmsdpUrl)
this_.pull_url = e.streams[0]
// resolve(e.streams[0])
})
this.player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, function (e) { // offer anwser 交换失败
console.log('offer anwser 交换失败', e)
this_.stop_play(reject, 'offer anwser 交换失败')
})
// WEBRTC_IS_H265
this.player.on(ZLMRTCClient.Events.WEBRTC_IS_H265, function (e) { // offer anwser 交换失败
console.log('H265视频格式', e)
this_.stop_play(reject, '右上角设置打开插件模式以支持H265')
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM, function (s) { // 获取到了本地流
console.log('获取到了本地流')
this_.push_url = s
// resolve(s)
})
this.player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED, function (s) { // 获取本地流失败
console.log('获取本地流失败', s)
this_.stop_play(reject, '获取本地流失败')
})
/**
*new表示刚创建一个新的 WebRTC 对象
connecting表示正在建立连接
connected表示已经成功建立连接
disconnected表示连接已经中断
failed表示连接失败
closed表示连接已经关闭
have-local-offer表示本地已经创建了一个 offer
have-remote-offer表示远程端已经创建了一个 offer
stable表示连接已经稳定
have-local-pranswer表示本地已经创建了一个 pranswer
have-remote-pranswer表示远程端已经创建了一个 pranswer
* */
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE, function (state) { // RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
console.log('当前状态==>', state)
if (state == 'connected') {
this_.player.pc.onjitterBuffer()
if (this_.push_url) {
resolve(this_.push_url)
} else if (this_.pull_url) {
resolve(this_.pull_url)
}
} else {
this_.triggerEvent(state)
}
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_OPEN, function (event) {
console.log('rtc datachannel 打开 :', event)
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_MSG, function (event) {
console.log('rtc datachannel 消息 :', event.data)
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_ERR, function (event) {
console.log('rtc datachannel 错误 :', event)
})
this.player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_CLOSE, function (event) {
console.log('rtc datachannel 关闭 :', event)
})
}
})
}
// 拉流失败的回调
stop_play(reject, msg) {
if (this.player) {
this.player.close()
this.player = null
}
reject && reject(msg)
}
// 关闭拉流
close_play(remote1) {
return new Promise((resolve, reject) => {
console.log('关闭拉流或者推流')
if (this.player) {
this.player.close()
this.player = null
if (remote1) {
remote1.srcObject = null
remote1.load()
}
}
resolve()
})
}
on(eventName, eventHandler) {
if (!this.eventHandlers[eventName]) {
this.eventHandlers[eventName] = []
}
this.eventHandlers[eventName].push(eventHandler)
}
triggerEvent(eventName) {
const handlers = this.eventHandlers[eventName]
console.log(handlers)
if (handlers) {
handlers.forEach((handler) => {
handler()
})
}
}
}

BIN
client/public/laspb.docx Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
@font-face {
font-family: 'YEFONTAoYeHei';
src: url('/font/YEFONTAoYeHei.ttf') format('truetype');
font-display: swap;
}

View File

@ -0,0 +1,96 @@
.first-loading-wrp {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 90vh;
min-height: 90vh;
}
.first-loading-wrp > h1 {
font-size: 28px;
font-weight: bolder;
}
.first-loading-wrp .loading-wrp {
display: flex;
align-items: center;
justify-content: center;
padding: 98px;
}
.dot {
position: relative;
box-sizing: border-box;
display: inline-block;
width: 64px;
height: 64px;
font-size: 64px;
transform: rotate(45deg);
animation: antRotate 1.2s infinite linear;
}
.dot i {
position: absolute;
display: block;
width: 28px;
height: 28px;
background-color: #1890ff;
border-radius: 100%;
opacity: 0.3;
transform: scale(0.75);
transform-origin: 50% 50%;
animation: antSpinMove 1s infinite linear alternate;
}
.dot i:nth-child(1) {
top: 0;
left: 0;
}
.dot i:nth-child(2) {
top: 0;
right: 0;
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s;
}
.dot i:nth-child(3) {
right: 0;
bottom: 0;
-webkit-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.dot i:nth-child(4) {
bottom: 0;
left: 0;
-webkit-animation-delay: 1.2s;
animation-delay: 1.2s;
}
@keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg);
}
}
@-webkit-keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg);
}
}
@keyframes antSpinMove {
to {
opacity: 1;
}
}
@-webkit-keyframes antSpinMove {
to {
opacity: 1;
}
}

View File

@ -0,0 +1 @@
v1.3.1

1
client/public/vite.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB