热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

pythongstreamer实现视频快进/快退/循环播放功能

这篇文章主要介绍了pythongstreamer实现视频快进快退循环播放功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

Gstreamer到底是个啥?

GStreamer 是一个 基于pipeline的多媒体框架,基于GObject,以C语言写成。

应用GStreamer这个这个多媒体框架,你可以写出任意一种流媒体的应用来如:meidaplayer、音视频编辑器、VOIP、流媒体服务器、音视频编码等等。

关于视频快进/快退/循环播放的知识总结:

1.本地视频时长获取:

Gst.Pad.query_duration官方函数介绍:

def Gst.Pad.query_duration (self, format):
 #python wrapper for 'gst_pad_query_duration'

Queries a pad for the total stream duration.

Parameters:
pad ( Gst.Pad ) –a Gst.Pad to invoke the duration query on.
format ( Gst.Format ) –the Gst.Format requested

Returns a tuple made of:
( gboolean ) –TRUE (not introspectable) if the query could be performed.
duration ( gint64 ) –TRUE (not introspectable) if the query could be performed.

使用如下:

pipeline.query_duration(Gst.Format.TIME)[1]

其中pipeline为播放本地视频的管道,query_duration()函数返回一个元组,元组的形式为[Ture,duration:******],******为以ns为单位的视频时长。

2.视频播放当前位置获取:

Gst.Pad.query_position官方函数介绍:

def Gst.Pad.query_position (self, format):
 #python wrapper for 'gst_pad_query_position'

Queries a pad for the stream position.

Parameters:
pad ( Gst.Pad ) –a Gst.Pad to invoke the position query on.
format ( Gst.Format ) –the Gst.Format requested

Returns a tuple made of:
( gboolean ) –TRUE (not introspectable) if the query could be performed.
cur ( gint64 ) –TRUE (not introspectable) if the query could be performed.

使用方法与时长获取函数query_duration()相同。

3.播放跳转函数:

Gst.Element.seek_simple官方函数介绍:

def Gst.Element.seek_simple (self, format, seek_flags, seek_pos):
 #python wrapper for 'gst_element_seek_simple'
 
Parameters:
element ( Gst.Element ) –a Gst.Element to seek on
format ( Gst.Format ) –a Gst.Format to execute the seek in, such as Gst.Format.TIME
seek_flags ( Gst.SeekFlags ) –seek options; playback applications will usually want to use GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT here
seek_pos ( gint64 ) –position to seek to (relative to the start); if you are doing a seek in Gst.Format.TIME this value is in nanoseconds - multiply with Gst.SECOND to convert seconds to nanoseconds or with Gst.MSECOND to convert milliseconds to nanoseconds.

Returns ( gboolean ) :
TRUE (not introspectable) if the seek operation succeeded. Flushing seeks will trigger a preroll, which will emit Gst.MessageType.ASYNC_DONE.

函数使用样例:

pipeline.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, time)

其中time的单位为nanoseconds。

有视频快进/快退/循环播放功能的小播放器.

import os, _thread, time
import gi
gi.require_version("Gst", "1.0")
gi.require_version('Gtk', '3.0')
from gi.repository import Gst, GObject, Gtk, Gdk
class GTK_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, "WM destroy")
  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)
  for ele in [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)
 def start_stop(self, w):
  if self.button.get_label() == "Start":
   filepath = self.entry.get_text().strip()
   if os.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")
 def play_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)
  while play_thread_id == self.play_thread_id:
   time.sleep(0.2)
   dur_int = self.player.query_duration(Gst.Format.TIME)[1]
   if dur_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)
  while play_thread_id == self.play_thread_id:
   pos_int = self.player.query_position(Gst.Format.TIME)[1]
   pos_str = self.convert_ns(pos_int)
   if play_thread_id == self.play_thread_id:
    Gdk.threads_enter()
    self.time_label.set_text(pos_str + " / " + dur_str)
    Gdk.threads_leave()
   time.sleep(1)
 def on_message(self, bus, message):
  t = message.type
  if t == Gst.MessageType.EOS:
   self.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, 0000000000)
  elif t == 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")
 def demuxer_callback(self, demuxer, pad, dst):
  caps = Gst.Pad.get_current_caps(pad)
  structure_name = caps.to_string()
  if structure_name.startswith("video"):
   videorate_pad = dst.get_static_pad("sink")
   pad.link(videorate_pad)
 def rewind_callback(self, w):
  rc, pos_int = self.player.query_position(Gst.Format.TIME)
  seek_ns = pos_int - 10 * 1000000000
  if seek_ns <0:
   seek_ns = 0
  print ('Backward: %d ns -> %d ns' % (pos_int, seek_ns))
  self.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, seek_ns)
 def forward_callback(self, w):
  rc, pos_int = self.player.query_position(Gst.Format.TIME)
  seek_ns = pos_int + 10 * 1000000000
  print ('Forward: %d ns -> %d ns' % (pos_int, seek_ns))
  self.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, seek_ns)
 def convert_ns(self, t):
  s,ns = divmod(t, 1000000000)
  m,s = divmod(s, 60)
  if m <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()

总结

到此这篇关于python gstreamer 实现视频快进/快退/循环播放功能的文章就介绍到这了,更多相关python gstreamer 实现视频快进/快退/循环播放内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 如何更改电脑系统的自动校时服务器地址?
    本文介绍了如何通过注册表编辑器更改电脑系统的自动校时服务器地址。通过修改注册表中的数值数据或新建字符串数值的方式,可以将默认的时钟同步服务器地址更改为自己所需要的域名或IP地址。详细步骤包括双击时间区域,点击internet时间,勾选自动校正域名设置定时等操作。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • Python项目实战10.2:MySQL读写分离性能优化
    本文介绍了在Python项目实战中进行MySQL读写分离的性能优化,包括主从同步的配置和Django实现,以及在两台centos 7系统上安装和配置MySQL的步骤。同时还介绍了创建从数据库的用户和权限的方法。摘要长度为176字。 ... [详细]
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
  • asp中如何嵌入python的简单介绍
    本文目录一览:1、如何在IIS中执行Python脚本 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文详细介绍了Vim编辑器中的三种模式(命令模式、末行模式和编辑模式)以及它们之间的操作区别和切换方法。Vim编辑器凭借其多种命令快捷键和高效率的操作方式,得到了广大厂商和用户的认可。对于想要高效操作文本的用户来说,了解这些模式的使用方法是必不可少的。 ... [详细]
  • wpf+mvvm代码组织结构及实现方式
    本文介绍了wpf+mvvm代码组织结构的由来和实现方式。作者回顾了自己大学时期接触wpf开发和mvvm模式的经历,认为mvvm模式使得开发更加专注于业务且高效。与此同时,作者指出mvvm模式相较于mvc模式的优势。文章还提到了当没有mvvm时处理数据和UI交互的例子,以及前后端分离和组件化的概念。作者希望能够只关注原始数据结构,将数据交给UI自行改变,从而解放劳动力,避免加班。 ... [详细]
  • 引号快捷键_首选项和设置——自定义快捷键
    3.3自定义快捷键(CustomizingHotkeys)ChemDraw快捷键由一个XML文件定义,我们可以根据自己的需要, ... [详细]
author-avatar
陈氏女子2602926065
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有