1. 程式人生 > >利用ffmpeg獲取rtsp視訊流並使用opencv播放

利用ffmpeg獲取rtsp視訊流並使用opencv播放

/*opencv庫*/
#include <opencv2\opencv.hpp>
#include <iostream>
extern "C"   /*這裡必須要使用C方式匯入*/
{
#include "libavcodec/avcodec.h"
#include "libavdevice/avdevice.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
#include "libavutil/avutil.h"
#include "libavutil/time.h"
#include "libswscale/swscale.h"
#include "libavutil/pixdesc.h"
}

#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avdevice.lib")
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avfilter.lib")
#pragma comment(lib, "swscale.lib")
#pragma comment(lib, "swresample.lib")
#pragma comment(lib, "postproc.lib")

using namespace std;
using namespace cv;

void open_rtsp(const char *rtsp)
{
	unsigned int    i;
	int             ret;
	int             video_st_index = -1;
	int             audio_st_index = -1;
	AVFormatContext *ifmt_ctx = NULL;
	AVPacket        pkt;
	AVStream        *st = NULL;
	char            errbuf[64];
	AVDictionary *optionsDict = NULL;
	av_register_all();                                                          // Register all codecs and formats so that they can be used.
	avformat_network_init();                                                    // Initialization of network components
	av_dict_set(&optionsDict, "rtsp_transport", "tcp", 0);                //採用tcp傳輸	,,如果不設定這個有些rtsp流就會卡著
	av_dict_set(&optionsDict, "stimeout", "2000000", 0);                  //如果沒有設定stimeout
	if ((ret = avformat_open_input(&ifmt_ctx, rtsp, 0, &optionsDict)) < 0) {            // Open the input file for reading.
		printf("Could not open input file '%s' (error '%s')\n", rtsp, av_make_error_string(errbuf, sizeof(errbuf), ret));
		goto EXIT;
	}

	if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {                // Get information on the input file (number of streams etc.).
		printf("Could not open find stream info (error '%s')\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
		goto EXIT;
	}

	for (i = 0; i < ifmt_ctx->nb_streams; i++) {                                // dump information
		av_dump_format(ifmt_ctx, i, rtsp, 0);
	}

	for (i = 0; i < ifmt_ctx->nb_streams; i++) {                                // find video stream index
		st = ifmt_ctx->streams[i];
		switch (st->codec->codec_type) {
		case AVMEDIA_TYPE_AUDIO: audio_st_index = i; break;
		case AVMEDIA_TYPE_VIDEO: video_st_index = i; break;
		default: break;
		}
	}
	if (-1 == video_st_index) {
		printf("No H.264 video stream in the input file\n");
		goto EXIT;
	}

	av_init_packet(&pkt);                                                       // initialize packet.
	pkt.data = NULL;
	pkt.size = 0;
	bool nRestart = false;
	int videoindex = -1;
	int audioindex = -1;
	AVStream *pVst;
	uint8_t* buffer_rgb = NULL;
	AVCodecContext *pVideoCodecCtx = NULL;
	AVFrame         *pFrame = av_frame_alloc();
	AVFrame         *pFrameRGB = av_frame_alloc();
	int got_picture;
	SwsContext      *img_convert_ctx = NULL;
	AVCodec *pVideoCodec = NULL;


	//if (!faceCascade.load(faceCascadeFileName))
	{
		cout << "臉模型檔案載入失敗" << endl;
		//return;
	}
	//if (!eyesCascade.load(eyesCasecadeFileName))
	{
		cout << "人眼模型檔案載入失敗" << endl;
		//return;
	}

	while (1)
	{
		do {
			ret = av_read_frame(ifmt_ctx, &pkt);                                // read frames
#if 1
			cout << pkt.size << endl;
			//decode stream
			if (!nRestart)
			{
				for (int i = 0; i < ifmt_ctx->nb_streams; i++)
				{
					if ((ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) && (videoindex < 0))
					{
						videoindex = i;
					}
					if ((ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) && (audioindex < 0))
					{
						audioindex = i;
					}
				}
				pVst = ifmt_ctx->streams[videoindex];
				pVideoCodecCtx = pVst->codec;
				pVideoCodec = avcodec_find_decoder(pVideoCodecCtx->codec_id);
				if (pVideoCodec == NULL)
					return;
				//pVideoCodecCtx = avcodec_alloc_context3(pVideoCodec);

				if (avcodec_open2(pVideoCodecCtx, pVideoCodec, NULL) < 0)
					return;
			}

			if (pkt.stream_index == videoindex)
			{
				fprintf(stdout, "pkt.size=%d,pkt.pts=%lld, pkt.data=0x%x.", pkt.size, pkt.pts, (unsigned int)pkt.data);
				int av_result = avcodec_decode_video2(pVideoCodecCtx, pFrame, &got_picture, &pkt);

				if (got_picture)
				{
					fprintf(stdout, "decode one video frame!\n");
				}

				if (av_result < 0)
				{
					fprintf(stderr, "decode failed: inputbuf = 0x%x , input_framesize = %d\n", pkt.data, pkt.size);
					return;
				}
#if 1
				if (got_picture)
				{
					int bytes = avpicture_get_size(AV_PIX_FMT_RGB24, pVideoCodecCtx->width, pVideoCodecCtx->height);
					buffer_rgb = (uint8_t *)av_malloc(bytes);
					avpicture_fill((AVPicture *)pFrameRGB, buffer_rgb, AV_PIX_FMT_RGB24, pVideoCodecCtx->width, pVideoCodecCtx->height);

					img_convert_ctx = sws_getContext(pVideoCodecCtx->width, pVideoCodecCtx->height, pVideoCodecCtx->pix_fmt,
						pVideoCodecCtx->width, pVideoCodecCtx->height, AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
					if (img_convert_ctx == NULL)
					{

						printf("can't init convert context!\n");
						return;
					}
					sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pVideoCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
					IplImage *pRgbImg = cvCreateImage(cvSize(pVideoCodecCtx->width, pVideoCodecCtx->height), 8, 3);
					memcpy(pRgbImg->imageData, buffer_rgb, pVideoCodecCtx->width * 3 * pVideoCodecCtx->height);
					Mat Img = cvarrToMat(pRgbImg, true);

					cvShowImage("GB28181Show", pRgbImg);

					//DetectFace(Img);
					cvWaitKey(10);
					cvReleaseImage(&pRgbImg);
					sws_freeContext(img_convert_ctx);
					av_free(buffer_rgb);
				}
#endif
			}

#endif
		} while (ret == AVERROR(EAGAIN));

		if (ret < 0) {
			printf("Could not read frame ---(error '%s')\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
			goto EXIT;
		}

		if (pkt.stream_index == video_st_index) {                               // video frame
			printf("Video Packet size = %d\n", pkt.size);
		}
		else if (pkt.stream_index == audio_st_index) {                         // audio frame
			printf("Audio Packet size = %d\n", pkt.size);
		}
		else {
			printf("Unknow Packet size = %d\n", pkt.size);
		}

		av_packet_unref(&pkt);
	}

EXIT:

	if (NULL != ifmt_ctx) {
		avformat_close_input(&ifmt_ctx);
		ifmt_ctx = NULL;
	}

	return;
}

int main(int argc, char* argv[])
{
while(1)
open_rtsp("rtsp://192.168.17.1/myz.mkv");
return 0;
}

原始碼路徑:https://github.com/lcmftianci/ffmpeg_rtsp_vs2015/tree/master/libonvif/RtspClient

加QQ群一起交流學習音視訊開發:476513431

相關推薦

利用ffmpeg獲取rtsp視訊流使用opencv播放

/*opencv庫*/ #include <opencv2\opencv.hpp> #include <iostream> extern "C" /*這裡必須要使用C方式匯入*/ { #include "libavcodec/avcodec.h"

apt-get安裝FFmpeg利用FFmpeg命令列獲取rtsp視訊流

執行環境:Ubuntu 14.04 注意:Ubuntu 12.04環境執行會出錯!!巨坑,很多人沒指定執行環境就把FFmpeg命令放到網上!!博主剛學FFmpeg的時候一直在Ubuntu 12.04下

RTSP再學習 -- 利用FFmpegrtsp 獲取H264裸流儲存到檔案中

既然已經可以通過 RTSP 獲取h264 裸流了。那麼通過 FFmpeg 將其儲存到檔案中怎麼做呢?一、首先RTSP獲取 h264 裸流我們上面兩篇文章主要講的是通過 rtsp://Your ip:554/stream_chn0.h265 播放H.265視訊流。PS:我剛試了

FFmpeg 獲取RTSP傳過來的視訊資料儲存成檔案

  廢話不多說,直接上程式碼。   需要注意的是,FFmpeg的版本很多,最新版本可能有些函式已經換成別的了。如果無法自行更改程式碼,可以找我以前相關FFmpeg的文章,下載我x64版本的工程包,裡面就有這個版本的FFmpeg。 #ifndef IN

FFmpeg 解碼本地視訊實現播放功能

本文寫於17年,FFMpeg 版本是3.0,demo在我的github可見:FFmpeg_decoder av_registerall(); avformart_network_init(); AVDictionary *opts = NULL; av_dict_set(&opt

利用ffmpeg錄製rtsp流的方法總結(一)

這裡主要結合平時對音視訊的學習,將ffmpeg錄製rtsp的方法在這裡記錄下。 首先,一般的錄製過程都是按照如下的流程圖進行錄製,除非某些不存在音訊的特殊情況。  這個是總體的錄製流程,然而這個流程對於推流來說也適用。因此對於流程中每一步的實現,需要弄明白。 在進入

FFmpeg獲取攝像頭資料編碼為H.264

       ffmpeg的視音訊編解碼功能非常強大,可以說包括了所有的視音訊編碼標準。在這裡我主要是呼叫ffmpeg工程裡的ffmpeg.exe檔案,呼叫之後,會自動完成編碼的操作。內部編碼的具體流程,以後再慢慢的看。1.介紹       先介紹下ffmpeg裡面的三個ex

RTSP視訊流的遠端播放的實現

無心學習,把最近這段時間的所想所思寄託在這片土地上,算是對自己的一個交代,也是對各位大大們的一種感激。 原料: (1)海康威視攝像頭一個 (2)PC機一臺 (3)阿里ip一個 實現的原理: (1)ffmpeg的轉碼 (2)傳送到ffserver伺服器等待監聽, (3)轉發

利用HtmlParse獲取Html內容提取

一.      網上獲取html內容 1.利用url獲取html內容: public static String getHtmlContent(String urlstr){ /*思路: 1.讀出原網頁:url--》openstream--》inputStreamRe

FFmpeg總結(十二)用ffmpeg與nginx實現直播多路流播放

xxx 開源 conf ref itl rect arc med rtm 圖:撒哈拉沙漠 下載 nginx 和 nginx-rtmp源碼: http://nginx.org/download/nginx-1.5.10.tar.gz https://github.com/a

利用Python3獲取辦公室的公網IP修改阿裏雲安全組規則

lencod 函數 range plain url move __name__ method port 阿裏雲Python SDK:SDK使用說明 API詳情請參考:阿裏雲ECS API 安裝依賴 #本文使用的Python版本為Python 3.7 pip

FFmpeg:視頻轉碼、剪切、合播放速調整

基本上 不安裝 同時 using 上傳 lis got 轉碼 導師 原文:https://fzheng.me/2016/01/08/ffmpeg/ FFmpeg:視頻轉碼、剪切、合並、播放速調整 2016-01-08 前陣子幫導師處理項目 ppt,因為插入視頻的格式問題被搞

利用sklearn獲取手寫數字數據集,進行可視化

字數 size pre code http text 添加 col sha %matplotlib inline from sklearn import datasets from matplotlib import pyplot as plt #獲取數據集 digits

使用ffmpeg轉碼m3u8播放

之前把一個MP4檔案入在雲伺服器,嘗試訪問,結果只能下載,不能訪問,主要還是想的太簡單了,鼓搗了一段時間後也沒去想了。後來發現很多視訊網站上的檔案源都是M3U8格式的,也沒去深入研究。今天心血來潮又研究了一下,發現還是挺簡單的。可以使用ffmpeg工具將mp4格式的視訊切片再生成 m3u8視訊流。m3u8簡介

python opencv 讀取rtsp視訊流

import cv2 cap = cv2.VideoCapture("rtsp://admin:[email protected]:554//Streaming/Channels/1") ret,frame = cap.read() while ret: ret,frame =

利用C++獲取某一資料夾下的所有檔名,獲取不帶字尾的檔名字

來源:https://www.cnblogs.com/fnlingnzb-learner/p/6424563.html 那麼到底如何查詢檔案呢?我們需要一個結構體和幾個大家可能不太熟悉的函式。這些函式和結構體在<io.h>的標頭檔案中, 結構體為struct _finddata_t

ffmpeg解碼視訊檔案播放

        最近學習了一下如何使用ffmpeg解碼音視訊,網上的教程挺多但是也挺雜的,搞了好幾天,明白了ffmpeg解碼音視訊的大體流程,這裡記錄一下ffmpeg解碼視訊並播放音視訊的例子,但並沒有做音訊、視訊播放 的同步處理。 直接上程式碼: #include &l

使用ffmpeg+nginx進行rtsp視訊流至rtmp視訊流的轉換

說明: 作業系統:window server 2008 R2 步驟: 1、安裝ffmpeg: 2、安裝nginx 需要下載舊版nginx並安裝nginx-rtmp-module(我使用的是從網上下載的nginx-rtmp整合版,版本號:nginx:1.11.

利用pyrealsense獲取深度圖,進行畫素對齊

系統:Ubuntu16.04 python版本:python2.7 核心版本:4.13.0 realsense SDK:librealsense1.12.1 python wrapper:pyrealsense2.2 這裡的pyrealsense2.2指的是pyrealsense

java利用反射獲取某個包下的所有獲取物件屬性、方法、例項化

首先貼上用到的jar包,當然也可以通過遞迴file.list獲取類的路徑名稱。 maven匯入jar包: <dependency> <groupId>