在 Gstreamer 中播放 iOS 8 中的管道时,进入后台并返回前台管道后不起作用:(?

In Gstreamer while playing the pipeline in iOS 8, and after entering background and returning foreground pipeline doesnt work :(?

-实际上我从 link,

下载了 gstreamer 的示例教程

http://cgit.freedesktop.org/~slomo/gst-sdk-tutorials/

git://people.freedesktop.org/~slomo/gst-sdk-tutorials

-现在是 运行 ipad 中的应用程序,应用程序开始播放。

提前致谢....iOS极客....

我最近尝试使用硬件 h264 解码,使用 Apple VideoToolBox API 通过 "vtdec" gstreamer 插件从 RaspberryPi 到 IOS8 进行实时流式传输。

我看了很多教程,即来自 braincorp (https://github.com/braincorp/gstreamer_ios_tutorial)

和 塞巴斯蒂安德罗格: http://cgit.freedesktop.org/~slomo/gst-sdk-tutorials/

我得到了后一个工作,修改了教程 3:

  • Server pipeline on RaspberryPi using pi Camera and Raspivid + gstreamer:
    raspivid -t 0 -w 1280 -h 720 -fps 25 -b 2500000 -p 0,0,640,480 -o - | gst-launch-0.10 -v fdsrc ! h264解析! rtph264pay 配置间隔=1 点=96 !支付宝! tcpserversink host=ServerIPRaspberryPi port=any_port_on_Rpi

  • client side pipeline one IOS 8 device:
    tcpclientsrc host=ServerIPRaspberryPi port=any_port_on_Rpi !国内生产总值支付! rtph264depay ! h264解析! vtdec! glimagesink

或与 glimagesink 相同 autovideosink.

此解决方案有效,可以同时使用多个客户端。我尝试让 udpsink 代替 tcpserversink 工作,但运气不好,到目前为止它从未奏效。

===重要===
此外,使用 gst_element_factory_make() + gst_bin_add_many (GST_BIN(pipeline), ...) 的工厂方式从未奏效。 相反,我使用了 pipeline = gst_parse_launch(...) 方法。

所以在我们的例子中,在 IOS 客户端:
管道 = gst_parse_launch("tcpclientsrc host=172.19.20.82 port=5000 ! gdpdepay ! rtph264depay ! h264parse ! vtdec ! autovideosink", &error);

可能的原因:有一个页面记录差异,以及如何从 gstreamer 0.101.0 移植代码: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-porting-1.0.html

我们注意到,在使用 "factory method" 时,根据我们是否使用 gstreamer 1.0[=78,管道中会缺少各种元素=] 或 0.1trph264depayavdec_h264 (用于其他平台即 linux 客户端)解码 h264 而不是 IOS 具体 vtdec).

我们几乎无法使用 Factory 方法将所有元素组合在一起,但我们使用 "gst_parse_launch()" 函数成功地解决了任何问题, 在 IOS 和 linux.

所以总而言之,虽然我们还没有测试并让 UDP 接收器工作,然后尝试使用 TCP 方式 tcpclientsrc 元素,让它工作,然后只有在它工作后,尝试找到 udp 的方式,如果你结束了,请告诉我们.

此致,希望这对你们中的许多人有所帮助。

罗曼小号

更新:让 UDP 工作。

经过进一步调查,我在 linux (PC x86) 上获得了 UDP h264 流式传输,但原理在 IOS 上应该是相同的(特别是 avdec_h264 (在 PC 上使用)必须替换为 vtdec)。

TCP 和 UDP 管道之间的主要区别:

服务器端:

  • IP:让我在 UDP 和 TCP 服务器端之间混淆的第一个元素:在 UDP 服务器 上,在 udpsink[=105= 上指定的 IP 地址]元素是客户端IP,即 gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! udpsink host=$CLIENTIP port=5000

而在TCP服务器端,IP是服务器端之一(tcpserversink上的主机参数)即 gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=$SERVERIP port=5000

  • 视频流payload/format:为了让客户端能够检测帧的格式和大小,TCP服务器端利用gdppay,一个 payloader 元素,在其管道中。在客户端相反的元素上,使用了一个de-payloader gdpdepay以便能够读取接收到的帧。 即

gst-launch-1.0 -v fdsrc ! h264解析! rtph264pay 配置间隔=1 点=96 ! gdppay ! tcpserversink 主机=$SERVERIP 端口=5000

UDP 服务器端 使用 gdpay 元素,它让客户端在其 udpsink 上使用 CAPS 见下文在客户端差异。

客户端

  • IP:UDP 客户端 不需要 需要任何指定的 IP。 虽然 TCP 客户端需要 服务器 IP (tcpclientsrc 上的主机参数),即 gst-launch-1.0 -v tcpclientsrc host=$SERVERIP port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false enable-last-buffer=false
  • 视频流payload/format:如前段所述,TCP服务器端使用payloader gdppay,而客户端使用de-payloader识别格式和帧的大小。

相反,UDP 客户端必须在其 udpsrc 元素上使用 caps 明确指定它,即 CAPS='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96'

gst-launch-1.0 -v udpsrc port=5000 caps=$CAPS ! rtph264depay ! avdec_h264!视频转换! autovideosink sync=false enable-last-buffer=false`

如何指定大写字母:它有点笨拙,但它有效: 运行 您的 UDP 服务器,带有详细选项 -vgst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! udpsink host=$CLIENTIP port=5000

您将获得以下日志:

Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:src: caps = video/x-h264, width=(int)1280, height=(int)720, parsed=(boolean)true, stream-format=(string)avc, alignment=(string)au, codec_data=(buffer)01640028ffe1000e27640028ac2b402802dd00f1226a01000428ee1f2c /GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0.GstPad:src: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)"J2QAKKwrQCgC3QDxImo\=\,KO4fLA\=\=", payload=(int)96, ssrc=(uint)3473549335, timestamp-offset=(uint)257034921, seqnum-offset=(uint)12956 /GstPipeline:pipeline0/GstUDPSink:udpsink0.GstPad:sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)"J2QAKKwrQCgC3QDxImo\=\,KO4fLA\=\=", payload=(int)96, ssrc=(uint)3473549335, timestamp-offset=(uint)257034921, seqnum-offset=(uint)12956 /GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0.GstPad:sink: caps = video/x-h264, width=(int)1280, height=(int)720, parsed=(boolean)true, stream-format=(string)avc, alignment=(string)au, codec_data=(buffer)01640028ffe1000e27640028ac2b402802dd00f1226a01000428ee1f2c /GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0: timestamp = 257034921 /GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0: seqnum = 12956 Pipeline is PREROLLED ... Setting pipeline to PLAYING ...

现在复制以 caps = application/x-rtp 开头的大写字母 这是指定 rtp 流格式的那个。据我所知,让 UDP 客户端识别 rtp 流内容然后初始化播放确实是强制性的。

为了总结并避免混淆,请在下面找到完整的命令行示例,使用带有 Raspberry pi 的 raspivid。如果你想尝试一下(在 linux 上)

UDP

  • 服务器:raspivid -t 0 -w 1280 -h 720 -fps 25 -b 2500000 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! udpsink host=$CLIENTIP port=5000
  • 客户: CAPS='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96' gst-launch-1.0 -v udpsrc port=5000 caps=$CAPS ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false enable-last-buffer=false

TCP

  • 服务器:raspivid -t 0 -w 1280 -h 720 -fps 25 -b 2500000 -o - | gst-launch-0.10 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=$SERVERIP port=5000

  • 客户:gst-launch-1.0 -v tcpclientsrc host=$SERVERIP port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false enable-last-buffer=false

注意:使用 cat 即可轻松将 Raspivid 替换为简单的 h264 文件,即 cat myfile.h264 | gst-launch...