標籤:
使用ffmpeg類庫進行開發的時候,開啟流媒體(或本地檔案)的函數是avformat_open_input()。
其中開啟網路流的話,前面要加上函數avformat_network_init()。
一般情況下,只要傳入流媒體的url就可以了。但是在開啟某些流媒體的時候,可能需要附加一些參數。
例如在播放中央人民廣播電台的聲音訊號的時候,其url為“rtsp://mms.cnr.cn/cnr003?MzE5MTg0IzEjIzI5NjgwOQ==”
如果直接進行開啟是不會成功的,我們可以使用ffplay做一下實驗:
- ffplay rtsp://mms.cnr.cn/cnr003?MzE5MTg0IzEjIzI5NjgwOQ==
會出現錯誤:
Invalid data found when processing input
這時候我們需要指定其傳輸方式為TCP,需要將命令改為如下形式:
- ffplay -rtsp_transport tcp rtsp://mms.cnr.cn/cnr003?MzE5MTg0IzEjIzI5NjgwOQ==
附加了參數以後,發現就可以正常播放了。
此外還可以附加一些參數,比如
- ffplay -rtsp_transport tcp -max_delay 5000000 rtsp://mms.cnr.cn/cnr003?MzE5MTg0IzEjIzI5NjgwOQ==
在使用FFMPEG類庫進行編程的時候,如何將這些附加的參數傳遞給avformat_open_input()呢?經過研究後發現,可以通過AVDictionary把參數傳給avformat_open_input()。
看一下avformat_open_input()的定義:
- /**
- * Open an input stream and read the header. The codecs are not opened.
- * The stream must be closed with av_close_input_file().
- *
- * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
- * May be a pointer to NULL, in which case an AVFormatContext is allocated by this
- * function and written into ps.
- * Note that a user-supplied AVFormatContext will be freed on failure.
- * @param filename Name of the stream to open.
- * @param fmt If non-NULL, this parameter forces a specific input format.
- * Otherwise the format is autodetected.
- * @param options A dictionary filled with AVFormatContext and demuxer-private options.
- * On return this parameter will be destroyed and replaced with a dict containing
- * options that were not found. May be NULL.
- *
- * @return 0 on success, a negative AVERROR on failure.
- *
- * @note If you want to use custom IO, preallocate the format context and set its pb field.
- */
- int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
/** * Open an input stream and read the header. The codecs are not opened. * The stream must be closed with av_close_input_file(). * * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context). * May be a pointer to NULL, in which case an AVFormatContext is allocated by this * function and written into ps. * Note that a user-supplied AVFormatContext will be freed on failure. * @param filename Name of the stream to open. * @param fmt If non-NULL, this parameter forces a specific input format. * Otherwise the format is autodetected. * @param options A dictionary filled with AVFormatContext and demuxer-private options. * On return this parameter will be destroyed and replaced with a dict containing * options that were not found. May be NULL. * * @return 0 on success, a negative AVERROR on failure. * * @note If you want to use custom IO, preallocate the format context and set its pb field. */int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
可以看出avformat_open_input()的第4個參數是一個AVDictionary類型的參數。這個參數就是傳入的附加參數。
設定AVDictionary的時候會用到av_dict_set()。
下面看看把命令
- ffplay -rtsp_transport tcp -max_delay 5000000 rtsp://mms.cnr.cn/cnr003?MzE5MTg0IzEjIzI5NjgwOQ==
轉化為代碼實現的方式:
- AVFormatContext *pFormatCtx;
- pFormatCtx = avformat_alloc_context();
- ...代碼略
- AVDictionary *avdic=NULL;
- char option_key[]="rtsp_transport";
- char option_value[]="tcp";
- av_dict_set(&avdic,option_key,option_value,0);
- char option_key2[]="max_delay";
- char option_value2[]="5000000";
- av_dict_set(&avdic,option_key2,option_value2,0);
- char url[]="rtsp://mms.cnr.cn/cnr003?MzE5MTg0IzEjIzI5NjgwOQ==";
-
- avformat_open_input(&pFormatCtx,url,NULL,&avdic);
FFMPEG類庫開啟流媒體的方法(傳參數)