Gstreamer python 推流 rtmp 测试

#!/usr/bin/env python3

import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst

#推流测试

RTMP = "rtmp://"
class RtmpPush(object):

    def __init__(self):
        # initialize GStreamer
        Gst.init(None)

        # create the elements
        self.video_source = Gst.ElementFactory.make("videotestsrc", "source_v")
        self.audio_source = Gst.ElementFactory.make("audiotestsrc", "source_a")
        self.audio_queue = Gst.ElementFactory.make("queue", "queue_a")
        self.audio_conv = Gst.ElementFactory.make("audioconvert", "conv_a")
        self.audio_encode = Gst.ElementFactory.make("avenc_aac", "encode_a")
        
        self.video_queue = Gst.ElementFactory.make("queue", "queue_v")
        self.video_conv = Gst.ElementFactory.make("videoconvert", "conv_v")
        self.video_encode = Gst.ElementFactory.make("x264enc", "encode_v")
        self.mux = Gst.ElementFactory.make("flvmux", "mux")
        #self.outsink = Gst.ElementFactory.make("filesink", "outsink")
        self.outsink = Gst.ElementFactory.make("rtmp2sink", "outsink")

        # create empty pipeline
        self.pipeline = Gst.Pipeline.new("test-pipeline")

        if (not self.video_source or not self.audio_source ):
            print("ERROR: Could not create av source elements")
            sys.exit(1)

        if (not self.pipeline   or not self.mux or not self.outsink
                or not self.audio_queue or not self.audio_conv or not self.audio_encode 
                or not self.video_queue or not self.video_conv or not self.video_encode):
            print("ERROR: Could not create all elements")
            sys.exit(1)
            
        # build the pipeline. we are NOT linking the source at this point.
        # will do it later
        self.pipeline.add(self.video_source)
        self.pipeline.add(self.audio_source)
        self.pipeline.add(self.audio_queue)
        self.pipeline.add(self.audio_conv)
        self.pipeline.add(self.audio_encode)
        self.pipeline.add(self.video_queue)
        self.pipeline.add(self.video_conv)
        self.pipeline.add(self.video_encode)
        self.pipeline.add(self.mux)
        self.pipeline.add(self.outsink)

        if not self.audio_source.link(self.audio_queue):
            print("ERROR: Could not link 'audio_source' to 'audio_queue'")
            sys.exit(1)
            
        if not self.audio_queue.link(self.audio_conv):
            print("ERROR: Could not link 'audio_queue' to 'audio_conv'")
            sys.exit(1)
            
        if not self.audio_conv.link(self.audio_encode):
            print("ERROR: Could not audio_queue 'audio_conv' to 'audio_encode'")
            sys.exit(1)     
               
        if not self.audio_encode.link(self.mux):
            print("ERROR: Could not link 'audio_encode' to 'mux'")
            sys.exit(1)

        if not self.video_source.link(self.video_queue):
            print("ERROR: Could not link 'video_source' to 'video_queue'")
            sys.exit(1)

        if not self.video_queue.link(self.video_encode):
            print("ERROR: Could not link 'video_queue' to 'video_decode'")
            sys.exit(1)

        if not self.video_encode.link(self.mux):
            print("ERROR: Could not link 'video_queue' to 'video_decode'")
            sys.exit(1)    
            
        if not self.mux.link(self.outsink):
            print("ERROR: Could not link 'mux' to 'outsink'")
            sys.exit(1)

        # set the location
        self.outsink.set_property("location", RTMP)

        # start playing
        ret = self.pipeline.set_state(Gst.State.PLAYING)
        if ret == Gst.StateChangeReturn.FAILURE:
            print("ERROR: Unable to set the pipeline to the playing state")
            sys.exit(1)

        # listen to the bus
        bus = self.pipeline.get_bus()
        terminate = False
        while True:
            msg = bus.timed_pop_filtered(
                Gst.CLOCK_TIME_NONE,
                Gst.MessageType.STATE_CHANGED | Gst.MessageType.EOS | Gst.MessageType.ERROR)
            if not msg:
                continue

            t = msg.type
            if t == Gst.MessageType.ERROR:
                err, dbg = msg.parse_error()
                print("ERROR:", msg.src.get_name(), " ", err.message)
                if dbg:
                    print("debugging info:", dbg)
                terminate = True
            elif t == Gst.MessageType.EOS:
                print("End-Of-Stream reached")
                terminate = True
            elif t == Gst.MessageType.STATE_CHANGED:
                # we are only interested in STATE_CHANGED messages from
                # the pipeline
                if msg.src == self.pipeline:
                    old_state, new_state, pending_state = msg.parse_state_changed()
                    print("Pipeline state changed from {0:s} to {1:s}".format(
                        Gst.Element.state_get_name(old_state),
                        Gst.Element.state_get_name(new_state)))
            else:
                # should not get here
                print("ERROR: Unexpected message received")
                break

            if terminate:
                break

        self.pipeline.set_state(Gst.State.NULL)

if __name__ == '__main__':
    p = RtmpPush()

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用Python调用Gstreamer进行推流,需要安装Python Gstreamer绑定库。可以使用以下命令在Linux中安装: ``` sudo apt-get install python-gst-1.0 ``` 接下来,可以使用以下Python代码来推送视频流: ```python import gi gi.require_version('Gst', '1.0') from gi.repository import GObject, Gst GObject.threads_init() Gst.init(None) pipeline = Gst.Pipeline() # 创建源 source = Gst.ElementFactory.make("v4l2src", "source") source.set_property("device", "/dev/video0") # 创建编码器 encoder = Gst.ElementFactory.make("x264enc", "encoder") encoder.set_property("speed-preset", "ultrafast") # 创建PayLoad pay = Gst.ElementFactory.make("rtph264pay", "pay") # 创建UDPSink udpsink = Gst.ElementFactory.make("udpsink", "udpsink") udpsink.set_property("host", "127.0.0.1") udpsink.set_property("port", 5000) # 添加到pipeline中 pipeline.add(source) pipeline.add(encoder) pipeline.add(pay) pipeline.add(udpsink) # 连接元素 source.link(encoder) encoder.link(pay) pay.link(udpsink) # 启动流 pipeline.set_state(Gst.State.PLAYING) # 等待流 bus = pipeline.get_bus() msg = bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS) if msg: if msg.type == Gst.MessageType.ERROR: err, debug = msg.parse_error() print("Error received from element %s: %s" % (msg.src.get_name(), err)) print("Debugging information: %s" % debug) elif msg.type == Gst.MessageType.EOS: print("End-Of-Stream reached.") else: print("Unexpected message received.") # 停止流 pipeline.set_state(Gst.State.NULL) ``` 这个代码段将从/dev/video0设备中获取视频流,并使用x264编码器进行编码,然后将其通过UDP发送到127.0.0.1:5000。可以根据需要更改设备和网络设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值