javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG、javaCV-openCV)

javaCV系列文章:

javacv开发详解之1:调用本机摄像头视频

javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG、javaCV-openCV)

javaCV开发详解之3:收流器实现,录制流媒体服务器的rtsp/rtmp视频文件(基于javaCV-FFMPEG)

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

javaCV开发详解之5:录制音频(录制麦克风)到本地文件/流媒体服务器(基于javax.sound、javaCV-FFMPEG)

javaCV开发详解之6:本地音频(话筒设备)和视频(摄像头)抓取、混合并推送(录制)到服务器(本地)

javaCV开发详解之7:让音频转换更加简单,实现通用音频编码格式转换、重采样等音频参数的转换功能(以pcm16le编码的wav转mp3为例)

补充篇:

音视频编解码问题:javaCV如何快速进行音频预处理和解复用编解码(基于javaCV-FFMPEG)

音视频编解码问题:16/24/32位位音频byte[]转换为小端序short[],int[],以byte[]转short[]为例

实现给图片增加图片水印或者文字水印(也支持视频图像帧添加水印)


前言:

上一章简单的介绍了javacv并且演示了如何获取本机摄像头:http://blog.csdn.net/eguid_1/article/details/51659578

本章将在上一章的基础上,增加视频推流到流媒体服务器和视频录制的功能;

功能:实现边播放边录制/推流,停止预览即停止录制/推流

基于本章代码可以轻松实现多人直播功能

一、开发所依赖的包

本章使用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;


javaCV的基础支撑包:javacv.jar,javacpp.jar,opencv.jar,opencv-windows-x86_64.jar、opencv-windows-x86.jar;


补充:opencv以及ffmpeg的包需要根据对应平台加载对应的包,本章使用windows平台依赖包,因此只引入了windows平台的包。

二、代码实现

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

注:时间运行该代码会导致内存溢出的原因是没有及时释放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);
		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");
		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);
		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();
	
	}

3、测试录制功能和推流功能

public static void main(String[] args) throws Exception, InterruptedException, org.bytedeco.javacv.FrameRecorder.Exception {
		recordCamera("output.mp4",25);
	}
public static void main(String[] args) throws Exception, InterruptedException, org.bytedeco.javacv.FrameRecorder.Exception {
		recordCamera("rtmp://192.168.30.21/live/record1",25);
	}


看到了摄像头窗口就说明已经开始录制,点击右上角关闭按钮即停止录制视频,在录制的时候刷新项目目录发现新生成了一个output.mp4文件,可以正常播放这个视频文件

到这章我们已经实现了录制本地摄像头视频和推送摄像头的视频到服务器,小伙伴们已经迫不及待的开始在线直播show了 - -!

既然已经实现了在线直播,那么我们想要保存别人的在线直播视频怎么办呢?

下一章将会讲解如何录制流媒体服务器的视频到本地文件

javaCV开发详解之3:收流器实现,录制流媒体服务器的rtsp/rtmp视频文件









你可能感兴趣的:(ffmpeg,javacv,opencv,录制,推流)