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

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 实现视频快进/快退/循环播放内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python使用beautifulsoup从爱奇艺网抓取视频播放

    复制代码 代码如下: import sysimport urllibfrom urllib import requestimport osfrom bs4 import BeautifulSoup class DramaItem:    def __init__(self, num, title, url):        self.num = num        self.title = title        self.url = url    def __str__(self):   

  • Python实现的视频播放器功能完整示例

    本文实例讲述了Python实现的视频播放器功能.分享给大家供大家参考,具体如下: # -*- coding:utf-8 -*- #! python3 # ---------------------------------------------------------------------------- # pyglet # Copyright (c) 2006-2008 Alex Holkner # All rights reserved. # # Redistribution and us

  • Python应用03 使用PyQT制作视频播放器实例

    最近研究了Python的两个GUI包,Tkinter和PyQT.这两个GUI包的底层分别是Tcl/Tk和QT.相比之下,我觉得PyQT使用起来更加方便,功能也相对丰富.这一篇用PyQT实现一个视频播放器,并借此来说明PyQT的基本用法.  视频播放器 先把已经完成的代码放出来.代码基于Python 3.5: import time import sys from PyQt4 import QtGui, QtCore from PyQt4.phonon import Phonon class Po

  • python gstreamer实现视频快进/快退/循环播放功能

    Gstreamer到底是个啥? GStreamer 是一个 基于pipeline的多媒体框架,基于GObject,以C语言写成. 应用GStreamer这个这个多媒体框架,你可以写出任意一种流媒体的应用来如:meidaplayer.音视频编辑器.VOIP.流媒体服务器.音视频编码等等. 关于视频快进/快退/循环播放的知识总结: 1.本地视频时长获取: Gst.Pad.query_duration官方函数介绍: def Gst.Pad.query_duration (self, format):

  • video.js 实现视频只能后退不能快进的思路详解

    主要思路是点击进度条需要获取拖动前的时间点,我用mouseup事件去处理的,获得到了oldTime 就好办,然后根据需求限制拖动快进快退,因为项目允许回看,不允许快进,所以得记录maxTime,记录用户正常情况观看视频最大的那个时间点,不允许超过maxTime var isMousedown = false; var oldTime=0,newTime=0,maxTime=0; //拖动进度条会先执行这个事件 $(".vjs-progress-holder").mouseup(func

  • vue实现可以快进后退的跑马灯组件

    本文实例为大家分享了vue开发实现跑马灯效果组件的具体代码,供大家参考,具体内容如下 用vue编写一个可以快进后退的跑马灯组件 由于业务需求,要实现一个会可以控制速度的跑马灯,初开始用js的setinterval每隔几毫秒来减取一个字符拼接到后面,效果不理想就放弃了.后查询用js的animate这个api改造大功告成! 效果图 组件代码 <template>   <div class="marquee" @mouseover="pause(true)&quo

  • 用python实现监控视频人数统计

    一.图示 客户端请求输入一段视频或者一个视频流,输出人数或其他目标数量,上报给上层服务器端,即提供一个http API调用算法统计出人数,最终http上报总人数 二.准备 相关技术 python pytorch opencv http协议 post请求 Flask Flask是一个Python实现web开发的微框架,对于像我对web框架不熟悉的人来说还是比较容易上手的. Flask安装 sudo pip install Flask 三.一个简单服务器应用 为了稍微了解一下flask是如何使用的,

  • 用python制作个视频下载器

    前言 某个夜深人静的夜晚,夜微凉风微扬,月光照进我的书房~ 当我打开文件夹以回顾往事之余,惊现许多看似杂乱的无聊代码.我拍腿正坐,一个想法油然而生:"生活已然很无聊,不如再无聊些叭". 于是,我决定开一个专题,便称之为kimol君的无聊小发明. 妙-啊~~~ 众所周知,视频是一个学习新姿势知识的良好媒介.那么,如何利用爬虫更加方便快捷地下载视频呢?本文将从数据包分析到代码实现来进行一个相对完整的讲解. 一.爬虫分析 本次选取的目标视频网站为某度旗下的好看视频: https://haok

  • python b站视频下载的五种版本

    项目地址: https://github.com/Henryhaohao/Bilibili_video_download 介绍 对于单P视频:直接传入B站av号或者视频链接地址(eg: 49842011或者https://www.bilibili.com/video/av49842011) 对于多P视频: 1.下载全集:直接传入B站av号或者视频链接地址(eg: 49842011或者https://www.bilibili.com/video/av49842011) 2.下载其中一集:传入那一集

  • 利用Python轻松实现视频转GIF动图

    目录 前言 1. 准备工作 2. 初探 3. 截取区域转动图 4. 固定区域转动图 5. 添加自定义文本 前言 不知道大家是不是有过类似的经历,在看视频的时候觉得某段非常有意思想弄成动图,但是无从下手! 或可以在网上找一些在线工具但是多多少少需要付费或者带有水印之类的,那么!? 对,今天我们就来学习用Python搞定这一需求吧! 动图效果 1. 准备工作 需要准备用于生成gif的视频文件,我这里用的是上次<用Python制作一个B站视频下载小工具>里案例中的视频.另外,就是需要用到moviep

  • Python实现Youku视频批量下载功能

    前段时间由于收集视频数据的需要,自己捣鼓了一个YouKu视频批量下载的程序.东西虽然简单,但还挺实用的,拿出来分享给大家. 版本:Python2.7+BeautifulSoup3.2.1 import urllib,urllib2,sys,os from BeautifulSoup import BeautifulSoup import itertools,re url_i =1 pic_num = 1 #自己定义的引号格式转换函数 def _en_to_cn(str): obj = itert

  • Python读取图片为16进制表示简单代码

    本文主要研究的是python读取jpg格式图片并显示为16进制的相关内容,具体如下. 代码: >>> aaa = open('C:\Users\Administrator\Desktop\java\watermarkphoto/2018119110506012.png','rb') >>> aaa.read() 读取的原图: 显示效果: 总结 一开始读取的图片稍微有点大,idle直接卡死,后来截取了一个小的图片,很快就显示出来. 以上就是本文关于Python读取图片为1

  • 基于python实现高速视频传输程序

    今天要说的是一个高速视频流的采集和传输的问题,我不是研究这一块的,没有使用什么算法,仅仅是兴趣导致我很想搞懂这个问题. 1,首先是视频数据[摄像头图像]的采集,通常可以使用vfw在vc或者vb下实现,这个库我用的不好,所以一直不怎么会用.现在我们用到的是python的videocapture库,这个库用起来很简单,如下: from VideoCapture import Device cam = Device() cam.setResolution(320,240) #设置显示分辨率 cam.s

随机推荐