javacv把海康摄像头rtsp流转推到rtmp流

前言:

使用javacv1.2版本,参考网上的代码,遇到了不少非常严重的问题,最后一个一个排除解决。解决主要的问题是:

问题一、ffmpeg默认是使用udp的方式,经常出现丢包的问题,需要把udp改成tcp就可以解决,以下是报错的内容:

Input #0, rtsp, from 'rtsp://admin:123123@192.168.1.64:554/Streaming/Channels/1':
  Metadata:
    title           : Media Presentation
  Duration: N/A, start: 0.040000, bitrate: N/A
    Stream #0:0: Video: h264 (Main), yuvj420p(pc, bt709), 2560x1440, 25 fps, 25 tbr, 90k tbn
[swscaler @ 000000001be02720] deprecated pixel format used, make sure you did set range correctly
[rtsp @ 0000000000f8c9a0] max delay reached. need to consume packet
[rtsp @ 0000000000f8c9a0] RTP: missed 4188 packets
[rtsp @ 0000000000f8c9a0] RTP: PT=60: bad cseq 61ae expected=5152
[rtsp @ 0000000000f8c9a0] max delay reached. need to consume packet
[rtsp @ 0000000000f8c9a0] RTP: missed 4189 packets
[rtsp @ 0000000000f8c9a0] max delay reached. need to consume packet
[rtsp @ 0000000000f8c9a0] RTP: missed 96 packets
[h264 @ 000000001a9fbfe0] left block unavailable for requested intra mode
[h264 @ 000000001a9fbfe0] error while decoding MB 0 67, bytestream 23926
[h264 @ 000000001a9fbfe0] concealing 3729 DC, 3729 AC, 3729 MV errors in P frame
[swscaler @ 000000001be02720] deprecated pixel format used, make sure you did set range correctly
[rtsp @ 0000000000f8c9a0] max delay reached. need to consume packet
[rtsp @ 0000000000f8c9a0] RTP: missed 99 packets

问题二、在设置为tcp后没有掉包,但是一直在50帧左右就无法获取frame,返回的一直是null,问题造成的原因是我的海康摄像头的尺寸太大了的原因?具体也还没有研究出来,不过是把问题解决了。但是后台还是一直报无数的错,不明白是什么造成的。但是功能可以使用了。报错的内容:

[swscaler @ 000000001be02720] deprecated pixel format used, make sure you did set range correctly

好了 直接上代码。帮助到的人请点个赞,研究了几天也不容易啊。

package test;
 
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.OpenCVFrameConverter;
public class TestRTMPGrabberRecorder {
    static boolean exit  = false;
    public static void main(String[] args) throws Exception {
        System.out.println("start...");
        String rtmpPath = "rtmp://casic207-pc1/live360p/ss1";
    //    String rtspPath = "rtmp://live.hkstv.hk.lxdns.com/live/hks"; // 香港收视
        //String rtspPath = "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov";
        String rtspPath = "rtsp://admin:123123@192.168.1.64:554/h264/ch1/main/av_stream";
        //ffmpeg -f rtsp -rtsp_transport tcp -i rtsp://admin:leeking123@192.168.1.64:554/h264/ch1/main/av_stream rtmp://casic207-pc1/live360p/ss1
        // ffmpeg -i  rtsp://admin:123123@192.168.1.64:554/h264/ch1/main/av_stream -vcodec copy -acodec copy -f flv rtmp://casic207-pc1/live360p/ss1
        int audioRecord =0; // 0 = 不录制,1=录制
        boolean saveVideo = false;
        test(rtmpPath,rtspPath,audioRecord,saveVideo);
        System.out.println("end...");
    }
 
    public static void test(String rtmpPath,String rtspPath,int audioRecord,boolean saveVideo ) throws Exception  {
        //FrameGrabber grabber = FrameGrabber.createDefault(0); // 本机摄像头 默认
        // 使用rtsp的时候需要使用 FFmpegFrameGrabber,不能再用 FrameGrabber
        int width = 640,height = 480;
        FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(rtspPath); 
        grabber.setOption("rtsp_transport", "tcp"); // 使用tcp的方式,不然会丢包很严重
        // 一直报错的原因!!!就是因为是 2560 * 1440的太大了。。
        grabber.setImageWidth(width);
        grabber.setImageHeight(height);
        System.out.println("grabber start");
        grabber.start();
        //FrameRecorder recorder = FrameRecorder.createDefault(rtmpPath, 640,480,0);
        // 流媒体输出地址,分辨率(长,高),是否录制音频(0:不录制/1:录制)
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(rtmpPath, width, height, audioRecord);
        recorder.setInterleaved(true);
        recorder.setVideoOption("crf","28");
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 28
        recorder.setFormat("flv"); // rtmp的类型
        recorder.setFrameRate(25);
         recorder.setPixelFormat(0); // yuv420p
         System.out.println("recorder start");
        recorder.start();
        //
        OpenCVFrameConverter.ToIplImage conveter = new OpenCVFrameConverter.ToIplImage();
        System.out.println("all start!!");
        int count = 0;
        while(!exit){
            count++;
            Frame frame = grabber.grabImage();
            if(frame == null){
                continue;
            }
            if(count % 100 == 0){
                System.out.println("count="+count);
            }
            recorder.record(frame); 
        }
        grabber.stop();
        grabber.release();
        recorder.stop();
        recorder.release();
    }
}

补充一个非常严重的问题,就是
Frame frame = grabber.grabImage();
的内存问题。frame的内存一直没有释放,最终会内存崩溃导致应用死掉。

需要把javacpp.jar的版本为1.3.1以上。本人使用1.3.3测试过。问题已经解决。

转载于:https://blog.csdn.net/leeking888/article/details/77542661
原文链接:https://blog.csdn.net/leeking888/article/details/77542661

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值