| #! /usr/bin/env python |
| |
| import gi |
| import sys |
| gi.require_version('Gst', '1.0') |
| from gi.repository import GObject, Gst |
| |
| # |
| # A simple RTP receiver |
| # |
| # receives alaw encoded RTP audio on port 5002, RTCP is received on port 5003. |
| # the receiver RTCP reports are sent to port 5007 |
| # |
| # .-------. .----------. .---------. .-------. .--------. |
| # RTP |udpsrc | | rtpbin | |pcmadepay| |alawdec| |alsasink| |
| # port=5002 | src->recv_rtp recv_rtp->sink src->sink src->sink | |
| # '-------' | | '---------' '-------' '--------' |
| # | | |
| # | | .-------. |
| # | | |udpsink| RTCP |
| # | send_rtcp->sink | port=5007 |
| # .-------. | | '-------' sync=false |
| # RTCP |udpsrc | | | async=false |
| # port=5003 | src->recv_rtcp | |
| # '-------' '----------' |
| |
| AUDIO_CAPS = 'application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)PCMA' |
| AUDIO_DEPAY = 'rtppcmadepay' |
| AUDIO_DEC = 'alawdec' |
| AUDIO_SINK = 'autoaudiosink' |
| |
| DEST = '127.0.0.1' |
| |
| RTP_RECV_PORT = 5002 |
| RTCP_RECV_PORT = 5003 |
| RTCP_SEND_PORT = 5007 |
| |
| GObject.threads_init() |
| Gst.init(sys.argv) |
| |
| #gst-launch -v rtpbin name=rtpbin \ |
| # udpsrc caps=$AUDIO_CAPS port=$RTP_RECV_PORT ! rtpbin.recv_rtp_sink_0 \ |
| # rtpbin. ! rtppcmadepay ! alawdec ! audioconvert ! audioresample ! autoaudiosink \ |
| # udpsrc port=$RTCP_RECV_PORT ! rtpbin.recv_rtcp_sink_0 \ |
| # rtpbin.send_rtcp_src_0 ! udpsink port=$RTCP_SEND_PORT host=$DEST sync=false async=false |
| |
| def pad_added_cb(rtpbin, new_pad, depay): |
| sinkpad = Gst.Element.get_static_pad(depay, 'sink') |
| lres = Gst.Pad.link(new_pad, sinkpad) |
| |
| # the pipeline to hold eveything |
| pipeline = Gst.Pipeline('rtp_client') |
| |
| # the udp src and source we will use for RTP and RTCP |
| rtpsrc = Gst.ElementFactory.make('udpsrc', 'rtpsrc') |
| rtpsrc.set_property('port', RTP_RECV_PORT) |
| |
| # we need to set caps on the udpsrc for the RTP data |
| caps = Gst.caps_from_string(AUDIO_CAPS) |
| rtpsrc.set_property('caps', caps) |
| |
| rtcpsrc = Gst.ElementFactory.make('udpsrc', 'rtcpsrc') |
| rtcpsrc.set_property('port', RTCP_RECV_PORT) |
| |
| rtcpsink = Gst.ElementFactory.make('udpsink', 'rtcpsink') |
| rtcpsink.set_property('port', RTCP_SEND_PORT) |
| rtcpsink.set_property('host', DEST) |
| |
| # no need for synchronisation or preroll on the RTCP sink |
| rtcpsink.set_property('async', False) |
| rtcpsink.set_property('sync', False) |
| |
| pipeline.add(rtpsrc, rtcpsrc, rtcpsink) |
| |
| # the depayloading and decoding |
| audiodepay = Gst.ElementFactory.make(AUDIO_DEPAY, 'audiodepay') |
| audiodec = Gst.ElementFactory.make(AUDIO_DEC, 'audiodec') |
| |
| # the audio playback and format conversion |
| audioconv = Gst.ElementFactory.make('audioconvert', 'audioconv') |
| audiores = Gst.ElementFactory.make('audioresample', 'audiores') |
| audiosink = Gst.ElementFactory.make(AUDIO_SINK, 'audiosink') |
| |
| # add depayloading and playback to the pipeline and link |
| pipeline.add(audiodepay, audiodec, audioconv, audiores, audiosink) |
| |
| audiodepay.link(audiodec) |
| audiodec.link(audioconv) |
| audioconv.link(audiores) |
| audiores.link(audiosink) |
| |
| # the rtpbin element |
| rtpbin = Gst.ElementFactory.make('rtpbin', 'rtpbin') |
| |
| pipeline.add(rtpbin) |
| |
| # now link all to the rtpbin, start by getting an RTP sinkpad for session 0 |
| srcpad = Gst.Element.get_static_pad(rtpsrc, 'src') |
| sinkpad = Gst.Element.get_request_pad(rtpbin, 'recv_rtp_sink_0') |
| lres = Gst.Pad.link(srcpad, sinkpad) |
| |
| # get an RTCP sinkpad in session 0 |
| srcpad = Gst.Element.get_static_pad(rtcpsrc, 'src') |
| sinkpad = Gst.Element.get_request_pad(rtpbin, 'recv_rtcp_sink_0') |
| lres = Gst.Pad.link(srcpad, sinkpad) |
| |
| # get an RTCP srcpad for sending RTCP back to the sender |
| srcpad = Gst.Element.get_request_pad(rtpbin, 'send_rtcp_src_0') |
| sinkpad = Gst.Element.get_static_pad(rtcpsink, 'sink') |
| lres = Gst.Pad.link(srcpad, sinkpad) |
| |
| rtpbin.connect('pad-added', pad_added_cb, audiodepay) |
| |
| Gst.Element.set_state(pipeline, Gst.State.PLAYING) |
| |
| mainloop = GObject.MainLoop() |
| mainloop.run() |
| |
| Gst.Element.set_state(pipeline, Gst.State.NULL) |
| |