读书笔记-第三课

前言

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

代码内容

package net.w2p.JCVStudio.zhiboStudy;

import javafx.embed.swing.SwingFXUtils;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;
import org.bytedeco.javacv.Frame;
import org.bytedeco.opencv.global.opencv_core;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.CvScalar;
import org.bytedeco.opencv.opencv_core.IplImage;

import org.bytedeco.opencv.opencv_core.Point;
import org.bytedeco.opencv.opencv_core.Scalar;
import org.bytedeco.opencv.opencv_imgproc.CvFont;
import org.opencv.core.CvType;
import org.opencv.core.Mat;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.util.concurrent.ConcurrentHashMap;

import static org.bytedeco.opencv.global.opencv_core.IPL_DEPTH_8U;
import static org.bytedeco.opencv.global.opencv_imgproc.*;

/***
 * 收流器实现,录制流媒体服务器的rtsp/rtmp视频文件(基于javaCV-FFMPEG)
 * https://blog.csdn.net/eguid_1/article/details/52680802
 * 顺便操作画面,进行文字打水印。
 * **/
public class Lesson03 {


    private ConcurrentHashMap<String,Object> mapParas=new ConcurrentHashMap<>(55);
    /**
     * 按帧录制视频
     *
     * @param inputFile-该地址可以是网络直播/录播地址,也可以是远程/本地文件路径
     * @param outputFile                              -该地址只能是文件地址,如果使用该方法推送流媒体服务器会报错,原因是没有设置编码格式
     * @throws FrameGrabber.Exception
     * @throws FrameRecorder.Exception
     * @throws org.bytedeco.javacv.FrameRecorder.Exception
     */
    public void frameRecord(String inputFile, String outputFile, int audioChannel)
            throws Exception {


        boolean isStart=true;//该变量建议设置为全局控制变量,用于控制录制结束
        // 获取视频源
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile);
        // 流媒体输出地址,分辨率(长,高),是否录制音频(0:不录制/1:录制)
        FFmpegFrameRecorder recorder=new FFmpegFrameRecorder(outputFile,1280,720,audioChannel);
        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(25);

        recorder.setVideoOption("preset", "ultrafast");
        recorder.setVideoOption("tune", "zerolatency");
        recorder.setVideoOption("fflags", "nobuffer");
        recorder.setVideoOption("analyzeduration", "0");
        // 开始取视频源
        mapParas.put("s",true);
        recordByFrame(grabber, recorder);


    }

    public static Mat bufferedImageToMat(BufferedImage bi) {
        Mat mat = new Mat(bi.getHeight(), bi.getWidth(), CvType.CV_8UC3);
        byte[] data = ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();
        mat.put(0, 0, data);
        return mat;
    }
    public void recordByFrame(FFmpegFrameGrabber grabber,FFmpegFrameRecorder recorder) throws Exception{
        //javacv提供的转换器,方便mat转换为Frame
        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
        final Java2DFrameConverter frameConverter = new Java2DFrameConverter();        try{
            grabber.start();
            recorder.start();
            Frame frame=null;
            boolean status=(Boolean) mapParas.get("s");
            int index=0;

            //--在帧上面添加文字。
            CvFont font = new CvFont();
            cvInitFont(font, CV_FONT_HERSHEY_PLAIN, 2.0, 2.0, 2, 2, CV_AA);
            String logoText="我打了水印";//水印文字
            // 水印文字位置
            org.bytedeco.opencv.opencv_core.Point point = new Point(10, 50);
            // 颜色,使用黄色
            Scalar scalar = new Scalar(0, 255, 255, 0);

            OpenCVFrameConverter.ToIplImage iplConverter = new OpenCVFrameConverter.ToIplImage();
            Java2DFrameConverter java2dConverter = new Java2DFrameConverter();


            while(status&&(frame=grabber.grab())!=null&&!Thread.interrupted()){
                final BufferedImage bufferedImage = frameConverter.convert(frame);

                //--画面合成
                if(bufferedImage!=null){
                    mark(bufferedImage,logoText,Color.RED,40,50);
                    IplImage iplImage = iplConverter.convert(java2dConverter.convert(bufferedImage));
//                cvPutText(iplImage/*IplImage*/, logoText, opencv_core.cvPoint(10,50),
//                        font,
//                        CvScalar.RED);
                    /***
                     * bufferedImage 转换为 mat 以便进行图形操作
                     * **/

//                Mat newMat = bufferedImageToMat(bufferedImage);
                    /**添加文字上去**/

//                IplImage bgrImage = IplImage.create(frame.imageWidth, frame.imageHeight,IPL_DEPTH_8U, 3);;

                    index++;
                    System.out.println("第几帧了:"+index);



                    if(iplImage!=null){
                        //--录入画面
                        recorder.record(converter.convert(iplImage));
                    }


                }

                if(frame.samples!=null){
                    //--录入声音
                    recorder.recordSamples(frame.samples);
                }

                //--如果不需要对画面和声音做合成,直接用record(frame)即可。
            }
            System.out.println("结束了,进行相关收尾。");
            grabber.stop();
            grabber.release();
            recorder.stop();
            recorder.release();

        }
        catch (Exception ed){
            ed.printStackTrace();
        }
        finally {
            if(grabber!=null){
                grabber.stop();
                grabber.release();
            }
            if(recorder!=null){
                recorder.stop();
                recorder.release();
            }
        }
    }


    // 加文字水印
    public void mark(BufferedImage bufImg, Image img, String text, Font font, Color color, int x, int y) {
        Graphics2D g = bufImg.createGraphics();
        g.drawImage(img, 0, 0, bufImg.getWidth(), bufImg.getHeight(), null);
        g.setColor(color);
        g.setFont(font);
        g.drawString(text, x, y);
        g.dispose();
    }
    // 加文字水印
    public void mark(BufferedImage bufImg,  String text, Color color, int x, int y) {
        Graphics2D g = bufImg.createGraphics();
        Font currentFont = g.getFont();
        Font newFont = currentFont.deriveFont(currentFont.getSize() * 2F);
        g.setFont(newFont);

        g.setColor(color);
        g.drawString(text, x, y);
        g.dispose();
    }


    public static void main(String[] args) throws Exception {

        /**
         * 本次内容实现了,普通视频-》推送到直播流
         * 直播流-》保存到本地
         * 直播流-》转推其他直播流
         * **/
        Lesson03 test=new Lesson03();
        final String inputFile="/home/too-white/temp/a02.mp4";
        final String outFile="/home/too-white/temp/lesson03_output.flv";
        final String rtmpUrl="rtmp://localhost/live/livestream";
        /**
         * 推荐使用的rtmp直播平台
         * https://blog.csdn.net/zhichaosong/article/details/89053009
         * **/
        final String rtmpOnlineUrl="rtmp://202.69.69.180:443/webcast/bshdlive-pc";


//        test.frameRecord(inputFile,outFile,1);
//        test.frameRecord(inputFile,rtmpUrl,1);
//        test.frameRecord(rtmpOnlineUrl,outFile,1);
        test.frameRecord(rtmpOnlineUrl,rtmpUrl,1);

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

猜你喜欢

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