先看错误,了解关键信息。其大意是说UDP超时,请用TCP重试。那按我们编码上的理解就是FFMpeg在读取RTSP的时采用了默认的UDP协议,在代码上我们需要将UDP转换成TCP协议来读取RTSP信息。
[rtsp @ 0x55995c61ccc0] UDP timeout, retrying with TCP
[rtsp @ 0x55995c61ccc0] method PAUSE failed: 455 Method Not Valid in This State
[rtsp @ 0x55995c61ccc0] Could not find codec parameters for stream 0 (Video: h264, none): unspecified size
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Input #0, rtsp, from 'rtsp://admin:123456@192.168.4.86:554/H264?ch=1&subtype=1':
Metadata:
title : RTSP Session/2.0
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264, none, 90k tbr, 90k tbn, 180k tbc
Output #0, flv, to 'rtmp://113.98.62.62:65528/live/test':
Stream #0:0: Video: h264, none, q=2-31
[flv @ 0x55995c65e280] dimensions not set
Segmentation fault
问题找到了,我们只要在打开流的时候,设置tcp转换参数就可以了。代码如下:
let mut opts: *mut AVDictionary = std::ptr::null_mut();
let rtsp_transport_key = CString::new("rtsp_transport").expect("to c str");
let rtsp_transport_value = CString::new("tcp").expect("to c str");
av_dict_set(&mut opts, rtsp_transport_key.as_ptr(), rtsp_transport_value.as_ptr(), 0);
avformat_open_input(&mut ifmt_ctx, input_path_cstr.as_ptr(), std::ptr::null_mut(), &mut opts);
改好再次测试推流,就不会出现之前的错误了。完整推流代码笔者已上传到gitee,在这里可以找到:https://gitee.com/dev-tang/ipcp