写这篇文章之前非常感谢博主 叫我三胖哥哥,我的代码是在他的基础上写的,https://blog.csdn.net/weixin_44232093 这是他的博客,可以去看看。
首先进行海康二次开发需要,在海康官网去下载SDk,下载地址是https://www.hikvision.com/cn/download_more_570.html
将下载好的SDK导入到工具中,我的是eclipse里面,如下图
你可以试运行这个demo,直接运行ClientDemo类就行了
首先,一定要保证这个demo能运行起来
然后自己再根据demo写个类进行测试预览跟实时流获取视频的问题。
package ClientDemo;
import java.awt.Frame;
import java.awt.Panel;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.examples.win32.W32API.HWND;
import com.sun.jna.ptr.ByteByReference;
import ClientDemo.HCNetSDK.FStdDataCallBack;
public class AJB extends Frame
{
private static final long serialVersionUID = 1L;
public AJB(String str)
{
super(str);
}
public static void main(String args[])
{
AJB fr = new AJB("海康实时预览");
Panel pan = new Panel();
fr.setSize(400, 400);
// fr.setBackground(Color.blue);
pan.setSize(100, 100);
// pan.setBackground(Color.yellow);
fr.add(pan);
fr.setVisible(true);
CameraInfo cameraInfo = new CameraInfo();
// cameraInfo.setAddress("192.168.99.8");
cameraInfo.setAddress("192.168.99.20");
cameraInfo.setPort((short) 8000);
cameraInfo.setUserName("admin");
// cameraInfo.setPwd("zmkj1234");
cameraInfo.setPwd("admin12345");
System.out.println(pan.getWidth());
System.out.println(pan.getHeight());
// 设置设备通道号 查看Demo代码 通道号为1
NativeLong channel = new NativeLong(1);
cameraInfo.setChannel(channel);
// 初始化HCNetSDK接口 实例化对象
HCNetSDK sdk = HCNetSDK.INSTANCE;
if (!sdk.NET_DVR_Init())
{
System.out.println("初始化失败");
}
// 创建设备
HCNetSDK.NET_DVR_DEVICEINFO_V30 deInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
// 注册用户设备
NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getAddress(), cameraInfo.getPort(), cameraInfo.getUserName(),
cameraInfo.getPwd(), deInfo);
cameraInfo.setUserId(id);
// 判断是否注册成功
if (cameraInfo.getUserId().intValue() < 0)
{
System.out.println("注册设备失败");
}
// 判断是否获取到设备能力
HCNetSDK.NET_DVR_WORKSTATE_V30 devWork = new HCNetSDK.NET_DVR_WORKSTATE_V30();
if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devWork))
{
System.out.println("获取设备能力集失败");
}
// 启动实时预览功能 创建clientInfo对象赋值预览参数
HCNetSDK.NET_DVR_CLIENTINFO clientInfo = new HCNetSDK.NET_DVR_CLIENTINFO();
clientInfo.lChannel = cameraInfo.getChannel(); // 设置通道号
clientInfo.lLinkMode = new NativeLong(0); // TCP取流
clientInfo.sMultiCastIP = null; // 不启动多播模式
// 创建窗口句柄
HWND hwnd = new HWND(Native.getComponentPointer(pan));
clientInfo.hPlayWnd = hwnd;
ClientDemo clientDemo = new ClientDemo();
ClientDemo.FRealDataCallBack fRealDataCallBack = clientDemo.fRealDataCallBack;
// System.out.println("fRealDataCallBack:" + fRealDataCallBack);
// 开启实时预览
NativeLong key = sdk.NET_DVR_RealPlay_V30(cameraInfo.getUserId(), clientInfo, fRealDataCallBack, null, true);
// 判断是否预览成功
if (key.intValue() == -1)
{
System.out.println("预览失败 错误代码为: " + sdk.NET_DVR_GetLastError());
sdk.NET_DVR_Logout(cameraInfo.getUserId());
sdk.NET_DVR_Cleanup();
}
boolean 成功1 = sdk.NET_DVR_SetRealDataCallBack(id, fRealDataCallBack, 0);
System.out.println("成功1:" + 成功1);
FStdDataCallBack fs = new FStdDataCallBack()
{
@Override
public void invoke(NativeLong lRealHandle, int dwDataType, ByteByReference pBuffer, int dwBufSize,
int dwUser)
{
}
};
boolean 成功2 = sdk.NET_DVR_SetStandardDataCallBack(id, fs, 0);
System.out.println("成功2:" + 成功2);
boolean 保存 = sdk.NET_DVR_SaveRealData(key, "E:\\video.mp4");
System.out.println("保存:" + 保存);
if (!保存)
{
System.out.println("错误码:" + sdk.NET_DVR_GetLastError());
}
try
{
Thread.sleep(5000);
}
catch (Exception e)
{
e.printStackTrace();
}
boolean 停止 = sdk.NET_DVR_StopRealPlay(key);
System.out.println("停止:" + 停止);
}
}
这段代码还带有个实体类,如下
package ClientDemo;
import com.sun.jna.NativeLong;
public class CameraInfo
{
private String address;
private String userName;
private String pwd;
private short port;
private NativeLong userId;
private NativeLong channel;
private NativeLong key;
public String getAddress()
{
return address;
}
public void setAddress(String address)
{
this.address = address;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getPwd()
{
return pwd;
}
public void setPwd(String pwd)
{
this.pwd = pwd;
}
public short getPort()
{
return port;
}
public void setPort(short port)
{
this.port = port;
}
public NativeLong getUserId()
{
return userId;
}
public void setUserId(NativeLong userId)
{
this.userId = userId;
}
public NativeLong getChannel()
{
return channel;
}
public void setChannel(NativeLong channel)
{
this.channel = channel;
}
public NativeLong getKey()
{
return key;
}
public void setKey(NativeLong key)
{
this.key = key;
}
// get set方法
}
这样就能获取到海康视频了,不过海康视频是一般播放器打不开的,可以使用VLC打开,所以如果公用还是需要转码。
不知道其他人是怎么转码的,我用的是FFmpeg进行转码,关于FFmpeg怎么转码,网上有很多实例,我就不多说了,一个cmd命令就搞定