读书笔记-第二课

前言

查看了相关文章然后一笔一笔打代码再调试成功出结果,
eguid的博客
不保证代码能够原封不动就能运行,
这里做一下记录。
ps:代码内容有改动,原版的可以看原作者的。

代码内容

package net.w2p.JCVStudio.zhiboStudy;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Point;
import org.bytedeco.opencv.opencv_core.Scalar;
import org.bytedeco.opencv.opencv_videoio.VideoCapture;

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 在lesson01基础上继续优化。测试推流--推到本地文件或者推到远程服务器上面。
 * https://blog.csdn.net/eguid_1/article/details/52678775
 * 推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG、javaCV-openCV)
 * 推流器 测试。
 * 原创本博客已停止维护!-eguid 发布于2016-09-27 11:50:00 阅读数 30135  收藏

 * **/
public class Lesson02 {
    /***
     * 添加水印并且导出为一个MP4文件。
     *
     * **/
    public void push(
            String outputUrl
            ,final int frameRate
    ) throws Exception {
        //做好自己!--eguid!http://www.eguid.cc
        String msg="fps:";//水印文字
        // 水印文字位置
        Point point = new Point(10, 50);
        // 颜色,使用黄色
        Scalar scalar = new Scalar(0, 255, 255, 0);
        DecimalFormat df=new DecimalFormat(".##");//数字格式化
        VideoCapture vc=null;
        //遍历查找摄像头
        int index=-1;
        for(;index<2;index++){
            vc=new VideoCapture(index);
            if(vc.grab()){
                //找到摄像头设备,退出遍历
                System.err.println("做好自己!--eguid温馨提示,获取本机当前摄像头序号:"+index);
                break;
            }
            vc.close();//没找到设备,释放资源
        }
        //vc为null,并且设备没正常开启,说明没找到设备
        if(vc!=null&&!vc.isOpened()){
            System.err.println("无法找到摄像头,请检查是否存在摄像头设备");
            return;
        }
        //使用java的JFrame显示图像
        CanvasFrame cFrame = new CanvasFrame("做好自己!--eguid!http://www.eguid.cc",
                CanvasFrame.getDefaultGamma()/2.2);
        cFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//        cFrame.setAlwaysOnTop(true);

        //javacv提供的转换器,方便mat转换为Frame
        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
        Mat mat=new Mat();
        double start=System.currentTimeMillis();
        double end;
        Frame ftmp=null;


        Java2DFrameConverter converter1 = new Java2DFrameConverter();
        OpenCVFrameConverter.ToIplImage converter2 = new OpenCVFrameConverter.ToIplImage();

        final String outputFilePath=outputUrl;
        FFmpegFrameRecorder recorder = null;

        long startTime=0;
        long videoTS=0;

        final ConcurrentHashMap<String,Object> map4Middle=new ConcurrentHashMap<>(2);

        cFrame.addWindowListener(new WindowAdapter()
        {
            @Override
            public void windowClosing(WindowEvent e)
            {
                System.out.println("Closed");

                FFmpegFrameRecorder recorder2=null;
                if(map4Middle.get("recorder")!=null){
                    recorder2=(FFmpegFrameRecorder)map4Middle.get("recorder");
                }
                map4Middle.put("stop",true);

               try{
                   if(recorder2!=null){
                       recorder2.stop();
                       recorder2.release();
                   }
                   System.out.println("窗口关闭啦,请做收尾工作");
               }
               catch (Exception ed){
                   ed.printStackTrace();
               }
                e.getWindow().dispose();

//                grabber.stop();//停止抓取

                System.exit(-1);//退出
                return;

            }
        });
        map4Middle.put("stop",false);
        for(int i=0;;i++){

            ftmp=null;
            vc.retrieve(mat);//重新获取mat
            if(vc.grab()){//是否采集到摄像头数据
                if(vc.read(mat)){//读取一帧mat图像
                    end=System.currentTimeMillis();
                    if(mat!=null){
                        opencv_imgproc.putText(mat,msg+df.format((1000.0/(end-start))),
                                point, opencv_imgproc.CV_FONT_VECTOR0, 1.2, scalar,
                                1, 20, false);
                    }
//          opencv_highgui.imshow("eguid", mat);该opencv方法windows下会无响应
                    ftmp=converter.convert(mat);
//                    Frame rotatedFrame=converter.convert(grabbedImage);//不知道为什么这里不做转换就不能推到rtmp
                    if(recorder==null){


                        recorder=
                                new FFmpegFrameRecorder(outputFilePath,
                                        ftmp.imageWidth,ftmp.imageHeight);
                        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // avcodec.AV_CODEC_ID_H264,编码
//                        recorder.setFormat("flv");
                        recorder.setFormat("flv");//封装格式,如果是推送到rtmp就必须是flv封装格式
                        recorder.setPixelFormat(0);
                        recorder.setFrameRate(frameRate);

                        recorder.setVideoOption("preset", "ultrafast");
                        recorder.setVideoOption("tune", "zerolatency");
                        recorder.setVideoOption("fflags", "nobuffer");
                        recorder.setVideoOption("analyzeduration", "0");


//                        recorder.setVideoOption("preset","ultrafast");
//                        recorder.setVideoOption("tune", "zerolatency");
                        try {
                            recorder.start();
                            map4Middle.put("recorder",recorder);

                        }
                        catch (Exception ed){
                            ed.printStackTrace();
                        }

                    }

                    cFrame.showImage(ftmp);



                    if(recorder.isCloseOutputStream()){
                        return;
                    }

                    /***计算帧的时间**/
                    if (startTime == 0) {
                        startTime = System.currentTimeMillis();
                    }
                    videoTS = 1000 * (System.currentTimeMillis() - startTime);

                    Boolean isStop=false;
                    isStop=(Boolean)map4Middle.get("stop");
                    if(isStop){
                        return;
                    }

                    recorder.setTimestamp(videoTS);



                    recorder.record(ftmp);
                    System.err.println(i);
                    start=end;
                }
                mat.release();//释放mat

                if(ftmp!=null){
                    //--导出到视频中区。
                }
            }



        }
    }

    public static void main(String[] args) throws Exception {
        Lesson02 test=new Lesson02();

        //--普通推送到文件保存。
//        test.push("/home/too-white/temp/002_push.flv",25);
        final String rtmpUrl="rtmp://localhost/live/livestream";
        test.push(rtmpUrl,25);

        //--播放地址也是这个啊。。

    }

}
发布了401 篇原创文章 · 获赞 256 · 访问量 271万+

猜你喜欢

转载自blog.csdn.net/cdnight/article/details/103886907