SoFunction
Updated on 2025-03-02

python gstreamer implements video fast forward/fast rewind/loop playback function

What is Gstreamer?

GStreamer is a pipeline-based multimedia framework written in C language based on GObject.

By applying GStreamer, the multimedia framework, you can write any kind of streaming applications such as: meidaplayer, audio and video editor, VOIP, streaming media server, audio and video encoding, etc.

Summary of knowledge about fast forward/fast rewind/loop playback of videos:

1. Obtain the local video duration:

Introduction to the official function of .query_duration:

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

Queries a pad for the total stream duration.

Parameters:
pad (  ) –a  to invoke the duration query on.
format (  ) –the  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.

Use as follows:

pipeline.query_duration()[1]

Where pipeline is the pipeline for playing local videos, the query_duration() function returns a tuple, the form of the tuple is [Ture,duration:******], and ******* is the video duration in units of ns.

2. Get the current location of the video playback:

Introduction to the official function of .query_position:

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

Queries a pad for the stream position.

Parameters:
pad (  ) –a  to invoke the position query on.
format (  ) –the  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.

Use method and duration to get functionquery_duration()same.

3. Play the jump function:

.seek_simple official function introduction:

def .seek_simple (self, format, seek_flags, seek_pos):
 #python wrapper for 'gst_element_seek_simple'
 
Parameters:
element (  ) –a  to seek on
format (  ) –a  to execute the seek in, such as 
seek_flags (  ) –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  this value is in nanoseconds - multiply with  to convert seconds to nanoseconds or with  to convert milliseconds to nanoseconds.

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

Function usage example:

pipeline.seek_simple(, , time)

The unit of time is nanoseconds.

A small player with video fast forward/fast backward/loop playback functions.

import os, _thread, time
import gi
gi.require_version("Gst", "1.0")
gi.require_version('Gtk', '3.0')
from  import Gst, GObject, Gtk, Gdk
class GTK_Main:
 def __init__(self):
  window = ()
  window.set_title("Vorbis-Player")
  window.set_default_size(500, -1)
  ("destroy", Gtk.main_quit, "WM destroy")
  vbox = ()
  (vbox)
   = ()
  vbox.pack_start(, False, False, 0)
  hbox = ()
  (hbox)
  buttonbox = ()
  hbox.pack_start(buttonbox, False, False, 0)
  rewind_button = ("Rewind")
  rewind_button.connect("clicked", self.rewind_callback)
  (rewind_button)
   = ("Start")
  ("clicked", self.start_stop)
  ()
  forward_button = ("Forward")
  forward_button.connect("clicked", self.forward_callback)
  (forward_button)
  self.time_label = ()
  self.time_label.set_text("00:00 / 00:00")
  (self.time_label)
  window.show_all()
   = ("player")
  source = ("filesrc", "file-source")
  demuxer = ("decodebin", "demuxer")
  videoconv = ("videoconvert", "converter")
  videosink = ("xvimagesink", "video-output")
  ("pad-added", self.demuxer_callback, videoconv)
  for ele in [source, demuxer, videoconv, videosink]:
   (ele)
  (demuxer)
  (videosink)
  bus = .get_bus()
  bus.add_signal_watch()
  ("message", self.on_message)
 def start_stop(self, w):
  if .get_label() == "Start":
   filepath = .get_text().strip()
   if (filepath):
    filepath = (filepath)
    .set_label("Stop")
    .get_by_name("file-source").set_property("location", filepath)
    .set_state()
    self.play_thread_id = _thread.start_new_thread(self.play_thread, ())
  else:
   self.play_thread_id = None
   .set_state()
   .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:
   (0.2)
   dur_int = .query_duration()[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
  (0.2)
  while play_thread_id == self.play_thread_id:
   pos_int = .query_position()[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()
   (1)
 def on_message(self, bus, message):
  t = 
  if t == :
   .seek_simple(, , 0000000000)
  elif t == :
   err, debug = message.parse_error()
   print ("Error: %s" % err, debug)
   self.play_thread_id = None
   .set_state()
   .set_label("Start")
   self.time_label.set_text("00:00 / 00:00")
 def demuxer_callback(self, demuxer, pad, dst):
  caps = .get_current_caps(pad)
  structure_name = caps.to_string()
  if structure_name.startswith("video"):
   videorate_pad = dst.get_static_pad("sink")
   (videorate_pad)
 def rewind_callback(self, w):
  rc, pos_int = .query_position()
  seek_ns = pos_int - 10 * 1000000000
  if seek_ns < 0:
   seek_ns = 0
  print ('Backward: %d ns -> %d ns' % (pos_int, seek_ns))
  .seek_simple(, , seek_ns)
 def forward_callback(self, w):
  rc, pos_int = .query_position()
  seek_ns = pos_int + 10 * 1000000000
  print ('Forward: %d ns -> %d ns' % (pos_int, seek_ns))
  .seek_simple(, , 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()
(None)
GTK_Main()
()

Summarize

This is the article about python gstreamer implementing video fast forward/fast reversal/loop playback functions. For more related python gstreamer implementing video fast forward/fast reversal/loop playback content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!