python gstreamer实现视频快进/快退/循环播放功能
Gstreamer到底是个啥?
GStreamer是一个基于pipeline的多媒体框架,基于GObject,以C语言写成。
应用GStreamer这个这个多媒体框架,你可以写出任意一种流媒体的应用来如:meidaplayer、音视频编辑器、VOIP、流媒体服务器、音视频编码等等。
关于视频快进/快退/循环播放的知识总结:
1.本地视频时长获取:
Gst.Pad.query_duration官方函数介绍:
defGst.Pad.query_duration(self,format): #pythonwrapperfor'gst_pad_query_duration' Queriesapadforthetotalstreamduration. Parameters: pad(Gst.Pad)–aGst.Padtoinvokethedurationqueryon. format(Gst.Format)–theGst.Formatrequested Returnsatuplemadeof: (gboolean)–TRUE(notintrospectable)ifthequerycouldbeperformed. duration(gint64)–TRUE(notintrospectable)ifthequerycouldbeperformed.
使用如下:
pipeline.query_duration(Gst.Format.TIME)[1]
其中pipeline为播放本地视频的管道,query_duration()函数返回一个元组,元组的形式为[Ture,duration:******],******为以ns为单位的视频时长。
2.视频播放当前位置获取:
Gst.Pad.query_position官方函数介绍:
defGst.Pad.query_position(self,format): #pythonwrapperfor'gst_pad_query_position' Queriesapadforthestreamposition. Parameters: pad(Gst.Pad)–aGst.Padtoinvokethepositionqueryon. format(Gst.Format)–theGst.Formatrequested Returnsatuplemadeof: (gboolean)–TRUE(notintrospectable)ifthequerycouldbeperformed. cur(gint64)–TRUE(notintrospectable)ifthequerycouldbeperformed.
使用方法与时长获取函数query_duration()相同。
3.播放跳转函数:
Gst.Element.seek_simple官方函数介绍:
defGst.Element.seek_simple(self,format,seek_flags,seek_pos): #pythonwrapperfor'gst_element_seek_simple' Parameters: element(Gst.Element)–aGst.Elementtoseekon format(Gst.Format)–aGst.Formattoexecutetheseekin,suchasGst.Format.TIME seek_flags(Gst.SeekFlags)–seekoptions;playbackapplicationswillusuallywanttouseGST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_KEY_UNIThere seek_pos(gint64)–positiontoseekto(relativetothestart);ifyouaredoingaseekinGst.Format.TIMEthisvalueisinnanoseconds-multiplywithGst.SECONDtoconvertsecondstonanosecondsorwithGst.MSECONDtoconvertmillisecondstonanoseconds. Returns(gboolean): TRUE(notintrospectable)iftheseekoperationsucceeded.Flushingseekswilltriggerapreroll,whichwillemitGst.MessageType.ASYNC_DONE.
函数使用样例:
pipeline.seek_simple(Gst.Format.TIME,Gst.SeekFlags.FLUSH,time)
其中time的单位为nanoseconds。
有视频快进/快退/循环播放功能的小播放器.
importos,_thread,time
importgi
gi.require_version("Gst","1.0")
gi.require_version('Gtk','3.0')
fromgi.repositoryimportGst,GObject,Gtk,Gdk
classGTK_Main:
def__init__(self):
window=Gtk.Window(Gtk.WindowType.TOPLEVEL)
window.set_title("Vorbis-Player")
window.set_default_size(500,-1)
window.connect("destroy",Gtk.main_quit,"WMdestroy")
vbox=Gtk.VBox()
window.add(vbox)
self.entry=Gtk.Entry()
vbox.pack_start(self.entry,False,False,0)
hbox=Gtk.HBox()
vbox.add(hbox)
buttonbox=Gtk.HButtonBox()
hbox.pack_start(buttonbox,False,False,0)
rewind_button=Gtk.Button("Rewind")
rewind_button.connect("clicked",self.rewind_callback)
buttonbox.add(rewind_button)
self.button=Gtk.Button("Start")
self.button.connect("clicked",self.start_stop)
buttonbox.add(self.button)
forward_button=Gtk.Button("Forward")
forward_button.connect("clicked",self.forward_callback)
buttonbox.add(forward_button)
self.time_label=Gtk.Label()
self.time_label.set_text("00:00/00:00")
hbox.add(self.time_label)
window.show_all()
self.player=Gst.Pipeline.new("player")
source=Gst.ElementFactory.make("filesrc","file-source")
demuxer=Gst.ElementFactory.make("decodebin","demuxer")
videoconv=Gst.ElementFactory.make("videoconvert","converter")
videosink=Gst.ElementFactory.make("xvimagesink","video-output")
demuxer.connect("pad-added",self.demuxer_callback,videoconv)
forelein[source,demuxer,videoconv,videosink]:
self.player.add(ele)
source.link(demuxer)
videoconv.link(videosink)
bus=self.player.get_bus()
bus.add_signal_watch()
bus.connect("message",self.on_message)
defstart_stop(self,w):
ifself.button.get_label()=="Start":
filepath=self.entry.get_text().strip()
ifos.path.isfile(filepath):
filepath=os.path.realpath(filepath)
self.button.set_label("Stop")
self.player.get_by_name("file-source").set_property("location",filepath)
self.player.set_state(Gst.State.PLAYING)
self.play_thread_id=_thread.start_new_thread(self.play_thread,())
else:
self.play_thread_id=None
self.player.set_state(Gst.State.NULL)
self.button.set_label("Start")
self.time_label.set_text("00:00/00:00")
defplay_thread(self):
play_thread_id=self.play_thread_id
Gdk.threads_enter()
self.time_label.set_text("00:00/00:00")
Gdk.threads_leave()
print(play_thread_id)
print(self.play_thread_id)
whileplay_thread_id==self.play_thread_id:
time.sleep(0.2)
dur_int=self.player.query_duration(Gst.Format.TIME)[1]
ifdur_int==-1:
continue
dur_str=self.convert_ns(dur_int)
Gdk.threads_enter()
self.time_label.set_text("00:00/"+dur_str)
Gdk.threads_leave()
break
time.sleep(0.2)
whileplay_thread_id==self.play_thread_id:
pos_int=self.player.query_position(Gst.Format.TIME)[1]
pos_str=self.convert_ns(pos_int)
ifplay_thread_id==self.play_thread_id:
Gdk.threads_enter()
self.time_label.set_text(pos_str+"/"+dur_str)
Gdk.threads_leave()
time.sleep(1)
defon_message(self,bus,message):
t=message.type
ift==Gst.MessageType.EOS:
self.player.seek_simple(Gst.Format.TIME,Gst.SeekFlags.FLUSH,0000000000)
elift==Gst.MessageType.ERROR:
err,debug=message.parse_error()
print("Error:%s"%err,debug)
self.play_thread_id=None
self.player.set_state(Gst.State.NULL)
self.button.set_label("Start")
self.time_label.set_text("00:00/00:00")
defdemuxer_callback(self,demuxer,pad,dst):
caps=Gst.Pad.get_current_caps(pad)
structure_name=caps.to_string()
ifstructure_name.startswith("video"):
videorate_pad=dst.get_static_pad("sink")
pad.link(videorate_pad)
defrewind_callback(self,w):
rc,pos_int=self.player.query_position(Gst.Format.TIME)
seek_ns=pos_int-10*1000000000
ifseek_ns<0:
seek_ns=0
print('Backward:%dns->%dns'%(pos_int,seek_ns))
self.player.seek_simple(Gst.Format.TIME,Gst.SeekFlags.FLUSH,seek_ns)
defforward_callback(self,w):
rc,pos_int=self.player.query_position(Gst.Format.TIME)
seek_ns=pos_int+10*1000000000
print('Forward:%dns->%dns'%(pos_int,seek_ns))
self.player.seek_simple(Gst.Format.TIME,Gst.SeekFlags.FLUSH,seek_ns)
defconvert_ns(self,t):
s,ns=divmod(t,1000000000)
m,s=divmod(s,60)
ifm<60:
return"%02i:%02i"%(m,s)
else:
h,m=divmod(m,60)
return"%i:%02i:%02i"%(h,m,s)
GObject.threads_init()
Gst.init(None)
GTK_Main()
Gtk.main()
总结
到此这篇关于pythongstreamer实现视频快进/快退/循环播放功能的文章就介绍到这了,更多相关pythongstreamer实现视频快进/快退/循环播放内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!