GStreamer推流MP4至VLC失败求助:无法识别SDP格式
嘿,看你的情况,GStreamer自己的客户端能正常接收播放,但VLC加载SDP就报错,咱们一步步来搞定这个问题:
1. 先揪出SDP文件的核心问题
你的SDP里写的a=rtpmap:96 H264-ES/90000是关键错误!GStreamer的rtph264pay处理MP4里的H264时,默认发送的是AVC封装的流(也就是带SPS/PPS头的格式,和MP4原生编码一致),但H264-ES是 elementary stream(裸流),和当前推流格式完全不匹配,VLC自然识别不了。
修改你的SDP文件为标准格式,还要补充SPS和PPS的信息(VLC必须靠这些初始化解码器):
v=0 m=video 5010 RTP/AVP 96 c=IN IP4 127.0.0.1 a=rtpmap:96 H264/90000 a=fmtp:96 packetization-mode=1; sprop-parameter-sets=这里填SPS的base64编码,这里填PPS的base64编码;
怎么获取SPS/PPS的base64编码?
用ffprobe命令就能快速拿到:
ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_data sample_mp4.mp4
输出里的codec_data是SPS+PPS的十六进制串,比如6742001E96560A01E10080881620000003004000000C03C880A070,你需要把它按00000001分隔成SPS和PPS两部分,分别转成base64后填到SDP里。
2. 优化服务端推流命令(更稳定)
你的原命令里video/x-h264的caps是多余的,加上qtdemux和config-interval=1会让推流更可靠:
gst-launch-1.0.exe -v filesrc location=sample_mp4.mp4 ! qtdemux ! h264parse ! rtph264pay config-interval=1 ! udpsink host=127.0.0.1 port=5010
qtdemux是专门解MP4封装的元件,比直接用filesrc接h264parse兼容性更好;config-interval=1让rtph264pay每隔1秒重发一次SPS/PPS,VLC就算中途加入也能快速初始化解码器。
3. 绕开SDP直接用VLC打开UDP流
如果不想折腾SDP,直接在VLC里输入网络地址:udp://@127.0.0.1:5010
然后在「媒体」→「打开网络串流」的选项里,手动设置编码格式为H264,或者让VLC自动检测(不过自动检测可能会慢一点)。
4. 验证推流是否正常
既然GStreamer客户端能播放,说明流本身没问题,但可以用Wireshark抓UDP 5010端口的包,看看RTP包里有没有NALU类型为7(SPS)或8(PPS)的包——如果有,说明服务端已经在发送关键初始化信息,问题就只剩VLC的配置环节。
最后总结
最关键的就是把SDP里的H264-ES改成标准的H264/90000,再补上SPS/PPS的base64信息,配合优化后的推流命令,VLC应该就能正常播放了。
内容的提问来源于stack exchange,提问作者Manish

