我正在参加一个艺术项目,其中包括远程播放视频。我已经用HTTP服务器和gstreamer视频播放器实现了一个简单的python应用程序。我可以捕捉到一个http请求并更改当前正在播放的视频,但我只想在同一个窗口中添加新的视频,并继续同时播放两个视频。在
我用playbin2来播放视频,但我认为它一次只能播放一个uri。我试图找到其他解决方案,可以同时播放多个视频,但没有用。。。在
有谁能发一个同时播放多个流的简单例子,或者给我一些文档或其他资源的提示??在
提前谢谢!!在
这是我写的代码: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()
下面是一个同时播放多个视频流的简单代码示例。在
它与Python2和3一起工作,并且使用标准的PythonGUI(Tk)和GStreamer1.0。因此它应该是可移植的,但我只在Ubuntu16.04下测试过。在
(ffmpeg fork libav在ubuntu14.04下产生了问题,而在16.04下似乎可以解决。注意,除了gstreamer1.0-plugins-*,还需要gstreamer1.0-libav包
代码被配置为在一列中创建八个帧,并将一个Gstreamer播放器与每个帧相关联。您需要提供一个(最多八个)有效本地视频文件名的列表,作为保存该文件的参数(例如多视频.py),如下所示:
声道简单地混合在一起。你可能想改变这个。在
我的解决方案不涉及远程播放,但您已经解决了这一部分。在
我以前在video files in tkinter上的另一个问题的答案中发布了相同的代码,这个问题并没有要求并发流。因此在这里更合适。在
^{pr2}$如果您将句柄保存到播放器(比如在player_list中),您可以稍后更改它在其中一个播放器中播放的uri,如下所示:
相关问题 更多 >
编程相关推荐