
DAHUA大华监控快照获取
DAHUA
大华监控设备实时快照获取
获取步骤
接口地址
http://【ip】/cgi-bin/snapshot.cgi:其中【ip】是监控平台的实际ip地址
参数
channel:频道id,类型数字或字符串都可
Digest Auth验证
需要进行Digest Auth验证,输入username和password
监控预览
Apifox接口调用
软件:foxapi
系统:win10
步骤:GET请求,输入api地址,添加Params参数channel=9,并进行【Auth】验证,请求结果如下:
Go-Gin框架
代码
const (
DefaultUsername = "" // 默认用户名
DefaultPassword = "" // 默认密码
DefaultUrl = "" // 默认地址
UploadAPI = "" // 快照上传接口地址
)
// 获取摄像头快照
func GetCameraSnapshot(baseurl string, channel string, username string, password string) ([]byte, error) {
// 请求地址
if baseurl == "" {
baseurl = DefaultUrl
}
// 用户名
if username == "" {
username = DefaultUsername
}
// 密码
if password == "" {
password = DefaultPassword
}
url := fmt.Sprintf("%s/cgi-bin/snapshot.cgi?channel=%s", baseurl, channel)
// 使用 DigestAuth 发送请求
digestAuth := NewDigestAuth(username, password)
return digestAuth.Request("GET", url, nil, nil)
}
// 上传图片到远程服务器
func UploadImage(imageData []byte) (string, error) {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// 照片上传文件夹【DaHua】
_ = writer.WriteField("fileName", "DaHua")
// 创建文件字段,并手动设置 Content-Type 为 image/jpeg
_, err := writer.CreateFormFile("file", "dahua.jpg")
if err != nil {
return "", fmt.Errorf("failed to create form file: %v", err)
}
// 创建一个多部分写入器,并设置 Content-Type
partHeader := make(textproto.MIMEHeader)
partHeader.Set("Content-Disposition", `form-data; name="file"; filename="dahua.jpg"`)
partHeader.Set("Content-Type", "image/jpeg") // 关键修改:明确设置 MIME 类型
filePart, err := writer.CreatePart(partHeader)
if err != nil {
return "", fmt.Errorf("failed to create part: %v", err)
}
// 写入图像数据
_, err = io.Copy(filePart, bytes.NewReader(imageData))
if err != nil {
return "", fmt.Errorf("failed to write file data: %v", err)
}
// 关闭 multipart writer
err = writer.Close()
if err != nil {
return "", fmt.Errorf("failed to close multipart writer: %v", err)
}
// 发送 POST 请求
req, err := http.NewRequest("POST", UploadAPI, body)
if err != nil {
return "", fmt.Errorf("failed to create request: %v", err)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("failed to send upload request: %v", err)
}
defer resp.Body.Close()
// 解析返回的 JSON
var uploadResp UploadResponse
err = json.NewDecoder(resp.Body).Decode(&uploadResp)
if err != nil {
return "", fmt.Errorf("failed to decode response: %v", err)
}
// 检查上传是否成功
if uploadResp.Ret != 200 || uploadResp.Data.Code != 1 {
return "", fmt.Errorf("upload failed: %s", uploadResp.Msg)
}
return uploadResp.Data.URL, nil
}
// 直接获取照片
DaHuaMonitor.GET("/Test", func(c *gin.Context) {
channel := c.DefaultQuery("channel", "9")
url := c.Query("url")
username := c.Query("username")
password := c.Query("password")
// 获取摄像头照片
imageData, err := GetCameraSnapshot(url, channel, username, password)
if err != nil {
ReturnError(c, http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.Data(http.StatusOK, "image/jpeg", imageData)
})
// 获取后将照片上传到服务器
DaHuaMonitor.GET("/DaHua", func(c *gin.Context) {
channel := c.DefaultQuery("channel", "9")
url := c.Query("url")
username := c.Query("username")
password := c.Query("password")
// 获取摄像头照片
imageData, err := GetCameraSnapshot(url, channel, username, password)
if err != nil {
ReturnError(c, http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 上传照片到服务器
imageURL, err := UploadImage(imageData)
if err != nil {
ReturnError(c, http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
ReturnSuccess(c, http.StatusOK, 1, gin.H{"url": imageURL}, "上传成功")
})
调用接口
/DaHua:
/Test:
WinForm
代码
using System;
using System.Drawing;
using System.Net.Http;
using System.Windows.Forms;
namespace DAHUA_Test
{
public partial class MainForm : Form
{
// 声明 HttpClient 作为成员变量以便重用
private HttpClient _httpClient;
public MainForm()
{
InitializeComponent();
picBox.SizeMode = PictureBoxSizeMode.Zoom;
TBUrl.Enabled = false;
}
private void BtnFetch_Click(object sender, EventArgs e)
{
if (this.ValidateChildren())
{
FetchDaHuaSnapshot(TBUrl.Text, TBChannel.Text);
}
else
{
Console.WriteLine("表单验证未通过");
}
}
private void TBChannel_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
if (string.IsNullOrEmpty(TBChannel.Text) || !int.TryParse(TBChannel.Text, out int value) || value <= 0)
{
errorProvider1.SetError(TBChannel, "请输入大于0的正整数");
e.Cancel = true; // 可选:阻止离开控件直到输入有效
}
else
{
errorProvider1.SetError(TBChannel, null); // 清除错误
}
}
private async void FetchDaHuaSnapshot(string url, string channel)
{
try
{
if (string.IsNullOrEmpty(channel) || !int.TryParse(channel, out int value) || value <= 0)
{
MessageBox.Show("channel 必须为大于0的正整数", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// 禁用按钮防止重复点击
btnFetch.Enabled = false;
lblStatus.Text = "正在连接摄像头...";
picBox.Image = null; // 清除旧图片
// 如果HttpClient未初始化,则创建它
if (_httpClient == null)
{
var handler = new HttpClientHandler
{
PreAuthenticate = true,
Credentials = new System.Net.NetworkCredential("admin", "admin123")
};
_httpClient = new HttpClient(handler)
{
Timeout = TimeSpan.FromSeconds(15) // 设置15秒超时
};
}
string apiUrl = $"{url}?channel={channel}";
lblStatus.Text = "正在获取快照...";
using (var response = await _httpClient.GetAsync(apiUrl))
{
// 检查响应状态
response.EnsureSuccessStatusCode();
// 读取响应内容为流
using (var stream = await response.Content.ReadAsStreamAsync())
{
// 从流创建图像
var image = Image.FromStream(stream);
// 在PictureBox中显示图像
picBox.Image = image;
lblStatus.Text = $"快照获取成功 {DateTime.Now:HH:mm:ss}";
}
}
}
catch (HttpRequestException ex)
{
lblStatus.Text = "网络错误: " + ex.Message;
MessageBox.Show($"网络请求失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
lblStatus.Text = "错误: " + ex.Message;
MessageBox.Show($"发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
btnFetch.Enabled = true;
}
}
}
}
预览
总结
直接调用DAHUA SDK接口,添加参数channel,并进行Digest Auth验证即可。或是在获取到快照后将照片上传至服务器,再返回图片的网络地址亦可。
附件
大华SDK:DAHUA_API.pdf
联系作者
微信:
QQ:
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 桥娃子
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果