1.docker rtmp推流到线上 然后网页显示(不依赖flash)_alfg/nginx-rtmp-CSDN博客 经过该博文
rtmp 已经可以推流到线上服务器然后不依赖flash显示
但是有的摄像头没有rtmp 只有rtsp 怎么办
这就要一个转发服务 或者主动拉流
@Async //多线程注解
@Override
public void writeText(ThCamera thCamera) {
try {
final int captureWidth = 1920;
final int captureHeight = 1080;
//rtsp取流地址以自己的为准
final FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("rtsp://admin:" + thCamera.getPwd() + "@" + thCamera.getIpAddress() + ":554/Streaming/Channels/1");
grabber.setImageWidth(captureWidth);
grabber.setImageHeight(captureHeight);
// rtsp格式一般添加TCP配置,否则丢帧会比较严重
grabber.setOption("rtsp_transport", "tcp");
grabber.start();
// 最后一个参数是AudioChannels,建议通过grabber获取
//rtmp 对应上一文章推送地址
final FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("rtmp://192.168.1.103:11000/hls/" + thCamera.getChannelName(), captureWidth, captureHeight, 0);
recorder.setInterleaved(true);
// 降低编码延时
recorder.setVideoOption("tune", "zerolatency");
// 提升编码速度
recorder.setVideoOption("preset", "ultrafast");
// 视频质量参数(详见 https://trac.ffmpeg.org/wiki/Encode/H.264)
recorder.setVideoOption("crf", "28");
// 分辨率
recorder.setVideoBitrate(2000000);
// 视频编码格式
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
// 视频格式
recorder.setFormat("flv");
// 视频帧率
recorder.setFrameRate(15);
recorder.setGopSize(60);
recorder.setAudioOption("crf", "0");
recorder.setAudioQuality(0);
recorder.setAudioBitrate(192000);
recorder.setSampleRate(44100);
// 建议从grabber获取AudioChannels
recorder.setAudioChannels(1);
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
recorder.start();
// 解决音视频同步导致的延时问题
Field field = recorder.getClass().getDeclaredField("oc");
field.setAccessible(true);
AVFormatContext oc = (AVFormatContext) field.get(recorder);
oc.max_interleave_delta(100);
// 用来测试的frame窗口
//final CanvasFrame cFrame = new CanvasFrame("frame");
Frame capturedFrame = null;
// 有些时候,程序执行回报下列错误,本次进行了代码优化
// av_interleaved_write_frame() error -22 while writing interleaved video packet.
int oldFrameNumber = Integer.MIN_VALUE;
long oldTimestamp = Long.MIN_VALUE;
System.out.println("运行到" + thCamera.getChannelName());
while ((capturedFrame = grabber.grab()) != null) {
// if (cFrame.isVisible()) {
// cFrame.showImage(capturedFrame);
// }
int newFrameNumber = grabber.getFrameNumber();
long newTimestamp = capturedFrame.timestamp;
if (newFrameNumber < oldFrameNumber) {
continue;
} else if (newFrameNumber > oldFrameNumber) {
oldTimestamp = Long.MIN_VALUE;
}
if (newTimestamp < oldTimestamp) {
continue;
}
oldFrameNumber = newFrameNumber;
oldTimestamp = newTimestamp;
recorder.setTimestamp(capturedFrame.timestamp);
recorder.record(capturedFrame);
}
// cFrame.dispose();
recorder.close();
grabber.close();
} catch (Exception e) {
e.printStackTrace();
}
}