大华sdk调用CLIENT_SetRealDataCallBackEx回调函数的相关问题

CLIENT_SetRealDataCallBackEx回调函数:

/**
	 * 实时监视数据回调函数--扩展(pBuffer内存由SDK内部申请释放)
	 */
	private static class CbfRealDataCallBackEx implements NetSDKLib.fRealDataCallBackEx {
		private CbfRealDataCallBackEx() {
		}

		private static class CallBackHolder {
			private static AutoRegisterModule.CbfRealDataCallBackEx instance
					= new AutoRegisterModule.CbfRealDataCallBackEx();
		}

		public static AutoRegisterModule.CbfRealDataCallBackEx getInstance() {
			return AutoRegisterModule.CbfRealDataCallBackEx.CallBackHolder.instance;
		}

		@Override
		public void invoke(LLong lRealHandle, int dwDataType, Pointer pBuffer,
						   int dwBufSize, int param, Pointer dwUser) throws IOException {
			int bInput=0;
			if(0 != lRealHandle.longValue())
			{
				switch(dwDataType) {
					case 0:
//
						System.out.println("码流大小为" + ToolKits.GetPointerDataToByteArr(pBuffer)+ "\n" + "码流类型为原始音视频混合数据");
						break;
					case 1:
						//标准视频数据

						break;
					case 2:
						//yuv 数据
						System.out.println("yuv码流大小为" + "\n" + "码流类型为原始音视频混合数据");
						break;
					case 3:
						//pcm 音频数据

						break;
					case 4:
						//原始音频数据

						break;
					default:
						break;
				}
			}
		}
	}

pBuffer为监视数据块地址 ,dwBufSize 为监视数据块的长度;

现在获取到了pBuffer,该如何转成H264裸码流?

参考的是:https://blog.csdn.net/zb95731/article/details/114282803

但是直接跳过解析的这步,想问问之后该怎么做

 

你有没有H264解码的JAR包呢?如果没有的话要先找一个。

同问。楼主有思路么

普通sdk接口只会出大华私有码流,配套使用大华playsdk才能播放,如果需要标准流,需要调用CLIENT_RealPlayByDataType接口才能转成标准码流,不过需要大华提供转码库,默认下载不到的

CLIENT_RealPlayByDataType 使用这个方法,然后回调码流类型选用GBPS,PS封装数据包,自己再打上RTP包头,>1400的包分开发送到zlmediakit 10000端口就能生成流,如果光取es裸码流,就解ps包就可以,参考以下javascript代码

//解析 PS 获取Nalus video/audio/streaminfo
static parseMpegPSPacket(buf, offset) {

    let position = offset || 0;

    //PSM 编码信息
    let streaminfo = {};

    //PES-video-payload-nalus
    let naluscache = Buffer.alloc(0);

    //PES-audio-payload
    let audiocache = Buffer.alloc(0);

    //读取PES
    while (buf.length - 6 > position) {

        let Identifier = buf.readUInt32BE(position);

        position += 4;

        if (Identifier == 0x01ba) {

            //系统时钟基准(6)+PS复用速率(4 position += 9;

            //填充头长度
            let pack_stuffing_length = (buf.readUInt8(position) & 0x07);

            position += 1;
            position += pack_stuffing_length;

            if (position > buf.length)
                break;
        }

        //System Header 0xbb
        if (Identifier == 0x01bb) {

            //系统标题头长度
            let header_length = (buf.readUInt8(position) << 8 | buf.readUInt8(position + 1));
            position += 2;
            position += header_length;

            if (position > buf.length)
                break;
        }

        //PSM 0xbc 解包判断音/视频编码 类型
        if (Identifier == 0x01bc) {

            //PES-length
            let pes_packet_length = (buf.readUInt8(position) << 8 | buf.readUInt8(position + 1));
            position += 2;

            let program_stream_info_length = buf.readUInt16BE(position + 2);
            let elementary_stream_map_length = buf.readUInt16BE(position + 4);

            let start = 6 + program_stream_info_length;
            let end = 6 + program_stream_info_length + elementary_stream_map_length;

            while (start < end) {

                let stream_type = buf.readUInt8(position + start++);
                let elementary_stream_id = buf.readUInt8(position + start++);
                let elmentary_stream_info_length = buf.readUInt8(position + start++) << 8 | buf.readUInt8(position + start++);

                if (elementary_stream_id == 0xc0)
                    streaminfo.audio = stream_type;

                if (elementary_stream_id == 0xe0)
                    streaminfo.video = stream_type;

                start += elmentary_stream_info_length;
            }

            position += pes_packet_length;

            if (position > buf.length)
                break;
        }

        if (Identifier >= 0x01e0 && Identifier <= 0x01ef) {

            //PES-length
            let pes_packet_length = (buf.readUInt8(position) << 8 | buf.readUInt8(position + 1));
            position += 2;

            //PES packet header
            let pes_header_length = buf.readUInt8(position + 2) + 3;
            //视频数据
            let data = buf.slice(position + pes_header_length, position + pes_packet_length);

            naluscache = Buffer.concat([naluscache, data]);

            position += pes_packet_length;

            if (position > buf.length)
                break;
        }

        if (Identifier >= 0x01c0 && Identifier <= 0x01df) {

            //PES-length
            let pes_packet_length = (buf.readUInt8(position) << 8 | buf.readUInt8(position + 1));
            position += 2;

            //PES packet header
            let pes_header_length = buf.readUInt8(position + 2) + 3;
            //音频数据
            let data = buf.slice(position + pes_header_length, position + pes_packet_length);
            audiocache = Buffer.concat([audiocache, data]);

            position += pes_packet_length;

            if (position > buf.length)
                break;
        }
    }

    //读取完毕分析nalus
    position = 0;

    let indexs = [];

    //视频Nalues
    let nalus = [];

    while (naluscache.length - 4 > position) {

        if (naluscache.readUInt32BE(position) == 1) {
            indexs.push(position);
            position += 4;

            if (indexs.length > 1) {
                let nalu = naluscache.slice(indexs[indexs.length - 2] + 4, indexs[indexs.length - 1]);

                nalus.push(nalu);
            }
        }

        position++;
    }

    if (indexs.length > 0) {
        let nalu = naluscache.slice(indexs[indexs.length - 1] + 4);
        nalus.push(nalu);
    }

    return { video: nalus, audio: audiocache, streaminfo: streaminfo };
}

还有一个办法就是解大华私有封包,DHAV--dhav,再从里面取出es裸码流,可以参考https://www.secrss.com/articles/6712

您好,我是有问必答小助手,您的问题已经有小伙伴解答了,您看下是否解决,可以追评进行沟通哦~

如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~

ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632