设备型号 DS-2CD2T26XM-LGLE
主控版本: V5.5.800 build 210816
isup 协议版本最高 4.0
4g物联网有流量,没插网线
现参考的ISUP SDK demo,但不知道如何获取实时流
如何拿到它的PS封装流推送到web显示?
或者如何将PS流转为rtsp其他流进行推送?
参考GPT的不采纳
之前使用过海康威视的SDK开发,记得有个rtsp视频流的地址的啊,直接使用那个地址,配合javacv抓取这个视频流进行推送,流服务器使用rtmp+nginx实现的。web端显示的话,可以在rtmp中配置直播流,web端嵌入个播放器播放。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
获取实时流可以通过海康威视ISUP SDK提供的接口实现。以下为获取实时流的基本步骤:
// 初始化SDK
HCNetSDK.INSTANCE.NET_DVR_Init();
// 登录设备
HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
int userId = HCNetSDK.INSTANCE.NET_DVR_Login_V40("10.0.0.1", (short) 8000, "admin", "password", deviceInfo);
// 设置预览参数
HCNetSDK.NET_DVR_PREVIEWINFO previewInfo = new HCNetSDK.NET_DVR_PREVIEWINFO();
previewInfo.hPlayWnd = new NativeLong(0); // 预览窗口句柄,为0表示不显示预览窗口
previewInfo.lChannel = new NativeLong(1); // 预览通道号
previewInfo.dwStreamType = 1; // 码流类型,1为主码流,2为子码流
previewInfo.dwLinkMode = 0; // 连接方式,0为TCP方式,1为UDP方式,2为多播方式
previewInfo.bBlocked = true; // 是否阻塞
// 开始预览
NativeLong lRealHandle = HCNetSDK.INSTANCE.NET_DVR_RealPlay_V40(userId, previewInfo, null);
// 设置获取实时流的回调函数
HCNetSDK.FRealDataCallBack_V30 fRealDataCallBack = (lRealHandle, dwDataType, pBuffer, dwBufSize, dwUser) -> {
// 将实时流数据转换为PS封装流,并推送到web端显示
// 获取PS封装流的代码示例(假设实时流数据已保存在byte数组buffer中)
byte[] psStreamData = getPsStreamData(buffer, dwBufSize);
// 将PS封装流推送到web端的代码示例
// ...
};
boolean res = HCNetSDK.INSTANCE.NET_DVR_SetRealData_V30(lRealHandle, fRealDataCallBack, null);
// 停止预览
HCNetSDK.INSTANCE.NET_DVR_StopRealPlay(lRealHandle);
// 注销设备
HCNetSDK.INSTANCE.NET_DVR_Logout(userId);
HCNetSDK.INSTANCE.NET_DVR_Cleanup();
关于如何将PS流转为rtsp或其他流进行推送,可以使用开源框架如FFmpeg或GStreamer实现。以下为使用FFmpeg将PS流转为RTMP流并推送到云端的代码示例:
// 初始化FFmpeg,需要提前编译好libavcodec、libavformat、libavutil等库文件
av_register_all();
avformat_network_init();
// 创建AVFormatContext和AVOutputFormat
AVFormatContext outputFormatContext = new AVFormatContext(null);
avformat_alloc_output_context2(outputFormatContext, null, "flv", "rtmp://your-host-url/live/your-stream-key");
AVOutputFormat outputFormat = outputFormatContext.oformat;
// 创建AVIOContext并打开rtmp输出流
AVIOContext pb = new AVIOContext();
avio_open2(pb, outputFormatContext.filename().getString(), AVIO_FLAG_WRITE, null, null);
outputFormatContext.pb(pb);
// 设置码流参数
AVStream outputStream = avformat_new_stream(outputFormatContext, null);
AVCodecContext codecContext = outputStream.codec();
codecContext.codec_id(codecId);
codecContext.codec_type(AVMEDIA_TYPE_VIDEO);
codecContext.width(width);
codecContext.height(height);
codecContext.bits_per_raw_sample(8);
codecContext.bits_per_coded_sample(8);
codecContext.time_base().num(timebaseNum);
codecContext.time_base().den(timebaseDen);
outputStream.time_base(codecContext.time_base());
outputStream.avg_frame_rate().num(25);
outputStream.avg_frame_rate().den(1);
// 推送PS封装流到RTMP服务器
AVPacket packet = new AVPacket();
av_init_packet(packet);
ByteBuffer data = ByteBuffer.wrap(psStreamData);
data.order(ByteOrder.LITTLE_ENDIAN);
while (data.remaining() > 0) {
int size = Math.min(4096, data.remaining());
packet.flags(AV_PKT_FLAG_KEY);
packet.timestamp(pktPts);
packet.pts(pktPts);
packet.dts(pktDts);
packet.stream_index(outputStream.index());
packet.data(av_malloc(size));
packet.size(size);
data.get(packet.data().position(0), size);
av_interleaved_write_frame(outputFormatContext, packet);
pktPts += frameDuration;
pktDts += frameDuration;
}
完整的示例代码请参考以下链接:https://github.com/hikvison/hikvison-isup-sdk-demo
如果我的回答解决了您的问题,请
该回答引用于gpt与OKX安生共同编写:
首先,您需要使用海康威视开发的ISUP SDK来连接设备并获取PS封装流。这部分可以参考海康威视提供的开发文档和示例代码。
// 初始化FFmpeg库
av_register_all();
// 打开输入文件流
AVFormatContext *input_format_context = NULL;
avformat_open_input(&input_format_context, "input.ps", NULL, NULL);
// 查找PS流
AVStream *ps_stream = NULL;
for (int i = 0; i < input_format_context->nb_streams; i++) {
AVStream *stream = input_format_context->streams[i];
if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && stream->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
ps_stream = stream;
break;
}
}
// 初始化输出码流
AVOutputFormat *output_format = av_guess_format("rtsp", NULL, NULL);
AVFormatContext *output_format_context = NULL;
avformat_alloc_output_context2(&output_format_context, output_format, "rtsp", NULL);
AVStream *output_stream = avformat_new_stream(output_format_context, NULL);
AVCodecParameters *codec_parameters = output_stream->codecpar;
avcodec_parameters_copy(codec_parameters, ps_stream->codecpar);
codec_parameters->codec_tag = 0;
// 打开输出文件流
avio_open(&output_format_context->pb, "output.rtsp", AVIO_FLAG_WRITE);
// 写入头部信息
avformat_write_header(output_format_context, NULL);
// 转换流数据
AVPacket packet;
while (av_read_frame(input_format_context, &packet) >= 0) {
if (packet.stream_index == ps_stream->index) {
// 将PS流解码成视频帧
AVFrame *frame = av_frame_alloc();
int ret = avcodec_send_packet(ps_stream->codecpar, &packet);
if (ret == 0) {
ret = avcodec_receive_frame(ps_stream->codecpar, frame);
}
// 将视频帧编码为RTSP流
AVPacket output_packet;
av_init_packet(&output_packet);
output_packet.data = NULL;
output_packet.size = 0;
ret = avcodec_send_frame(codec_parameters, frame);
if (ret == 0) {
ret = avcodec_receive_packet(codec_parameters, &output_packet);
}
// 写入输出文件流
av_interleaved_write_frame(output_format_context, &output_packet);
// 释放资源
av_packet_unref(&output_packet);
av_frame_free(&frame);
}
av_packet_unref(&packet);
}
// 写入尾部信息
av_write_trailer(output_format_context);
// 释放资源
avformat_close_input(&input_format_context);
avio_close(output_format_context->pb);
avformat_free_context(output_format_context);
最后,您需要在web页面上加载RTSP流进行播放。您可以使用HTML5中的video标签,并设置src属性为RTSP流的URL地址,如下所示:
<video src="rtsp://localhost:8554/output" autoplay></video>
这样,当您启动FFmpeg命令行工具来推送RTSP流时,web页面就会自动开始播放该流了。
如有用的话,还望采纳!