如何在 python TKinter 中使用 GStreamer 在视频播放器中调整大小和裁剪?

Posted

技术标签:

【中文标题】如何在 python TKinter 中使用 GStreamer 在视频播放器中调整大小和裁剪?【英文标题】:How to resize and crop in a video player using GStreamer in python TKinter? 【发布时间】:2016-08-23 06:49:19 【问题描述】:

我使用嵌入在我的应用程序中的 TKinter 和 GStreamer 在 python 中编写了一个小型媒体播放器。该播放器基于下面的代码,它是对Way to play video files in Tkinter? 的一个小修改。

import os, sys
import Tkinter as tkinter
import threading

import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')
gi.require_version('GdkX11', '3.0')
from gi.repository import Gst, GObject, GdkX11, GstVideo

def set_frame_handle(bus, message, frame_id):
    if not message.get_structure() is None:
        print message.get_structure().get_name()
        if message.get_structure().get_name() == 'prepare-window-handle':
            display_frame = message.src
            display_frame.set_property('force-aspect-ratio', True)
            display_frame.set_window_handle(frame_id)

window = tkinter.Tk()
window.title('')
window.geometry('500x400')

GObject.threads_init()
Gst.init(None)

display_frame = tkinter.Canvas(window, bg='#030')
display_frame.pack(side=tkinter.TOP,expand=tkinter.YES,fill=tkinter.BOTH)
frame_id = display_frame.winfo_id()

player = Gst.ElementFactory.make('playbin', None)

filepath = os.path.realpath('kbps.mp4')
filepath2 = "file:///" + filepath.replace('\\', '/').replace(':', '|')
player.set_property('uri', filepath2)

bus = player.get_bus()
bus.enable_sync_message_emission()
bus.connect('sync-message::element', set_frame_handle, frame_id)

player.set_state(Gst.State.PLAYING)

window.mainloop()

我需要放大视频的某些部分,因此我需要使用名为 videocropvideoscale 的 GStreamer 基础插件,它们都是 GStreamer 1.0 的一部分.

不幸的是,经过几天的研究,我还没有找到一个简单的 python 示例来说明如何在 Tkiinter 中使用这些插件(我没有使用 Gtk 或任何其他库)。

谁能给我一个例子来说明如何使用这些?任何帮助将非常感激。在此先感谢...

【问题讨论】:

【参考方案1】:

我想通了,可以通过添加视频过滤器元素来完成。添加的代码如下:

VideoCrop = Gst.ElementFactory.make('videocrop', 'VideoCrop')
VideoCrop.set_property('top', 100)
VideoCrop.set_property('bottom', 100)
VideoCrop.set_property('left', 50)
VideoCrop.set_property('right', 150)
player.set_property('video-filter', VideoCrop)

以下是整个源代码,在 linux 和 Windows 上测试过

import os, sys
import Tkinter as tkinter

import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')
gi.require_version('GdkX11', '3.0')
from gi.repository import Gst, GObject, GdkX11, GstVideo

def set_frame_handle(bus, message, frame_id):
    if not message.get_structure() is None:
        print message.get_structure().get_name()
        if message.get_structure().get_name() == 'prepare-window-handle':
            display_frame = message.src
            display_frame.set_property('force-aspect-ratio', True)
            display_frame.set_window_handle(frame_id)

window = tkinter.Tk()
window.title('')
window.geometry('500x400')

GObject.threads_init()
Gst.init(None)

# can aslo use display_frame = tkinter.Frame(window)
display_frame = tkinter.Canvas(window, bg='#030')

display_frame.pack(side=tkinter.TOP,expand=tkinter.YES,fill=tkinter.BOTH)
frame_id = display_frame.winfo_id()

player = Gst.ElementFactory.make('playbin', None)

filepath = os.path.realpath('kbps.mp4')
filepath2 = "file:///" + filepath.replace('\\', '/').replace(':', '|')
player.set_property('uri', filepath2)

VideoCrop = Gst.ElementFactory.make('videocrop', 'VideoCrop')
VideoCrop.set_property('top', 100)
VideoCrop.set_property('bottom', 100)
VideoCrop.set_property('left', 50)
VideoCrop.set_property('right', 150)
player.set_property('video-filter', VideoCrop)

bus = player.get_bus()
bus.enable_sync_message_emission()
bus.connect('sync-message::element', set_frame_handle, frame_id)

player.set_state(Gst.State.PLAYING)

window.mainloop()

【讨论】:

以上是关于如何在 python TKinter 中使用 GStreamer 在视频播放器中调整大小和裁剪?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 tkinter 在 python 中嵌入 python 解释器框架?

如何在 Python 中使用 tkinter 选择目录并存储位置

如何在 Codeanywhere.com 上的 Python 中使用 tkinter 模块

我如何使用python将终端输出到网格中的tkinter框架?

如何使用 tkinter/ttk 在 Python 3 中显示图像?

python tkinter Label 图形