文章目录
1. 前言2. 对接过程 以海康SDK取流推流为例1. 引入JavaCv Maven依赖,按需引入2. 流处理类3. 注册海康SDK取流回调函数4. 取流回调函数
3. 小结
1. 前言
如果想要更低延迟方案参见:Java对接海康SDK并推往ZLM4J实现超低延迟播放 支持H265转H264编码 本文主要介绍海康、大华SDK取流推流过程,这里就不展示对接海康、大华SDK了 这个是重点 Native.setCallbackThreadInitializer(this, new CallbackThreadInitializer(true, false, "HikRealStream-" + RandomUtil.randomNumbers(8))); 增加回放流速度控制
2. 对接过程 以海康SDK取流推流为例
1. 引入JavaCv Maven依赖,按需引入
org.bytedeco
javacv
1.5.9
org.bytedeco
ffmpeg
6.0-1.5.9
windows-x86_64-gpl
org.bytedeco
ffmpeg
6.0-1.5.9
linux-x86_64-gpl
2. 流处理类
/**
* 推流处理
*
* @author lidaofu
* @since 2023/11/10
**/
@Slf4j
public class StreamPushHandle {
private FFmpegFrameGrabber grabber = null;
private FFmpegFrameRecorder recorder = null;
private PipedOutputStream outputStream;
private PipedInputStream inputStream;
private String pushAddress;
private SdkStreamClose streamClose;
private Long handleId;
private AVPacket avPacket = null;
private Frame frame = null;
private boolean isPlayBack=false;
private double frameRate = 25.0;
public StreamPushHandle(String pushAddress, SdkStreamClose streamClose, Boolean isPlayBack) {
this.pushAddress = pushAddress;
this.streamClose = streamClose;
this.outputStream = new PipedOutputStream();
this.inputStream = new PipedInputStream(256* 1024);
this.isPlayBack = isPlayBack;
try {
//建立管道连接
inputStream.connect(outputStream);
} catch (IOException e) {
throw new FFmpegException("创建输入管道失败");
}
}
/**
* 设置播放句柄
*
* @param handleId
*/
public void setHandleId(Long handleId) {
this.handleId = handleId;
}
/**
* 异步接收海康/大华/宇视设备sdk回调实时视频裸流数据
*/
public void write(byte[] data,int dwBufSize) {
try {
outputStream.write(data, 0, dwBufSize);
} catch (IOException e) {
throw new FFmpegException("写入数据失败", e);
}
}
/**
* 推流
*/
public void push() {
try {
FFmpegLogCallback.setLevel(avutil.AV_LOG_ERROR);
grabber = new FFmpegFrameGrabber(inputStream, 0);
//有些码率什么可以自己设置、不过没有必要
grabber.setVideoCodec(avcodec.AV_CODEC_ID_H264);
// 设置读取的最大数据,单位字节 为了加快首播速度
grabber.setOption("probesize", "8192");
// 设置分析的最长时间,单位微秒 为了加快首播速度
grabber.setOption("analyzeduration", "1000000");
// 5秒超时 单位微秒
grabber.setOption("stimeout", "5000000");
// 5秒超时 单位微秒
grabber.setOption("rw_timeout", "5000000");
// 设置缓存大小,提高画质、减少卡顿花屏
grabber.setOption("buffer_size", "1024000");
grabber.start();
// 部分监控设备流信息里携带的帧率为9000,如出现此问题,会导致dts、pts时间戳计算失败,播放器无法播放,故出现错误的帧率时,默认为25帧
if (grabber.getFrameRate() > 0 && grabber.getFrameRate() |