ffmpeg は rtsp h265 を取得し、ffmpeg を使用して RTSP サーバーからストリームを取得し、さまざまな形式でファイルを保存します

ffmpeg: FFmpeg という名前は、MPEG ビデオ エンコード規格に由来しています。その前の「FF」は「Fast Forward」を表します。これは、デジタル オーディオとビデオの記録と変換に使用できるオープン ソース コンピューター プログラムのセットです。そしてそれらをストリームに変換します。

ライブラリ構成:

libavformat: さまざまなオーディオおよびビデオのカプセル化フォーマットの生成および解析に使用されます。これには、デコードに必要な情報を取得してデコード コンテキスト構造を生成したり、オーディオおよびビデオ フレームを読み取ったりする機能が含まれます。

libavcodec: さまざまな種類のサウンド/画像のエンコードおよびデコードに使用されます。

libavutil: いくつかの公共ユーティリティ関数が含まれています。

libswscale: ビデオ シーンのスケーリングとカラー マッピングの変換に使用されます。

libpostproc: ポストエフェクト処理に使用されます。

ffmpeg: このプロジェクトによって提供されるツール。TV カードのフォーマット変換、デコード、またはリアルタイム エンコードに使用できます。

ffsever: HTTP マルチメディア リアルタイム ブロードキャスト ストリーミング サーバー。

ffplay: ffmpeg ライブラリを使用して解析およびデコードし、SDL を通じて表示する単純なプレーヤーです。

一般に、カメラの RTSP から取得するビデオ ストリームは、オリジナルのデータ ストリームである「ネイキッド ストリーム」です。結果として得られるコード ストリームは通常 h264 または h265 です。av_read_frame() を使用して各フレームのデータを読み取ります。データは構造体 AVpack に格納されます。

ビデオ ストリームを h264 および h265 ファイルに保存するプロセス:

( av_register_all() 函数在ffmpeg4.0以上版本已经被废弃,所以4.0以下版本就需要注册初始函数)

avformat_alloc_context( );用来申请AVFormatContext类型变量并初始化默认参数,申请的空间

avformat_open_input();打开网络流或文件流

avformat_find_stream_info();获取视频文件信息

av_malloc(sizeof( AVPacket ));  申请 AVPacket 空间,以便存放数据

av_read_frame();读取每一帧的(h264、h265)数据,存放在结构体AVPack里面

fwrite();写入文件,h264编码的文件的后缀写.h264,h265编码的文件的后缀写.h265,

av_free( packet );  写完之后释放  AVPacket 的空间

avformat_free_context( );函数释放空间

avformat_close_input();关闭rtsp流

用FFmpeg将rtsp视频流保存成文件的demo:

#include #include #ifdef __cplusplus

extern "C"

{

#endif

/*Include ffmpeg header file*/

#include #ifdef __cplusplus

}

#endif

int main()

{

AVFormatContext *pFormatCtx = NULL;

AVDictionary *options = NULL;

AVPacket *packet = NULL;

char filepath[] = "rtsp://172.168.0.161:554/11";

//av_register_all(); //函数在ffmpeg4.0以上版本已经被废弃,所以4.0以下版本就需要注册初始函数

av_dict_set(&options, "buffer_size", "1024000", 0); //设置缓存大小,1080p可将值跳到最大

av_dict_set(&options, "rtsp_transport", "tcp", 0); //以tcp的方式打开,

av_dict_set(&options, "stimeout", "5000000", 0); //设置超时断开链接时间,单位us

av_dict_set(&options, "max_delay", "500000", 0); //设置最大时延

pFormatCtx = avformat_alloc_context(); //用来申请AVFormatContext类型变量并初始化默认参数,申请的空间

//打开网络流或文件流

if (avformat_open_input(&pFormatCtx, filepath, NULL, &options) != 0)

{

printf("Couldn't open input stream.\n");

return 0;

}

//获取视频文件信息

if (avformat_find_stream_info(pFormatCtx, NULL)<0)

{

printf("Couldn't find stream information.\n");

return 0;

}

//查找码流中是否有视频流

int videoindex = -1;

unsigned i = 0;

for (i = 0; inb_streams; i++)

if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)

{

videoindex = i;

break;

}

if (videoindex == -1)

{

printf("Didn't find a video stream.\n");

return 0;

}

packet = (AVPacket *)av_malloc(sizeof(AVPacket)); // 申请空间,存放的每一帧数据 (h264、h265)

FILE *fpSave;

fpSave = fopen("geth264_test.h264", "wb");

//这边可以调整i的大小来改变文件中的视频时间,每 +1 就是一帧数据

for (i = 0; i < 200; i++)

{

if (av_read_frame(pFormatCtx, packet) >= 0)

{

if (packet->stream_index == videoindex)

{

fwrite(packet->data, 1, packet->size, fpSave);

}

av_packet_unref(packet);

}

}

fclose(fpSave);

av_free(packet);

avformat_close_input(&pFormatCtx);

return 0;

}

おすすめ

転載: blog.csdn.net/xiehuanbin/article/details/133162374