1. 程式人生 > >javaCV開發詳解之4:轉流器實現(也可作為本地收流器、推流器,新增新增圖片及文字水印,視訊影象幀儲存),實現rtsp/rtmp/本地檔案轉發到rtmp流媒體伺服器(基於javaCV-FFMPEG)

javaCV開發詳解之4:轉流器實現(也可作為本地收流器、推流器,新增新增圖片及文字水印,視訊影象幀儲存),實現rtsp/rtmp/本地檔案轉發到rtmp流媒體伺服器(基於javaCV-FFMPEG)

javaCV系列文章:

補充篇:

  • 歡迎大家積極開心的加入討論群

javacpp-ffmpeg:

前言:

本章基於javaCV實現轉流器和收流器功能,測試採用監控rtsp地址轉發至rtmp伺服器地址

新增openCV儲存圖片功能。

補充:

作為轉流器可以輕鬆實現rtsp/rtmp/本地檔案/本地攝像頭推送到rtmp流媒體伺服器;

作為收流器可以用來把流媒體伺服器視訊流錄製到本地檔案。

關於預設接收/推送rtsp流丟幀問題,由於ffmpeg預設採用udp方式,所以可以通過更改為tcp的方式來實現丟幀補償,解決方式如下:

1、FFmpeg命令方式:增加一個配置命令 -rtsp_transport tcp

2、javacv方式:FFmpegFrameGrabber.java中533行 AVDictionary options= new AVDictionary(null);後面增加一個配置av_dict_set(options, "rtsp_transport", "tcp", 0); 即可

3、ffmpeg原生方式:同上

一、開發所依賴的包(具體依賴包請檢視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的方式新增水印

如何從grabber中獲取BufferedImage:

//獲取BufferedImage可以給影象幀新增水印
		Java2DFrameConverter javaconverter=new Java2DFrameConverter();
		BufferedImage buffImg=javaconverter.convert(grabber.grab());

獲取到了BufferedImage我們就可以給視訊幀新增文字或者圖片水印了

二、程式碼實現

本功能實現按幀取流和轉發服務

/**
	 * 轉流器
	 * @param inputFile
	 * @param outputFile
	 * @throws Exception
	 * @throws org.bytedeco.javacv.FrameRecorder.Exception
	 * @throws InterruptedException
	 */
	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("沒有取到第一幀");
		}
		//如果想要儲存圖片,可以使用 opencv_imgcodecs.cvSaveImage("hello.jpg", grabbedImage);來儲存圖片
		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); // 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:[email protected]:37779/cam/realmonitor?channel=1&subtype=0";

		String outputFile="rtmp://192.168.30.21/live/pushFlow";

		recordPush(inputFile, outputFile,25);

支援eguid原創

相關推薦

javaCV開發4實現作為本地新增新增圖片文字水印視訊影象儲存實現rtsp/rtmp/本地檔案轉發rtmp媒體伺服器(基於javaCV-FFMPEG)

javaCV系列文章: 補充篇: 歡迎大家積極開心的加入討論群 javacpp-ffmpeg: 前言: 本章基於javaCV實現轉流器和收流器功能,測試採用監控rtsp地址轉發至rtmp伺服器地址 新增openCV儲存圖片功能。 補充:

[]javaCV開發5錄製音訊(錄製麥克風)到本地檔案/媒體伺服器(基於javax.soundjavaCV-FFMPEG)

本文轉載自部落格:https://blog.csdn.net/eguid_1/article/details/52702385 ------------------------------------------------------------------------------------

javaCV開發2實現本地攝像頭視訊媒體伺服器以及攝像頭錄製視訊功能實現(基於javaCV-FFMPEGjavaCV-openCV)

javaCV系列文章: 補充篇: 歡迎大家積極開心的加入討論群 javacpp-ffmpeg: 前言: 本章將在上一章的基礎上,增加視訊推流到流媒體伺服器和視訊錄製的功能; 功能:實現邊播放邊錄製/推流,停止預覽即停止錄製/推流 提示:

javacv開發1呼叫本機攝像頭視訊建議使用javaCV1.3版本

javaCV系列文章: 補充篇: 前言:javacv開發包是用於支援java多媒體開發的一套開發包,可以適用於本地多媒體(音視訊)呼叫以及音視訊,圖片等檔案後期操作(圖片修改,音視訊解碼剪輯等等功能),這裡只使用最簡單的本地攝像頭呼叫來演示一下javacv

UIView控制元件改變座標系convertRect:

一、示例 如下圖所示,橙色view是藍色view的子控制元件,藍色view是綠色view的子控制元件。由於橙色view的frame是參考藍色view的,因此,如果需要獲取橙色view相對於綠色view的位置,就必須進行座標系的轉換。 二、實現方法 UIView類中提供瞭如下四個方法,可以改變座標系

Git開發第一講Git分割槽配置與日誌

前言 曾經聽到過這樣一句話:不會git就不要敲程式碼了。細細品味確實有其中的道理,可能是當事人程式碼被強行覆蓋後的嘆息吧! 因此,為了避免這種情況,接下來我們就一起來好好學習git的相關知識吧!不怕你不會,就怕你不看! 一、git的三個分割槽: 工作區(working directory) 暫存區(st

OSPFOSPF LSA

ospf lsa詳解 forwarding address OSPF LSA詳解OSPF V2版本中常用的主要有6類LSA,分別是Router-LSA、Network-LSA、Network-summary-LSA、ASBR-summary-LSA、AS-External-LSA、NSSA-LSA,接

ZCU106開發VIVADO開發環境的安裝

感謝大家漫長的等待!! 我們團隊從去年底拿到ZCU106後就一直在進行相關研發,由於手頭上的活比較多就把ZCU106開發詳解的釋出給延遲了。 從本週開始我們團隊開始對我們在ZCU106開發過程中遇到的問題和解決辦法跟大家進行分享。我們的QQ群是836535064。希望跟大家一起玩好這一個牛逼的晶片。

Android開發onTouch和onClick

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

MyGUI3.2.0+Ogre1.8.1開發第一個MyGUI程式

  mygui是一款簡單、易用的開源圖形介面開發庫,主要面向物件是遊戲的3D介面,下面是它的官方介紹 MyGUI是為遊戲和3D應用程式建立圖形使用者介面(GUI)的一個庫。 mygui的主要目標是:速度,靈活性和易用性。(出自MyGUI官網) 官方網站:http

ALSA音效卡驅動中的DAPMwidget-具備路徑和電源管理資訊的kcontrol

上一篇文章中,我們介紹了音訊驅動中對基本控制單元的封裝:kcontrol。利用kcontrol,我們可以完成對音訊系統中的mixer,mux,音量控制,音效控制,以及各種開關量的控制,通過對各種kcontrol的控制,使得音訊硬體能夠按照我們預想的結果進行工作。同時我

ALSA音效卡驅動中的DAPMdapm事件機制dapm event

前面的六篇文章,我們已經討論了dapm關於動態電源管理的有關知識,包括widget的建立和初始化,widget之間的連線以及widget的上下電順序等等。本章我們準備討論dapm框架中的另一個機制:事件機制。通過dapm事件機制,widget可以對它所關心的dapm事

ZCU106開發PS側MIO閃燈重磅推出

感謝大家兩週的等待!!本週連發兩篇!!!!  最近團隊事情比較多,在忙ZCU106的視訊處理方面的開發實現了編解碼,RTSP視訊流,影象疊加等應用。如果有朋友想了解更多相關資訊請加QQ群836535064。我們會將相關資料釋出於QQ群中。 歡迎有需求的朋友深度合作。本團隊

ZCU106開發AXI_Bram重磅推出進階必備

感謝大家兩週的等待!!本週連發兩篇!!!!  最近團隊事情比較多,在忙ZCU106的視訊處理方面的開發實現了編解碼,RTSP視訊流,影象疊加等應用。如果有朋友想了解更多相關資訊請加QQ群836535064。我們會將相關資料釋出於QQ群中。 歡迎有需求的朋友深度合作。本團隊

ZCU106開發AXI_HP重磅推出進階必備

感謝大家的等待!! 如果有朋友想了解更多相關資訊請加QQ群836535064。我們會將相關資料釋出於QQ群中。 歡迎有需求的朋友深度合作。本團隊專注於高速視訊編解碼,高速訊號採集處理方案提供。同樣也請入群加管理員。 ZCU106開發詳解之AXI_Bram(重磅推

大資料hdfsput許可權剖析與常用命令

–無論是對於hdfs的讀和寫,對於使用者來說都是無感知的、透明的操作,使用者並不關心資料如何讀出來如何寫進去的,只要返回一個結果告訴使用者資料讀出來了或寫進去了,至於怎麼讀怎麼寫,使用者並不關心 補充: 讀:hdfs dfs -ls / = hdfs dfs

ZCU106開發PS側SD卡FAT32檔案系統高階外設大神

感謝大家的等待!! 本週將四連發,我們團隊也將盡自己能力為大家答疑解惑!!! 如果有朋友想了解更多相關資訊請加QQ群836535064。我們會將相關資料釋出於QQ群中。 歡迎有需求的朋友深度合作。本團隊專注於高速視訊編解碼,高速訊號採集處理,高速異構平臺,高速儲存方案提

ZCU106開發PS側開源TCP/IP協議棧UDP回顯程式高階外設大神

感謝大家的等待!! 本週將四連發,我們團隊也將盡自己能力為大家答疑解惑!!! 如果有朋友想了解更多相關資訊請加QQ群836535064。我們會將相關資料釋出於QQ群中。 歡迎有需求的朋友深度合作。本團隊專注於高速視訊編解碼,高速訊號採集處理,高速異構平臺,高速儲存方案提

ALSA音效卡驅動中的DAPM建立widget之間的連線關係

前面我們主要著重於codec、platform、machine驅動程式中如何使用和建立dapm所需要的widget,route,這些是音訊驅動開發人員必須要了解的內容,經過前幾章的介紹,我們應該知道如何在alsa音訊驅動的3大部分(codec、platform、machin

【OpenCV3影象處理】Mat類 元素的獲取與賦值 對比.at<>()函式 和 .ptr<>()函式

Mat中畫素的獲取與賦值 計算機視覺中,影象的讀取是影象處理的基礎,影象就是一系列畫素值,OpenCV使用資料結構cv::Mat來儲存影象。cv::Mat是一個矩陣類,矩陣中每一個元素都代表一個畫素,對於灰度影象,畫素用8位無符號數,0表示黑色,255表示白色。對於彩色