详细解决方案
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:
-
-
-
- Java2DFrameConverter javaconverter=new Java2DFrameConverter();
- BufferedImage buffImg=javaconverter.convert(grabber.grab());
获取到了
BufferedImage我们就可以给视频帧添加文字或者图片水印了
二、代码实现
-
-
-
-
-
-
-
-
-
-
- public static void recordPush(String inputFile,String outputFile,int v_rs) throws Exception, org.bytedeco.javacv.FrameRecorder.Exception, InterruptedException{
- Loader.load(opencv_objdetect.class);
- long startTime=0;
- FrameGrabber grabber =FFmpegFrameGrabber.createDefault(inputFile);
- try {
- grabber.start();
- } catch (Exception e) {
- try {
- grabber.restart();
- } catch (Exception e1) {
- throw e;
- }
- }
-
- OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
- Frame grabframe =grabber.grab();
- IplImage grabbedImage =null;
- if(grabframe!=null){
- System.out.println("取到第一帧");
- grabbedImage = converter.convert(grabframe);
- }else{
- System.out.println("没有取到第一帧");
- }
-
- FrameRecorder recorder;
- try {
- recorder = FrameRecorder.createDefault(outputFile, 1280, 720);
- } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
- throw e;
- }
- recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
- recorder.setFormat("flv");
- recorder.setFrameRate(v_rs);
- recorder.setGopSize(v_rs);
- System.out.println("准备开始推流...");
- try {
- recorder.start();
- } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
- try {
- System.out.println("录制器启动失败,正在重新启动...");
- if(recorder!=null)
- {
- System.out.println("尝试关闭录制器");
- recorder.stop();
- System.out.println("尝试重新开启录制器");
- recorder.start();
- }
-
- } catch (org.bytedeco.javacv.FrameRecorder.Exception e1) {
- throw e;
- }
- }
- System.out.println("开始推流");
- CanvasFrame frame = new CanvasFrame("camera", CanvasFrame.getDefaultGamma() / grabber.getGamma());
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setAlwaysOnTop(true);
- while (frame.isVisible() && (grabframe=grabber.grab()) != null) {
- System.out.println("推流...");
- frame.showImage(grabframe);
- grabbedImage = converter.convert(grabframe);
- Frame rotatedFrame = converter.convert(grabbedImage);
-
- if (startTime == 0) {
- startTime = System.currentTimeMillis();
- }
- recorder.setTimestamp(1000 * (System.currentTimeMillis() - startTime));
- if(rotatedFrame!=null){
- recorder.record(rotatedFrame);
- }
-
- Thread.sleep(40);
- }
- frame.dispose();
- recorder.stop();
- recorder.release();
- grabber.stop();
- System.exit(2);
- }
三、测试转流服务
-
-
- public static void main(String[] args)
- throws FrameRecorder.Exception, FrameGrabber.Exception, InterruptedException {
-
- String inputFile = "rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0";
-
- String outputFile="rtmp://192.168.30.21/live/pushFlow";
-
- recordPush(inputFile, outputFile,25);