最近看了一篇关于Java推流的文章

本文介绍如何使用JavaCV库实现从摄像头获取视频并进行实时录制,包括依赖包配置、代码实现及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、开发所依赖的包

javacv.jar,javacpp.jar,ffmpeg.jar,ffmpeg-系统平台.jar,opencv.jar,opencv-系统平台.jar。

其中ffmpeg-系统平台.jar,opencv-系统平台.jar中的系统平台根据开发环境或者测试部署环境自行更改为对应的jar包,比如windows7 64位系统替换为ffmpeg-x86-x64.jar

为什么要这样做:因为ffmpeg-系统平台.jar中存放的是c/c++本地so/dll库,而ffmpeg.jar就是使用javacpp封装的对应本地库java接口的实现,而javacpp就是基于jni的一个功能性封装包,方便实现jni,javacv.jar就是对9个视觉库进行了二次封装,但是实现的功能有限,所以建议新手先熟悉openCV和ffmpeg这两个C/C++库的API后再来看javaCV思路就会很清晰了。

JavaCV下载地址

二、代码实现

本功能采用按帧录制/推流,通过关闭播放窗口停止视频录制/推流

注:时间运行该代码会导致内存溢出的原因是没有及时释放IplImage资源(由于javacv是jni方式调用C,部分对象需要手动释放资源,以防止内存溢出错误

    /** 
         * 按帧录制本机摄像头视频(边预览边录制,停止预览即停止录制) 
         *  
         * @author eguid 
         * @param outputFile -录制的文件路径,也可以是rtsp或者rtmp等流媒体服务器发布地址 
         * @param frameRate - 视频帧率 
         * @throws Exception 
         * @throws InterruptedException 
         * @throws org.bytedeco.javacv.FrameRecorder.Exception 
         */  
        public static void recordCamera(String outputFile, double frameRate)  
                throws Exception, InterruptedException, org.bytedeco.javacv.FrameRecorder.Exception {  
            Loader.load(opencv_objdetect.class);  
            FrameGrabber grabber = FrameGrabber.createDefault(0);//本机摄像头默认0,这里使用javacv的抓取器,至于使用的是ffmpeg还是opencv,请自行查看源码  
            grabber.start();//开启抓取器  
      
            OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();//转换器  
            IplImage grabbedImage = converter.convert(grabber.grab());//抓取一帧视频并将其转换为图像,至于用这个图像用来做什么?加水印,人脸识别等等自行添加  
            int width = grabbedImage.width();  
            int height = grabbedImage.height();  
          
            FrameRecorder recorder = FrameRecorder.createDefault(outputFile, width, height);  
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // avcodec.AV_CODEC_ID_H264,编码  
            recorder.setFormat("flv");//封装格式,如果是推送到rtmp就必须是flv封装格式  
            recorder.setFrameRate(frameRate);  
              
            recorder.start();//开启录制器  
            long startTime=0;  
            long videoTS=0;  
            CanvasFrame frame = new CanvasFrame("camera", CanvasFrame.getDefaultGamma() / grabber.getGamma());  
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
            frame.setAlwaysOnTop(true);  
            Frame rotatedFrame=converter.convert(grabbedImage);//不知道为什么这里不做转换就不能推到rtmp  
            while (frame.isVisible() && (grabbedImage = converter.convert(grabber.grab())) != null) {  
                rotatedFrame = converter.convert(grabbedImage);  
                frame.showImage(rotatedFrame);  
                if (startTime == 0) {  
                    startTime = System.currentTimeMillis();  
                }  
                videoTS = 1000 * (System.currentTimeMillis() - startTime);  
                recorder.setTimestamp(videoTS);  
                recorder.record(rotatedFrame);  
                Thread.sleep(40);  
            }  
            frame.dispose();  
            recorder.stop();  
            recorder.release();  
            grabber.stop();  
          
        }  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值