ffmpeg用avformat_open_input()解析網絡流時,默認是阻塞的。
當遇到解析錯誤的網絡流時,會導致該函數長時間不返回。
為此可以設置ffmpeg的-stimeout 的參數,要注意 -stimeout的單位是us 微妙。
用法就是設置在解析的 url 之前 (這里設置超時為5秒)即:
“ffmpeg -stimeout 5000000 -i rtsp://admin:admin@192.168.7.102:554/h264...........”
或者:
“ffmpeg -stimeout 5000000 -rtsp_transport tcp -i rtsp://admin:12345@172.16.7.166:554/h264.....”
備注:-stimeout 設置在你要解析的url之后是沒有作用的。
=============================================
從網絡上搜索到的有關資料:
一:
“去看ffmpeg的tcp.c的源代碼(會阻塞的網絡地址基本都是tcp協議),搜索上面兩個關鍵字,就明白是如何退出了。我之前的文章只說了open的時候阻塞,其實網絡環境復雜,有可能在read或write時候斷網或阻塞異常。但根基卻是在tcp.c這個文件里。把interrupt_callback和timeout設置好了,就可以解決這些問題。”
二:
“ffmpeg的avformat_open_input()默認是阻塞的,用戶可以通過設置“ic->flags |= AVFMT_FLAG_NONBLOCK;”設置成非阻塞(通常是不推薦的);或者是設置timeout設置超時時間;或者是設置interrupt_callback定義返回機制。
附一段代碼參考下吧。
ic = avformat_alloc_context();
if(ic == NULL){
ERR("error avformat_alloc_context \n");
return -1;
}
ic->interrupt_callback.callback = tvie_decode_interrupt_cb;
ic->interrupt_callback.opaque = handle;
//ic->flags |= AVFMT_FLAG_NONBLOCK;
if(strncmp(handle->params.path, "rtmp:", sizeof("rtmp:")) == 0){
av_dict_set(&opts, "timeout", "6", 0); // in secs
}
else if(strncmp(handle->params.path, "http:", sizeof("http:")) == 0){
av_dict_set(&opts, "timeout", "6000", 0); // in ms
}
err = avformat_open_input(&ic, handle->params.path, NULL, &opts);
”