当前位置: 代码迷 >> 综合 >> javaCV开发详解之4:转流器实现(也可作为本地收流器、推流器,新增添加图片及文字水印,视频图像帧保存),实现rtsp/rtmp/本地文件转发到rtmp流媒体服务器(基于javaCV-FFMPEG)
  详细解决方案

javaCV开发详解之4:转流器实现(也可作为本地收流器、推流器,新增添加图片及文字水印,视频图像帧保存),实现rtsp/rtmp/本地文件转发到rtmp流媒体服务器(基于javaCV-FFMPEG)

热度:36   发布时间:2023-11-25 03:15:21.0
转自:http://blog.csdn.net/eguid_1/article/details/52678775
本章基于javaCV实现转流器和收流器功能,测试采用监控rtsp地址转发至rtmp服务器地址
新增openCV保存图片功能。
补充:
作为转流器可以轻松实现rtsp/rtmp/本地文件/本地摄像头推送到rtmp流媒体服务器;
作为收流器可以用来把流媒体服务器视频流录制到本地文件。

一、开发所依赖的包(具体依赖包请查看javacv开发详解之1)

本章使用windows环境开发,基于javaCV的基础支撑包以及ffmpeg-3.1.2-1.2.jar、ffmpeg-3.1.2-1.2-windows-x86.jar、ffmpeg-3.1.2-1.2-windows-x86_64.jar;

补充:

如果想要给视频添加水印,需要从视频中取出图像帧,给图像帧添加文字、图片水印即可

在此之前我们需要取到BufferedImage,通过这个我们就可以用Java的方式添加水印

如何用java添加水印:http://blog.csdn.net/eguid_1/article/details/52973508

如何从grabber中获取BufferedImage:

[java] view plaincopy
print?

      1. //获取BufferedImage可以给图像帧添加水印  
      2.         Java2DFrameConverter javaconverter=new Java2DFrameConverter();  
      3.         BufferedImage buffImg=javaconverter.convert(grabber.grab());  
获取到了 BufferedImage我们就可以给视频帧添加文字或者图片水印了

二、代码实现

本功能实现按帧取流和转发服务


[java] view plaincopy
print?

      1. /** 
      2.      * 转流器 
      3.      * @param inputFile 
      4.      * @param outputFile 
      5.      * @throws Exception 
      6.      * @throws org.bytedeco.javacv.FrameRecorder.Exception 
      7.      * @throws InterruptedException 
      8.      */  
      9.     public static void recordPush(String inputFile,String outputFile,int v_rs) throws Exception, org.bytedeco.javacv.FrameRecorder.Exception, InterruptedException{  
      10.         Loader.load(opencv_objdetect.class);  
      11.         long startTime=0;  
      12.         FrameGrabber grabber =FFmpegFrameGrabber.createDefault(inputFile);  
      13.         try {  
      14.             grabber.start();  
      15.         } catch (Exception e) {  
      16.             try {  
      17.                 grabber.restart();  
      18.             } catch (Exception e1) {  
      19.                 throw e;  
      20.             }  
      21.         }  
      22.           
      23.         OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();  
      24.         Frame grabframe =grabber.grab();  
      25.         IplImage grabbedImage =null;  
      26.         if(grabframe!=null){  
      27.             System.out.println("取到第一帧");  
      28.             grabbedImage = converter.convert(grabframe);  
      29.         }else{  
      30.             System.out.println("没有取到第一帧");  
      31.         }  
      32.         //如果想要保存图片,可以使用 opencv_imgcodecs.cvSaveImage("hello.jpg", grabbedImage);来保存图片  
      33.         FrameRecorder recorder;  
      34.         try {  
      35.             recorder = FrameRecorder.createDefault(outputFile, 1280720);  
      36.         } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {  
      37.             throw e;  
      38.         }  
      39.         recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // avcodec.AV_CODEC_ID_H264  
      40.         recorder.setFormat("flv");  
      41.         recorder.setFrameRate(v_rs);  
      42.         recorder.setGopSize(v_rs);  
      43.         System.out.println("准备开始推流...");  
      44.         try {  
      45.             recorder.start();  
      46.         } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {  
      47.             try {  
      48.                 System.out.println("录制器启动失败,正在重新启动...");  
      49.                 if(recorder!=null)  
      50.                 {  
      51.                     System.out.println("尝试关闭录制器");  
      52.                     recorder.stop();  
      53.                     System.out.println("尝试重新开启录制器");  
      54.                     recorder.start();  
      55.                 }  
      56.                   
      57.             } catch (org.bytedeco.javacv.FrameRecorder.Exception e1) {  
      58.                 throw e;  
      59.             }  
      60.         }  
      61.         System.out.println("开始推流");  
      62.         CanvasFrame frame = new CanvasFrame("camera", CanvasFrame.getDefaultGamma() / grabber.getGamma());  
      63.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
      64.         frame.setAlwaysOnTop(true);  
      65.         while (frame.isVisible() && (grabframe=grabber.grab()) != null) {  
      66.             System.out.println("推流...");  
      67.             frame.showImage(grabframe);  
      68.             grabbedImage = converter.convert(grabframe);  
      69.             Frame rotatedFrame = converter.convert(grabbedImage);  
      70.               
      71.             if (startTime == 0) {  
      72.                 startTime = System.currentTimeMillis();  
      73.             }  
      74.             recorder.setTimestamp(1000 * (System.currentTimeMillis() - startTime));//时间戳  
      75.             if(rotatedFrame!=null){  
      76.             recorder.record(rotatedFrame);  
      77.             }  
      78.               
      79.             Thread.sleep(40);  
      80.         }  
      81.         frame.dispose();  
      82.         recorder.stop();  
      83.         recorder.release();  
      84.         grabber.stop();  
      85.         System.exit(2);  
      86.     }  

三、测试转流服务

[java] view plaincopy
print?

      1. public static void main(String[] args)  
      2.             throws FrameRecorder.Exception, FrameGrabber.Exception, InterruptedException {  
      3.   
      4.          String inputFile = "rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0";  
      5.   
      6.         String outputFile="rtmp://192.168.30.21/live/pushFlow";  
      7.   
      8.         recordPush(inputFile, outputFile,25);  
  相关解决方案