gtk + vlc, событие MediaPlayerEndReached не воспроизводит следующее видео - PullRequest
0 голосов
/ 01 июня 2018

Итак, я использую GTK + / VLC для создания окна с областью воспроизведения видео и кнопкой «Далее».

Это начинается с воспроизведения первого видеофайла и нажатия кнопки «Далее», чтобы перейти кСледующий медиафайл, воспроизводящий его.Пока все работает отлично.

Моя проблема , если я жду, пока не запустится MediaPlayerEndReached, выполняется button_Next(), но видео не меняется.

Я что-то упустил?

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
import time

from os import listdir
from os.path import join

startingPath = './files/'

# ----------------------------------

class MediaWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Media Player")
        self.set_decorated(False) # removes titlebar
        self.move(300,150)
        self.connect("destroy", Gtk.main_quit)

        self.currFldrIdx = 0
        self.currFileIdx = 0

        self.Fldrs = []
        for fldrs in sorted(listdir(startingPath)):
            self.Fldrs.append(join(startingPath,fldrs))
        print self.Fldrs

        self.num_Fldrs = len(self.Fldrs)

        # vlc
        self.vlcInstance = vlc.Instance('--no-xlib')
        self.vlcPlayer = self.vlcInstance.media_player_new()

    def setup_objects_and_events(self):
        self.pause_nextImg = Gtk.Image.new_from_icon_name(
            "gtk-media-forward",
            Gtk.IconSize.MENU
        )

        # Buttons
        self.button_Next = Gtk.Button()
        self.button_Next.set_image(self.pause_nextImg)
        self.button_Next.connect("clicked", self.on_button_NextImg)

        # Area
        self.draw_area = Gtk.DrawingArea()
        self.draw_area.set_size_request(800,480)
        self.draw_area.connect("realize",self._realized)

        # Grid ------------------------------------
        self.hbox1 = Gtk.Box()
        self.hbox1.pack_start(self.draw_area, True, True, 0)

        self.hbox2 = Gtk.Box()
        self.hbox2.pack_start(self.button_Next, True, True, 0)

        self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.add(self.vbox)
        self.vbox.pack_start(self.hbox1, True, True, 0)
        self.vbox.pack_start(self.hbox2, False, True, 0)

    def on_button_NextImg(self, widget):
        print 'next!'
        num_FldrFiles = len(listdir(self.Fldrs[self.currFldrIdx]))

        self.currFileIdx = self.currFileIdx+1 if self.currFileIdx+1<num_FldrFiles else 0

        fileToShow = join(self.Fldrs[self.currFldrIdx], sorted(listdir(self.Fldrs[self.currFldrIdx]))[self.currFileIdx])
        print 'now showing' + fileToShow

        self.vlcPlayer.set_xwindow(self.win_id)
        self.vlcPlayer.set_mrl(fileToShow)
        self.vlcPlayer.play()

    def _realized(self, widget, data=None):
        fileToShow = join(self.Fldrs[self.currFldrIdx], sorted(listdir(self.Fldrs[self.currFldrIdx]))[self.currFileIdx])

        self.win_id = widget.get_window().get_xid()
        self.vlcPlayer.set_xwindow(self.win_id)
        self.vlcPlayer.set_mrl(fileToShow)

        self.events = self.vlcPlayer.event_manager()
        self.events.event_attach(vlc.EventType.MediaPlayerEndReached, self.EventManager)

        self.vlcPlayer.play()

    def EventManager(self, event):
        if event.type == vlc.EventType.MediaPlayerEndReached:
            print "Event reports - finished, playing next"
            self.button_Next.clicked()

# ----------------------------------
if __name__ == '__main__':
    # Create
    win = MediaWindow()
    # Setup
    win.setup_objects_and_events()
    win.show_all()
    Gtk.main()

1 Ответ

0 голосов
/ 09 июня 2018

Ваша проблема описана здесь:

API libvlc не возвращается в пределах своих обратных вызовов https://forum.videolan.org/viewtopic.php?f=32&t=80305

и здесь: https://forum.videolan.org/viewtopic.php?t=82502

У вас обычно должно быть mainloop в вашем приложении (gobject.mainloop () или Qt mainloop), поэтому вместо этого вы должны зарегистрировать метод для перезапуска проигрывателя

Это немного ошибочно для имен файлов, но ваш код теперь регистрирует требуемую функцию GObject.idle_add().

import sys
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject
gi.require_version('GdkX11', '3.0')
from gi.repository import GdkX11

import vlc
import time

from os import listdir
from os.path import join

startingPath = './files/'

# ----------------------------------

class MediaWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Media Player")
        self.autoPlay = 0
        self.set_decorated(False) # removes titlebar
        self.move(300,150)
        self.connect("destroy", Gtk.main_quit)

        self.currFldrIdx = 0
        self.currFileIdx = 0

        self.Fldrs = ['/home/public/2005.mp3','/home/public/happy.mp3','/home/public/vp.mp3']
        #for fldrs in sorted(listdir(startingPath)):
        #    self.Fldrs.append(join(startingPath,fldrs))

        self.num_Fldrs = len(self.Fldrs) - 1

        # vlc
        self.vlcInstance = vlc.Instance('--no-xlib')
        self.vlcPlayer = self.vlcInstance.media_player_new()

    def setup_objects_and_events(self):
        self.pause_nextImg = Gtk.Image.new_from_icon_name(
            "gtk-media-forward",
            Gtk.IconSize.MENU
        )

        # Buttons
        self.button_Next = Gtk.Button()
        self.button_Next.set_image(self.pause_nextImg)
        self.button_Next.connect("clicked", self.on_button_NextImg)

        # Area
        self.draw_area = Gtk.DrawingArea()
        self.draw_area.set_size_request(800,480)
        self.draw_area.connect("realize",self._realized)

        # Grid ------------------------------------
        self.hbox1 = Gtk.Box()
        self.hbox1.pack_start(self.draw_area, True, True, 0)

        self.hbox2 = Gtk.Box()
        self.hbox2.pack_start(self.button_Next, True, True, 0)

        self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.add(self.vbox)
        self.vbox.pack_start(self.hbox1, True, True, 0)
        self.vbox.pack_start(self.hbox2, False, True, 0)

    def on_button_NextImg(self, widget=None):
        self.currFileIdx += 1
        if self.currFileIdx > self.num_Fldrs:
            self.currFileIdx = 0

        fileToShow = self.Fldrs[self.currFileIdx]
        media = self.vlcInstance.media_new_path(fileToShow)
        self.vlcPlayer.set_media(media)
        if self.vlcPlayer.play() == -1:
            print ("error playing",fileToShow)
        else:
            print("now playing",fileToShow)

    def _realized(self, widget, data=None):
        fileToShow = self.Fldrs[self.currFldrIdx]
        self.win_id = widget.get_window().get_xid()
        self.vlcPlayer.set_xwindow(self.win_id)
        self.vlcPlayer.set_mrl(fileToShow)

        self.events = self.vlcPlayer.event_manager()
        self.events.event_attach(vlc.EventType.MediaPlayerEndReached, self.EventManager)
        self.vlcPlayer.play()

    def EventManager(self, event):
        if event.type == vlc.EventType.MediaPlayerEndReached:
            GObject.idle_add(self.on_button_NextImg)

# ----------------------------------
if __name__ == '__main__':
    # Create
    win = MediaWindow()
    # Setup
    win.setup_objects_and_events()
    win.show_all()
    Gtk.main()
...