最近使用ffmpeg來做一個rtsp的客戶端,這過程也遇到不少問題,不過相應都比較好,一路走下來.不過到項目結尾時,且遇到一個比較糾結的問題.那就是客戶端在使用的過程中,把rtsp服務器的網斷了.這時客戶端會卡死.無法操作.嘗試了各種線程的處理,還不行.最后追蹤代碼來到av_read_frame這個函數.問題就出現在它身上了.當服務器斷網后,這個函數會一直沒有返回,且整個線程也停在那里了.
難道就沒有連接超時的判斷.
原來要想實現連接超時的判斷,得用回調函數.網上有兩種設置方法.不過我這邊只有這種是有效的.
直接上代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
AVCodec *pCodec;
// Register all formats and codecs
av_register_all();
avcodec_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
pFormatCtx->interrupt_callback.callback = interrupt_cb;--------注冊回調函數
pFormatCtx->interrupt_callback.opaque = pFormatCtx;
AVDictionary* options = NULL;
av_dict_set(&options,
"rtsp_transport"
,
"tcp"
, 0);
// ret = avformat_open_input(&pFormatCtx, cFullPath, 0, &options);
//avformat_network_init();
// Open video file
if
(avformat_open_input(&pFormatCtx, [url cStringUsingEncoding:NSASCIIStringEncoding], 0, &options) != 0) {
av_log(NULL, AV_LOG_ERROR,
"Couldn't open file\n"
);
goto
initError;
}
|
再另外定義一下函數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
static
int
interrupt_cb(
void
*ctx)
{
// do something
NSLog(@
"%d"
,time_out);
time_out++;
if
(time_out > 40) {
NSLog(@
"------%d"
, firsttimeplay);
time_out=0;
if
(firsttimeplay) {
firsttimeplay=0;
NSLog(@
"++++++++"
);
return
1;
//這個就是超時的返回
}
}
return
0;
}
|
這樣,回調函數就會一直在后台運行着,然后就可以在上面加一些邏輯讓超時返回1了,返回1,系統就自動結束,把主動權交回給主線程,這樣用戶就可以再操作ui了,卡死的問題ok