python 播放视频流_python gstreamer播放多个视频流

这是一个Python项目,旨在实现一个艺术项目,通过HTTP服务器和gstreamer播放视频。目前,程序能切换播放不同视频,但目标是使同一窗口能同时播放多个视频流。代码中定义了VideoDictionary类来管理视频数据库,VideoPlayer类用于播放视频,而HttpHandler类处理HTTP请求以切换视频。然而,目前playbin2元素仅支持单个URI播放,因此需要一个解决方案来同时播放多个视频流。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我正在参与一个包括远程播放视频的艺术项目.我已经实现了一个带有HTTP服务器和gstreamer视频播放器的简单

python应用程序.我能够捕获一个http请求并更改当前正在播放的视频,但我想在同一窗口中添加新视频并继续同时播放两个视频.

我用playbin2来播放视频,但我认为它当时只能玩一个uri.我试图找到可以同时播放多个视频的其他解决方案,但没有用…

任何人都可以发布一个同时播放多个流的简单示例,或者给我一些指向文档或其他资源的指针?

提前致谢!!

PS.这是我写的代码:VideoPlayer类初始化流,playCurrent函数切换当前播放的视频 – 我希望该功能只是将新视频添加到流中.

#!/usr/bin/python

import threading

import time

import BaseHTTPServer

from BaseHTTPServer import HTTPServer

from urlparse import urlparse, parse_qs

from os import path

import gst

import gtk

HOST_NAME = 'localhost' # !!!REMEMBER TO CHANGE THIS!!!

PORT_NUMBER = 9000 # Maybe set this to 9000.

#################################################################

# VIDEO DICTIONARY

# Manages the video database

#################################################################

# VideoDictionary class

#################################################################

# This class allows to access the video database

# used by the video player - for best performance, it's a native

# python dictionary

class VideoDictionary():

# declaring filenames

filename = path.join(path.dirname(path.abspath(__file__)), 'large.mp4')

filename_02 = path.join(path.dirname(path.abspath(__file__)), '01.avi')

# declaring uris

uri = 'file://' + filename

uri_02 = 'file://' + filename_02

# combining it all into a dictionary

videoDict = {}

videoDict["01"] = uri

videoDict["02"] = uri_02

# setting the current video

currentVideo = "01"

#################################################################

# VIDEO DICTIONARY END

#################################################################

#################################################################

# VIDEO PLAYER

# Manages all the video playing

#################################################################

# VideoPlayer class

#################################################################

# This class initializes the GST pipe context and it

# handles different events related to video stream playing

class VideoPlayer(object, VideoDictionary):

VideoDictionary = ""

def __init__(self, VideoDictionary):

self.VideoDictionary = VideoDictionary

self.window = gtk.Window()

self.window.connect('destroy', self.quit)

self.window.set_default_size(1024, 768)

self.drawingarea = gtk.DrawingArea()

self.window.add(self.drawingarea)

# Create GStreamer pipeline

self.pipeline = gst.Pipeline()

# Create bus to get events from GStreamer pipeline

self.bus = self.pipeline.get_bus()

# This is needed to make the video output in our DrawingArea:

self.bus.enable_sync_message_emission()

self.bus.connect('sync-message::element', self.on_sync_message)

# Create GStreamer elements

self.playbin = gst.element_factory_make('playbin2')

# Add playbin2 to the pipeline

self.pipeline.add(self.playbin)

self.window.show_all()

self.xid = self.drawingarea.window.xid

print('DEBUG INFO: player initialization finished')

def playCurrent(self):

print('DEBUG INFO: getting running video ')

print(self.VideoDictionary.currentVideo)

self.pipeline.set_state(gst.STATE_READY)

self.playbin.set_property('uri', self.VideoDictionary.videoDict[self.VideoDictionary.currentVideo])

self.pipeline.set_state(gst.STATE_PLAYING)

def quit(self, window):

print('DEBUG INFO: quitting player')

self.pipeline.set_state(gst.STATE_NULL)

gtk.main_quit()

def on_sync_message(self, bus, msg):

if msg.structure.get_name() == 'prepare-xwindow-id':

msg.src.set_property('force-aspect-ratio', True)

msg.src.set_xwindow_id(self.xid)

def on_eos(self, bus, msg):

print('DEBUG INFO: EOS detected')

print('on_eos(): seeking to start of video')

self.pipeline.seek_simple(

gst.FORMAT_TIME,

gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_KEY_UNIT,

0L

)

def on_error(self, bus, msg):

print('DEBUG INFO: error detected')

print('on_error():', msg.parse_error())

#################################################################

# VIDEO PLAYER END

#################################################################

#################################################################

# HTTP SERVER

# implements the http listener in a separate thread

# the listener plays the videos depending on the

# received parameters in the GET request

#################################################################

# HttpHandler class

#################################################################

# uses global variables to operate videos

class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler):

def do_GET(self):

# initialize the currently played video

global VideoDictionary

print('DEBUG INFO: GET running playCurrent')

if VideoDictionary.currentVideo == "01":

VideoDictionary.currentVideo = "02"

else:

VideoDictionary.currentVideo = "01"

# play the video we have just set

global player

player.playCurrent()

# HttpThread class

#################################################################

# initializes the http listener in a separate thread

class HttpThread (threading.Thread):

def __init__(self):

threading.Thread.__init__(self)

def run(self):

gtk.gdk.threads_enter()

server_class = BaseHTTPServer.HTTPServer

httpd = server_class((HOST_NAME, PORT_NUMBER), HttpHandler)

print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)

try:

httpd.serve_forever()

except KeyboardInterrupt:

pass

httpd.server_close()

print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)

gtk.gdk.threads_leave()

return

#################################################################

# HTTP SERVER END

#################################################################

if __name__ == '__main__':

VideoDictionary = VideoDictionary()

player = VideoPlayer(VideoDictionary)

gtk.gdk.threads_init()

thread2 = HttpThread()

thread2.run()

gtk.gdk.threads_enter()

gtk.main()

gtk.gdk.threads_leave()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值