【问题标题】:Save rtsp stream into avi file with gstreamer使用 gstreamer 将 rtsp 流保存到 avi 文件中
【发布时间】:2016-10-12 16:06:59
【问题描述】:

我有一个视频服务器,它通过 rtsp 为我提供视频和音频流。我可以使用带有命令的 gstreamer 工具 gst-launch 看到它:

gst-launch-1.0 uridecodebin uri=rtsp://path/to/source ! autovideosink

现在我需要将该视频流存储到文件中,以便随后在任何流行的视频播放器(VLC、Windows Media Player 等)中播放。

我尝试简单地将autovideosink 替换为filesink location=file.avi 并添加-e 选项,就像answer 中推荐的那样。文件已创建,但我认为它的视频格式不正确(VLC 无法播放)。

我还尝试了最近引用的答案中的命令:

gst-launch-1.0 -e rtspsrc location=rtsp://path/to/source ! decodebin !
x264enc ! mp4mux ! filesink location=file.avi

它给了我错误:

ERROR: from element /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc0: Internal data flow error.
Additional debug info:
gstbasesrc.c(2865): gst_base_src_loop (): /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc0:
streaming task paused, reason not-linked (-1)

原因是(我认为)x264enc ! mp4mux 用于 H.264 编解码器,但my device 仅适用于 MPEG4 part2 模式(MP4V-ES,即 H.263)。所以我需要替换管道中的一些元素以满足我的设备的能力。但是通过查看gstreamer plugins list,我找不到任何适合 MP4V-ES (H.263) 的东西。

现在我的问题是:如何修改 gst-launch 命令以将视频从我稍微旧的设备保存到文件中以进一步播放?

详细命令的完整日志:

gst-launch-1.0 -e -v rtspsrc location=rtsp://192.168.101.44/moxa-cgi/multicaststream_ch1_stream1 ! decodebin ! avenc_mpeg4 ! mp4mux ! filesink location=file.mp4

Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Progress: (open) Opening Stream
Progress: (connect) Connecting to rtsp://192.168.101.44/moxa-cgi/multicaststream_ch1_stream1
Progress: (open) Retrieving server options
Progress: (open) Retrieving media info
Progress: (request) SETUP stream 0
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager: latency = 2000
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager: ntp-sync = false
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager: use-pipeline-clock = false
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager: drop-on-latency = false
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager: buffer-mode = Slave receiver to sender clock
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc0: timeout = 5000000000

(gst-launch-1.0:9068): GStreamer-WARNING **: gstpad.c:4555:store_sticky_event:<udpsrc1:src> Sticky event misordering, got 'caps' before 'stream-start'
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc1.GstPad:src: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc1.GstPad:src: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc1: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSink:udpsink0: ttl = 128
Progress: (request) SETUP stream 1
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc2: timeout = 5000000000
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc3.GstPad:src: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc3: caps = application/x-rtcp

(gst-launch-1.0:9068): GStreamer-WARNING **: gstpad.c:4555:store_sticky_event:<udpsrc3:src> Sticky event misordering, got 'caps' before 'stream-start'
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc3.GstPad:src: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:recv_rtcp_sink_1.GstProxyPad:proxypad5: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager/GstRtpSession:rtpsession1.GstPad:sync_src: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager/GstRtpSsrcDemux:rtpssrcdemux1.GstPad:rtcp_sink: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager/GstRtpSession:rtpsession1.GstPad:recv_rtcp_sink: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:recv_rtcp_sink_1: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSink:udpsink2: ttl = 128
Progress: (open) Opened Stream
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Progress: (request) Sending PLAY request
Progress: (request) Sending PLAY request
Progress: (request) Sent PLAY request
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc0: timeout = 0
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc2: timeout = 0
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager/GstRtpSession:rtpsession0.GstPad:send_rtcp_src: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:send_rtcp_src_0: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSink:udpsink1.GstPad:sink: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:send_rtcp_src_0.GstProxyPad:proxypad3: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager/GstRtpSession:rtpsession1.GstPad:send_rtcp_src: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:send_rtcp_src_1: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSink:udpsink3.GstPad:sink: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:send_rtcp_src_1.GstProxyPad:proxypad6: caps = application/x-rtcp
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:recv_rtp_src_1_109102090_0: caps = application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU, encoding-params=(string)1, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)2318609, seqnum-base=(uint)26256, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0.GstGhostPad:recv_rtp_src_1_109102090_0: caps = application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU, encoding-params=(string)1, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)2318609, seqnum-base=(uint)26256, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstDecodeBin:decodebin0.GstGhostPad:sink.GstProxyPad:proxypad0: caps = application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU, encoding-params=(string)1, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)2318609, seqnum-base=(uint)26256, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind.GstPad:src: caps = application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU, encoding-params=(string)1, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)2318609, seqnum-base=(uint)26256, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind.GstPad:sink: caps = application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU, encoding-params=(string)1, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)2318609, seqnum-base=(uint)26256, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstDecodeBin:decodebin0.GstGhostPad:sink: caps = application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU, encoding-params=(string)1, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)2318609, seqnum-base=(uint)26256, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0.GstGhostPad:recv_rtp_src_1_109102090_0.GstProxyPad:proxypad8: caps = application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU, encoding-params=(string)1, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)2318609, seqnum-base=(uint)26256, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:recv_rtp_src_1_109102090_0.GstProxyPad:proxypad7: caps = application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU, encoding-params=(string)1, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)2318609, seqnum-base=(uint)26256, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstRtpPcmuDepay:rtppcmudepay0.GstPad:src: caps = audio/x-mulaw, channels=(int)1, rate=(int)8000
/GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMuLawDec:mulawdec0.GstPad:sink: caps = audio/x-mulaw, channels=(int)1, rate=(int)8000
/GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstRtpPcmuDepay:rtppcmudepay0.GstPad:sink: caps = application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU, encoding-params=(string)1, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)2318609, seqnum-base=(uint)26256, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMuLawDec:mulawdec0.GstPad:src: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)8000, channels=(int)1
/GstPipeline:pipeline0/GstDecodeBin:decodebin0.GstDecodePad:src_0.GstProxyPad:proxypad9: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)8000, channels=(int)1
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:recv_rtp_src_0_2387976809_96: caps = application/x-rtp, media=(string)video, payload=(int)96, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)3, config=(string)000001B003000001B50900000100000001200088400668582120A31F, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)26503772, seqnum-base=(uint)15792, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0.GstGhostPad:recv_rtp_src_0_2387976809_96: caps = application/x-rtp, media=(string)video, payload=(int)96, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)3, config=(string)000001B003000001B50900000100000001200088400668582120A31F, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)26503772, seqnum-base=(uint)15792, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0.GstGhostPad:recv_rtp_src_0_2387976809_96.GstProxyPad:proxypad11: caps = application/x-rtp, media=(string)video, payload=(int)96, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)3, config=(string)000001B003000001B50900000100000001200088400668582120A31F, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)26503772, seqnum-base=(uint)15792, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
/GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstRtpBin:manager.GstGhostPad:recv_rtp_src_0_2387976809_96.GstProxyPad:proxypad10: caps = application/x-rtp, media=(string)video, payload=(int)96, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)3, config=(string)000001B003000001B50900000100000001200088400668582120A31F, a-tool=(string)"MOXA\ 4CH\ Streamming\ Server\ V1.0", a-type=(string)broadcast, x-qt-text-nam=(string)"4CH\ Streaming", x-qt-text-inf=(string)/dev/at2042, clock-base=(uint)26503772, seqnum-base=(uint)15792, npt-start=(guint64)0, play-speed=(double)1, play-scale=(double)1
ERROR: from element /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc0: Internal data flow error.
Additional debug info:
gstbasesrc.c(2865): gst_base_src_loop (): /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0/GstUDPSrc:udpsrc0:
streaming task paused, reason not-linked (-1)
EOS on shutdown enabled -- waiting for EOS after Error
Waiting for EOS...

Ctrl+C在这里按下。

handling interrupt.
Interrupt: Stopping pipeline ...
Interrupt while waiting for EOS - stopping pipeline...
Execution ended after 0:00:12.942466327
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...

您还可以在this link 上查看“好”(保存到文件作品)和“坏”(发生错误)的差异。

【问题讨论】:

    标签: video save gstreamer rtsp mpeg-4


    【解决方案1】:

    您拥有的相机似乎正在生成 MPEG4 Type 2 流,您正试图将其封装在 mp4 容器中。因此 x264_enc 尝试将不起作用,因为流类型不兼容。其次,您不能像其他尝试那样使用具有 AVI 文件类型的 MP4 多路复用器,尽管您可以尝试使用 avimux。分解从上限协商中运行良好的流,我们可以将其构造为:

    gst-launch-1.0 -v -e rtspsrc location=rtsp://path/to/source ! rtpmp4vdepay ! mpeg4videoparse ! mp4mux ! filesink location=test.mp4
    

    rtpmp4vdepaympeg4videoparsemp4mux 通常包含在 decodebin 元素本身中,但只是为了让我们的生活更轻松并看看出了什么问题,将这些元素放在一起总是好的.它使您可以控制正在构建的管道,而不是将其留给上限协商来确定我不推荐用于 IP 摄像机的管道。

    我还建议尝试管道(但避免使用 IP 摄像机的 decodebin):

    gst-launch-1.0 -e rtspsrc location=rtsp://path/to/source ! decodebin ! avenc_mpeg4 ! mp4mux ! filesink location=file.mp4
    

    话虽如此,this link 在原始问题中发布,但在尝试播放流时显示了不同的协商格式。例如,“工作”的那个尝试按照上面工作管道中提到的顺序添加元素,而不工作的那个尝试通过添加 rtppcmudepay 元素来协商不同的格式。我认为这将取决于相机,它使 decodebin 认为有不止一种类型的流可用,并且 decodebin 旨在通过添加不需要的附加元素来解决这些上限。

    【讨论】:

    • 最后一行的命令与我的答案相同(文件扩展名除外)。它仅适用于约 10% 的情况。 IE。 decodebin ! avenc_mpeg4rtpmp4vdepay ! mpeg4videoparse 链之间存在一些难以理解的区别。如果您知道,将其反映在答案中会很酷。
    • 已编辑更多信息 - 您能否将您的相机类型添加到原始问题中,也许对于面临类似问题的其他人。谢谢:)
    • 链接到我的视频服务器(不是相机)的 pdf 文档已经存在问题。 4 个通道中的每一个都包含视频+音频流。我不需要音频流(因为没有麦克风)。但我认为gst-play 也确实接收到音频流。不知道如何在没有真正的音频源的情况下检查它的存在。
    • 我之前用过MOXA设备,我想你可以登录设备的配置页面,关闭音频。
    • 这是旧设备,只能使用 MS IE6 进行配置。而且我根本找不到任何禁用音频流的选项。
    【解决方案2】:

    使用avenc_mpeg4 代替x264enc 对我有用。最后的命令是:

    gst-launch-1.0 -e rtspsrc location=rtsp://path/to/source ! decodebin ! avenc_mpeg4 ! mp4mux ! filesink location=file.avi

    它有效。但只有 1 次 ~10。其他 9 次我得到了与问题相同的错误:

    流式传输任务已暂停,原因未关联 (-1)

    我不知道它的真正原因是什么。但我认为这是设备功能。

    但是,命令如下:

    gst-play-1.0 rtsp://path/to/source

    工作稳定,即没有错误。

    【讨论】:

    • 在“未链接”消息之前,它应该说明哪个垫或哪个元素未链接,您也可以粘贴吗?
    • @SamerTufail 你可以看到它有问题。
    • 我试图将底部链接到顶部,所以我错过了,抱歉。您可以尝试使用“-v”和“-e”运行管道并共享输出吗?
    • @SamerTufail 日志已添加。
    • 你可以试试这个:gst-launch-1.0 -v -e rtspsrc location=rtsp://path/to/source ! rtpmp4vdepay ! mpeg4vparse ! mp4 多路复用器!文件接收器位置=file.avi
    猜你喜欢
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多