实时推流

This commit is contained in:
shikong 2023-09-15 17:26:48 +08:00
parent 4b84f9e3b2
commit fc85a0782d

View File

@ -111,8 +111,9 @@ public class DeviceProxyService {
// FFmpeg 调试日志 // FFmpeg 调试日志
// FFmpegLogCallback.set(); // FFmpegLogCallback.set();
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(fromUrl); FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(fromUrl);
// 30秒超时
grabber.setOption("stimeout", "30000000");
grabber.start(); grabber.start();
grabber.flush();
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(toUrl, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels()); FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(toUrl, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());
recorder.setInterleaved(true); recorder.setInterleaved(true);
@ -120,7 +121,7 @@ public class DeviceProxyService {
recorder.setVideoOption("tune", "zerolatency"); recorder.setVideoOption("tune", "zerolatency");
recorder.setVideoOption("crf", "25"); recorder.setVideoOption("crf", "25");
// recorder.setMaxDelay(500); // recorder.setMaxDelay(500);
recorder.setGopSize(10); recorder.setGopSize((int) (grabber.getFrameRate() * 2));
recorder.setFrameRate(grabber.getFrameRate()); recorder.setFrameRate(grabber.getFrameRate());
recorder.setSampleRate(grabber.getSampleRate()); recorder.setSampleRate(grabber.getSampleRate());
recorder.setOption("flvflags", "no_duration_filesize"); recorder.setOption("flvflags", "no_duration_filesize");
@ -139,6 +140,7 @@ public class DeviceProxyService {
recorder.setFormat("rtp_mpegts"); recorder.setFormat("rtp_mpegts");
recorder.setVideoOption("threads", String.valueOf(Runtime.getRuntime().availableProcessors())); // 解码线程数 recorder.setVideoOption("threads", String.valueOf(Runtime.getRuntime().availableProcessors())); // 解码线程数
recorder.start(grabber.getFormatContext()); recorder.start(grabber.getFormatContext());
grabber.flush();
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
AtomicBoolean record = new AtomicBoolean(true); AtomicBoolean record = new AtomicBoolean(true);
@ -147,7 +149,10 @@ public class DeviceProxyService {
record.set(false); record.set(false);
}, time, TimeUnit.SECONDS); }, time, TimeUnit.SECONDS);
try { try {
long begin = System.currentTimeMillis();
AVPacket k; AVPacket k;
long dts = 0;
long pts = 0;
int no_frame_index = 0; int no_frame_index = 0;
while (record.get() && no_frame_index < 10 ) { while (record.get() && no_frame_index < 10 ) {
k = grabber.grabPacket(); k = grabber.grabPacket();
@ -156,8 +161,22 @@ public class DeviceProxyService {
no_frame_index++; no_frame_index++;
continue; continue;
} }
// 获取到的pkt的dtspts异常将此包丢弃掉
if (k.dts() == avutil.AV_NOPTS_VALUE && k.pts() == avutil.AV_NOPTS_VALUE || k.pts() < dts) {
avcodec.av_packet_unref(k);
continue;
}
// 记录上一pkt的dtspts
dts = k.dts();
pts = k.pts();
recorder.recordPacket(k); recorder.recordPacket(k);
avcodec.av_packet_unref(k); avcodec.av_packet_unref(k);
long end = System.currentTimeMillis();
long sleep_real = (long) ((1000 / grabber.getFrameRate()) - (end - begin));
begin = end;
if (sleep_real > 0) {
Thread.sleep(sleep_real);
}
} }
grabber.close(); grabber.close();
recorder.close(); recorder.close();