Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使Python中的GStreamer视频/音频平滑循环_Python_Python 3.x_Audio_Video_Gstreamer - Fatal编程技术网

使Python中的GStreamer视频/音频平滑循环

使Python中的GStreamer视频/音频平滑循环,python,python-3.x,audio,video,gstreamer,Python,Python 3.x,Audio,Video,Gstreamer,我正在尝试使用GStreamer平滑地循环MPEG-4文件。我想播放视频和音频,如果有,并循环播放。我的应用程序使用GTK作为UI 现在我有三个问题: Raspberry Pi 4的视频播放不稳定/不稳定,我正在运行它。我所说的“起伏/急促”是指每1-2秒,播放就会冻结几秒钟。当在VLC应用程序中播放相同的视频时,它是平滑的 不播放音频。同样,在VLC中播放时,音频如预期的那样存在。据我所知,playbin元素自动播放音频和视频 当到达视频结束时,最后一帧将冻结1-2秒,然后再从第一帧开始播放视

我正在尝试使用GStreamer平滑地循环MPEG-4文件。我想播放视频和音频,如果有,并循环播放。我的应用程序使用GTK作为UI

现在我有三个问题:

  • Raspberry Pi 4的视频播放不稳定/不稳定,我正在运行它。我所说的“起伏/急促”是指每1-2秒,播放就会冻结几秒钟。当在VLC应用程序中播放相同的视频时,它是平滑的
  • 不播放音频。同样,在VLC中播放时,音频如预期的那样存在。据我所知,
    playbin
    元素自动播放音频和视频
  • 当到达视频结束时,最后一帧将冻结1-2秒,然后再从第一帧开始播放视频
  • 我目前有以下代码


    视频_player.py:

    #/usr/bin/python3
    导入操作系统
    导入gi
    gi.要求_版本(“Gst”、“1.0”)
    gi.要求_版本(“Gtk”、“3.0”)
    gi.需要_版本(“GstVideo”、“1.0”)
    从gi.repository导入Gst、Gtk、GstVideo
    类视频播放器(Gtk.DrawingArea):
    定义初始化(self,video\u uri:str,loop:bool):
    super()。\uuuu init\uuuuu()
    自我循环=循环
    self.\uu video\u uri=“file://”+os.path.abspath(video\u uri)
    self.\uuxid=无
    Gst.init(无)
    self.connect(“实现”,self.\u on\u实现)
    self.set_size_request(19201080)#本例中的硬编码
    self.\uu playbin=Gst.ElementFactory.make(“playbin”,“player”)
    self.\u总线=self.\u playbin.get\u总线()
    self.\uuuu总线。添加信号\u手表()
    self.\uuu总线.connect(“消息::eos”,self.\uu在视频端)
    self.\u总线.启用\u同步\u消息\u发射()
    self.\u总线.connect(“同步消息::元素”,self.\u在同步消息上)
    self.\u playbin.set\u属性(“uri”,self.\u video\u uri)
    def_uuon_urealize(self,widget:Gtk.Window,data=None)->None:
    window=widget.get_window()
    self.\uxid=window.get\uxid()
    同步消息上的定义(self,总线:Gst.bus,消息:Gst.message)->无:
    如果message.get_structure().get_name()=“准备窗口句柄”:
    image\u sink=message.src
    image_sink.set_属性(“强制纵横比”,True)
    图像\u接收器。设置\u窗口\u句柄(self.\u xid)
    视频端上的定义(self,总线:Gst.bus,消息:Gst.message)->无:
    如果是自循环:
    self.\u playbin.set\u state(Gst.state.NULL)
    self.\u playbin.set\u state(Gst.state.PLAYING)
    def播放(自)->无:
    如果self.\u playbin.get\u state(0).state!=Gst.State.PLAYING:
    self.\u playbin.set\u state(Gst.state.PLAYING)
    
    main.py:

    #/usr/bin/python3
    从视频播放器导入视频播放器
    导入gi
    gi.要求_版本(“Gtk”、“3.0”)
    从gi.repository导入Gtk
    window=Gtk.window()
    视频播放器=视频播放器(“test\u video.mp4”,loop=True)
    添加(视频播放器)
    window.fullscreen()
    window.show_all()
    视频播放器。播放()
    Gtk.main()
    
    这个答案提供了一个使用VLC的示例;这一点被问题的作者所接受(见评论)——Raspberry Pi 4和其他类似SOC上的GStreamer通常是滞后的,如果不开始修改GStreamer库,软解决方案可能对OP没有帮助

    请注意,该代码受到了您的启发,但已根据您的需要进行了修改

    进行视频循环所需的更改(上述链接中未提供)是将参数'--input REPLATE=-1'传递给vlcinstance

    安装依赖项(假设您已经安装了gtk)

    您的代码:

    import sys
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk
    gi.require_version('GdkX11', '3.0')
    from gi.repository import GdkX11
    
    import vlc
    
    MRL = ""  # File to play
    WIDTH = 300
    HEIGHT = 300
    
    class ApplicationWindow(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self, title="Python-Vlc Media Player")
            self.player_paused=False
            self.is_player_active = False
            self.connect("destroy",Gtk.main_quit)
               
        def show(self):
            self.show_all()
            
        def setup_objects_and_events(self):
            self.playback_button = Gtk.Button()
            self.stop_button = Gtk.Button()
            
            self.play_image = Gtk.Image.new_from_icon_name(
                    "gtk-media-play",
                    Gtk.IconSize.MENU
                )
            self.pause_image = Gtk.Image.new_from_icon_name(
                    "gtk-media-pause",
                    Gtk.IconSize.MENU
                )
            self.stop_image = Gtk.Image.new_from_icon_name(
                    "gtk-media-stop",
                    Gtk.IconSize.MENU
                )
            
            self.playback_button.set_image(self.play_image)
            self.stop_button.set_image(self.stop_image)
            
            self.playback_button.connect("clicked", self.toggle_player_playback)
            self.stop_button.connect("clicked", self.stop_player)
            
            self.draw_area = Gtk.DrawingArea()
            self.draw_area.set_size_request(WIDTH,HEIGHT)
            
            self.draw_area.connect("realize",self._realized)
            
            self.hbox = Gtk.Box(spacing=6)
            self.hbox.pack_start(self.playback_button, True, True, 0)
            self.hbox.pack_start(self.stop_button, True, True, 0)
            
            self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
            self.add(self.vbox)
            self.vbox.pack_start(self.draw_area, True, True, 0)
            self.vbox.pack_start(self.hbox, False, False, 0)
            
        def stop_player(self, widget, data=None):
            self.player.stop()
            self.is_player_active = False
            self.playback_button.set_image(self.play_image)
            
        def toggle_player_playback(self, widget, data=None):
    
            """
            Handler for Player's Playback Button (Play/Pause).
            """
    
            if self.is_player_active == False and self.player_paused == False:
                self.player.play()
                self.playback_button.set_image(self.pause_image)
                self.is_player_active = True
    
            elif self.is_player_active == True and self.player_paused == True:
                self.player.play()
                self.playback_button.set_image(self.pause_image)
                self.player_paused = False
    
            elif self.is_player_active == True and self.player_paused == False:
                self.player.pause()
                self.playback_button.set_image(self.play_image)
                self.player_paused = True
            else:
                pass
            
        def _realized(self, widget, data=None):
            self.vlcInstance = vlc.Instance("--no-xlib", "--input-repeat=-1")
            self.player = self.vlcInstance.media_player_new()
            win_id = widget.get_window().get_xid()
            self.player.set_xwindow(win_id)
            self.player.set_mrl(MRL)
            self.player.play()
            self.playback_button.set_image(self.pause_image)
            self.is_player_active = True
    
    if __name__ == '__main__':
        if not sys.argv[1:]:
           print("Exiting \nMust provide the MRL.")
           sys.exit(1)
        if len(sys.argv[1:]) == 1:
            MRL = sys.argv[1]
            window = ApplicationWindow()
            window.setup_objects_and_events()
            window.show()
            Gtk.main()
            window.player.stop()
            window.vlcInstance.release()
    

    我对覆盆子皮4的Gstreamer有严重的问题。一个阻碍问题是。但可能还有更多。目前,对于Gstreamer应用程序,我仍然被迫使用Pi 3。许多人报告说,在诸如rpi等平台上,Gstreamer存在问题,关于如何使用vlc绑定或调用Popen()实现这一点的代码示例也可以接受吗?@Alexisdevarenes是的,使用vlc绑定也很好well@alexisdevarennes如果可能的话,请包含显示如何在GTK小部件中显示视频的代码
    import sys
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk
    gi.require_version('GdkX11', '3.0')
    from gi.repository import GdkX11
    
    import vlc
    
    MRL = ""  # File to play
    WIDTH = 300
    HEIGHT = 300
    
    class ApplicationWindow(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self, title="Python-Vlc Media Player")
            self.player_paused=False
            self.is_player_active = False
            self.connect("destroy",Gtk.main_quit)
               
        def show(self):
            self.show_all()
            
        def setup_objects_and_events(self):
            self.playback_button = Gtk.Button()
            self.stop_button = Gtk.Button()
            
            self.play_image = Gtk.Image.new_from_icon_name(
                    "gtk-media-play",
                    Gtk.IconSize.MENU
                )
            self.pause_image = Gtk.Image.new_from_icon_name(
                    "gtk-media-pause",
                    Gtk.IconSize.MENU
                )
            self.stop_image = Gtk.Image.new_from_icon_name(
                    "gtk-media-stop",
                    Gtk.IconSize.MENU
                )
            
            self.playback_button.set_image(self.play_image)
            self.stop_button.set_image(self.stop_image)
            
            self.playback_button.connect("clicked", self.toggle_player_playback)
            self.stop_button.connect("clicked", self.stop_player)
            
            self.draw_area = Gtk.DrawingArea()
            self.draw_area.set_size_request(WIDTH,HEIGHT)
            
            self.draw_area.connect("realize",self._realized)
            
            self.hbox = Gtk.Box(spacing=6)
            self.hbox.pack_start(self.playback_button, True, True, 0)
            self.hbox.pack_start(self.stop_button, True, True, 0)
            
            self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
            self.add(self.vbox)
            self.vbox.pack_start(self.draw_area, True, True, 0)
            self.vbox.pack_start(self.hbox, False, False, 0)
            
        def stop_player(self, widget, data=None):
            self.player.stop()
            self.is_player_active = False
            self.playback_button.set_image(self.play_image)
            
        def toggle_player_playback(self, widget, data=None):
    
            """
            Handler for Player's Playback Button (Play/Pause).
            """
    
            if self.is_player_active == False and self.player_paused == False:
                self.player.play()
                self.playback_button.set_image(self.pause_image)
                self.is_player_active = True
    
            elif self.is_player_active == True and self.player_paused == True:
                self.player.play()
                self.playback_button.set_image(self.pause_image)
                self.player_paused = False
    
            elif self.is_player_active == True and self.player_paused == False:
                self.player.pause()
                self.playback_button.set_image(self.play_image)
                self.player_paused = True
            else:
                pass
            
        def _realized(self, widget, data=None):
            self.vlcInstance = vlc.Instance("--no-xlib", "--input-repeat=-1")
            self.player = self.vlcInstance.media_player_new()
            win_id = widget.get_window().get_xid()
            self.player.set_xwindow(win_id)
            self.player.set_mrl(MRL)
            self.player.play()
            self.playback_button.set_image(self.pause_image)
            self.is_player_active = True
    
    if __name__ == '__main__':
        if not sys.argv[1:]:
           print("Exiting \nMust provide the MRL.")
           sys.exit(1)
        if len(sys.argv[1:]) == 1:
            MRL = sys.argv[1]
            window = ApplicationWindow()
            window.setup_objects_and_events()
            window.show()
            Gtk.main()
            window.player.stop()
            window.vlcInstance.release()