Non working Parallel videoplayer

mdelamo90 at gmail.com mdelamo90 at gmail.com
Thu Feb 4 07:37:50 EST 2016


I have coded a program with python and vlc that plays some videos, but whenever I try to play 3 videos at once, Windows closes the program, I'm guessing that the reason is that one process can't play 3 videos at once (but I don't really know).

My trimmed program plays one video (trhough a global variable, os it's easy to change) and once you press the number 2 on the keyboard it put the data from a video on the queue to be played by another process.

The new process starts and makes some prints, then it should start the new video and another one, so we should have two videos playing, one on the left part of the screen and the other on the right.

I've done this on linear programming, but I can't make the new process to start the videos. I oame from a C/C++ background so I don't know if it's something I didn't fully grasp about the multiprocess on Python or something else that I'm doing wrong.

Here is the linear working version (commented lines 206-220) and the parallel non-working version lines (221-225) Comment/Uncomment to toogle bewtween them.

Its huge for a miniexample (383 lines), but I didn't know how to make it shorter (it comes from a 3000+ project):



# import external libraries
import wx # 2.8
import vlc
import pdb
from time import sleep
# import standard libraries
import user
import urllib

VIDEO1 = "Insert_your_first_video.mp4"
VIDEO2 = "Insert_your_second_video.mp4"


class MyOpener(urllib.FancyURLopener):
    version = "App/1.7"  # doesn't work
    version = "Mozilla/4.0 (MSIE 6.0; Windows NT 5.0)2011-03-10 15:38:34"  # works


class Consumer(multiprocessing.Process):
    def __init__(self, task_queue):
        multiprocessing.Process.__init__(self)
        self.task_queue = task_queue

    def run(self):
        app = wx.App()
        proc_name = self.name

        print "waiting for queue"

        while True:  # While queue not empy
            print self.task_queue.qsize()
            next_task = self.task_queue.get()
            global dual, midsection
            midsection = next_task.d
            dual = True
            player2 = Player("Dual PyVLC Player")
            player2.Centre()
            # show the player window centred and run the application
            print "parametro a " + str(next_task.a)
            print "parametro b " + str(next_task.b)
            print "parametro c " + str(next_task.c)
            print "parametro d " + str(next_task.d)
          # tasks.put(Task(media, dual, time, midsection))

            player2.playFile(VIDEO1,next_task.c,True)
            player2.playFile(VIDEO2,next_task.c,False)
            #player.vidplayer1.set_media(next_task.a)
            #player.vidplayer2.play()
            player2.Maximize(True)
            player2.OnFullscreen(None)
            player2.SetTransparent(255)
            player2.SetFocus()
            player2.Show(True)
            #sleep(10000)
            #player2.vidplayer1.set_title(next_task.a)
            '''player1.SetTransparent(0)
            player1.timer1.Start(fadetime)
            player1.set_amount(0)'''

    def playFile(self,moviefile,time,principal):

        # Creation
        self.Media = self.Instance.media_new_path(moviefile)
        self.SetTitle("Monkey")
        #self.SetIcon(wx.Icon('Monkey.ico', wx.BITMAP_TYPE_ICO))

        if dual:
            if principal:
                #If we dont set any handle it starts in another window, maybe usefull for dual screens?
                self.vidplayer1.set_media(self.Media)
                #self.vlchandle = self.vidplayer1.get_xwindow()
                self.vidplayer1.set_hwnd(self.videopanel.GetHandle())
                self.OnPlay(None,True)
                self.vidplayer1.set_time(time)
            else:
                self.vidplayer2.set_media(self.Media)
                #self.vlchandle = self.vidplayer2.get_xwindow()
                self.vidplayer2.set_hwnd(self.videopanel2.GetHandle())
                self.OnPlay(None,False)
                self.vidplayer2.set_time(time)
        else:
            self.vidplayer1.set_media(self.Media)
            #self.vlchandle = self.vidplayer1.get_xwindow()
            self.vidplayer1.set_hwnd(self.videopanel.GetHandle())
            self.OnPlay(None,True)
            self.vidplayer1.set_time(time)

class Task(object):
    def __init__(self, a, b, c, d):
        self.a = a  # can't be media, it's not pickable
        self.b = b  # boolean
        self.c = c  # Number (time)
        self.d = d  # boolean

    def __str__(self):
        return '%s * %s' % (self.a, self.b, self.c, self.d)

class Player(wx.Frame):
    """The main window has to deal with events.
    """
    def __init__(self, title, OS="windows"):

        self.OS = OS

        wx.Frame.__init__(self, None, -1, title,
                          pos=wx.DefaultPosition, size=(950, 500))
        self.SetBackgroundColour(wx.BLACK)

        # Panels
        # The first panel holds the video/videos and it's all black

        self.videopanel = wx.Panel(self, -1)
        self.videopanel.SetBackgroundColour(wx.BLACK)

        if dual:
            videopanel2 = wx.Panel(self, -1)
            self.videopanel2 = videopanel2
            self.videopanel2.SetBackgroundColour(wx.BLACK)

        # The third panel holds controls
        ctrlpanel = wx.Panel(self, -1)
        self.ctrlpanel = ctrlpanel
        self.timeslider = wx.Slider(ctrlpanel, -1, 0, 0, 1000)
        self.timeslider.SetRange(0, 1000)
        '''nextvid = wx.Button(ctrlpanel, label=">")
        prevvid = wx.Button(ctrlpanel, label="<")
        pause = wx.Button(ctrlpanel, label="Pause")
        play = wx.Button(ctrlpanel, label="Play")
        stop = wx.Button(ctrlpanel, label="Stop")
        fullscreen = wx.Button(ctrlpanel, label="Fullscreen on/off")
        self.showcontrols = wx.CheckBox(ctrlpanel, -1, 'Show controls')'''

        # Bind controls to events

        #self.Bind(wx.EVT_BUTTON, self.on_full_screen, fullscreen)
        #self.Bind(wx.EVT_CHECKBOX, self.on_show_controls_checkbox, self.showcontrols)
        self.videopanel.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)

        # Give a pretty layout to the controls
        ctrlbox = wx.BoxSizer(wx.VERTICAL)
        box1 = wx.BoxSizer(wx.HORIZONTAL)
        box2 = wx.BoxSizer(wx.HORIZONTAL)
        '''box1.Add(self.timeslider, 1)
        # box2 contains some buttons
        box2.Add(play, flag=wx.RIGHT, border=5)
        box2.Add(pause)
        box2.Add(stop)
        box2.Add(nextvid)
        box2.Add(prevvid)
        box2.Add(fullscreen)
        box2.Add(self.showcontrols)'''
        box2.Add((-1, -1), 1)

        ctrlbox.Add(box1, 0, flag=wx.EXPAND | wx.BOTTOM, border=10)
        ctrlbox.Add(box2, 0, flag=wx.EXPAND)
        ctrlpanel.SetSizer(ctrlbox)

        self.videopanel.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseLeaveCtrlpanel)

        if dual:
            self.videopanel2.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseLeaveCtrlpanel)

        # Put everything together
        sizer2 = wx.BoxSizer(wx.VERTICAL)
        sizer1 = wx.BoxSizer(wx.HORIZONTAL)
        sizer1.Add(self.videopanel, 1, flag=wx.EXPAND)
        if dual:
            sizer1.Add(self.videopanel2, 1, flag=wx.EXPAND)
        sizer2.Add(sizer1, 1, flag=wx.EXPAND)
        sizer2.Add(ctrlpanel, 0, flag=wx.EXPAND | wx.BOTTOM | wx.TOP, border=1)
        self.SetSizer(sizer2)
        self.SetMinSize((550, 270))

        # finally create the timer, which updates the timeslider
        self.timer = wx.Timer(self)
        #self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)

        #self.show_controls(True)
        # VLC player controls
        plugin_path = None  # Multiplatform
        if self.OS == "linux":
            plugin_path == "/usr/lib/vlc/plugins"
        elif self.OS == "windows":
            plugin_path == "C:\\Program Files (x86)\\VideoLAN\\VLC\\plugins"
        if plugin_path:
            self.Instance = vlc.Instance("--plugin-path %s" % plugin_path)
        else:
            self.Instance = vlc.Instance('--input-repeat=-1 --reset-config --no-video-title-show')# --start-time=10')

        #print "VLC Instance: %s" % self.Instance
        #We create instances of VLC, can we make them in the same Frame?
        self.vidplayer1 = self.Instance.media_player_new()
        self.vidplayer2 = self.Instance.media_player_new()

    def on_full_screen(self, evt):
        self.Show()
        self.ShowFullScreen(not self.IsFullScreen())

    def OnKeyDown(self, event):
        global dual,time,midsection,sizer1,To_pause
        keycode = event.GetKeyCode()
        print keycode
        if keycode == 50:
        # 2
            if dual == False:  # We change to dual video
                '''dual = True
                time = player.vidplayer1.get_time()
                media = player.vidplayer1.get_media()
                # We make visible the background videoplayer
                player2.SetTransparent(255)
                # We stop the foreground videoplayer
                player1.vidplayer1.stop()
                player.vidplayer1.stop()
                # We create a dual video player and put the old video on the left
                player2.playFile(VIDEO1, 0, True)
                player2.playFile(VIDEO2, 0, False)
                # We make invisible the foreground videoplayer
                player.SetTransparent(0)
                player1.SetTransparent(0)
                player2.Show(True)'''
                time = player.vidplayer1.get_time()
                media = player.vidplayer1.get_media()
                player.vidplayer1.stop()
                player.SetTransparent(0)
                tasks.put(Task(VIDEO1, dual, time, midsection))
            else:  # We change to mono
                if player2.vidplayer1.get_time() != -1:
                    time = player2.vidplayer1.get_time()
                    media = player2.vidplayer1.get_media()
                    player2.vidplayer2.stop()
                    player.vidplayer1.set_media(media)
                    player1.vidplayer1.stop()
                    player.vidplayer1.play()
                    player.vidplayer1.set_time(time)
                    sleep(0.8)
                    player2.vidplayer1.stop()
                    player2.Hide()
                    '''if To_pause == False:
                        player.vidplayer1.pause()'''
                    player.Show(True)
                else:
                    time = player3.vidplayer1.get_time()
                    media = player3.vidplayer1.get_media()
                    player2.vidplayer2.set_media(player3.vidplayer2.get_media())
                    player3.vidplayer2.stop()
                    player.vidplayer1.set_media(media)
                    player3.vidplayer1.stop()
                    player.vidplayer1.play()
                    player.vidplayer1.set_time(time)
                    sleep(0.8)
                    player3.vidplayer1.stop()
                    player3.Hide()
                    '''if To_pause == False:
                        player.vidplayer1.pause()'''
                    player.Show(True)
            dual = not dual

    def playFile(self,moviefile,time,principal):

        # Creation
        self.Media = self.Instance.media_new_path(moviefile)
        self.SetTitle("Monkey")
        #self.SetIcon(wx.Icon('Monkey.ico', wx.BITMAP_TYPE_ICO))

        if dual:
            if principal:
                #If we dont set any handle it starts in another window, maybe usefull for dual screens?
                self.vidplayer1.set_media(self.Media)
                #self.vlchandle = self.vidplayer1.get_xwindow()
                self.vidplayer1.set_hwnd(self.videopanel.GetHandle())
                self.OnPlay(None,True)
                self.vidplayer1.set_time(time)
            else:
                self.vidplayer2.set_media(self.Media)
                #self.vlchandle = self.vidplayer2.get_xwindow()
                self.vidplayer2.set_hwnd(self.videopanel2.GetHandle())
                self.OnPlay(None,False)
                self.vidplayer2.set_time(time)
        else:
            self.vidplayer1.set_media(self.Media)
            #self.vlchandle = self.vidplayer1.get_xwindow()
            self.vidplayer1.set_hwnd(self.videopanel.GetHandle())
            self.OnPlay(None,True)
            self.vidplayer1.set_time(time)

        # set the volume slider to the current volume
        #self.volslider.SetValue(self.vidplayer.audio_get_volume() / 2)


    def OnFullscreen(self,evt):
        self.Show()
        self.ShowFullScreen(not self.IsFullScreen())


    def OnPlay(self, evt, principal):
        """Toggle the status to Play/Pause.
        If no file is loaded, open the dialog window.
        """
        # check if there is a file to play, otherwise open a
        # wx.FileDialog to select a file
        if principal:
            if not self.vidplayer1.get_media():
                self.OnOpen(None)
            else:
                # Try to launch the media, if this fails display an error message
                if self.vidplayer1.play() == -1:
                    self.errorDialog("Unable to play.")
                else:
                    #Set timer to callback every 500 ms timeslider moves every 0'5s
                    self.timer.Start(500)
        else:
            if not self.vidplayer2.get_media():
                self.OnOpen(None)
            else:
                # Try to launch the media, if this fails display an error message
                if self.vidplayer2.play() == -1:
                    self.errorDialog("Unable to play.")
                else:
                    #Set timer to callback every 500 ms timeslider moves every 0'5s
                    self.timer.Start(500)

    def OnTimer(self, evt):
        """Update the time slider according to the current movie time.
        """
        # update the time
        time = self.vidplayer1.get_time()
        time = self.vidplayer1.get_time()

    def OnMouseLeaveCtrlpanel(self,evt):
        None

    def OnSetTime(self, evt):
        """Set the time according to the time sider.
        """
        time = self.timeslider.GetValue()
        # vlc.MediaPlayer.set_time returns 0 if success, -1 otherwise
        if self.vidplayer1.set_time(time) == -1:
            self.errorDialog("Failed to set time")


if __name__ == "__main__":
    global dual,midsection, tasks
    midsection = True

    tasks = multiprocessing.JoinableQueue()
    num_consumers = 2
    consumers = [Consumer(tasks)
                  for i in xrange(num_consumers)]
    for w in consumers:
        w.start()

    # Create a wx.App(), which handles the windowing system event loop
    app = wx.App()
    width, height = wx.GetDisplaySize()
    # Create the windows containing our media players
    dual = False

    player1 = Player("Single PyVLC Player")
    player = Player("Single PyVLC Player")
    dual = True

    player2 = Player("Dual PyVLC Player")

    player2.Centre()  # show the player window centred and run the application
    player2.playFile(VIDEO1, 0, True)
    player2.playFile(VIDEO2, 0, False)

    player2.Maximize(True)
    player2.on_full_screen(None)
    player2.vidplayer1.stop()
    player2.vidplayer2.stop()  # The machine can't play 3 vids at once...
    player2.Hide()
    player2.SetTransparent(0)

    player.Centre()
    player.playFile(VIDEO1,0,True)
    player.Maximize(True)
    player.OnFullscreen(None)
    player.vidplayer1.play() #The machine can't play 3 vids at once...
    player.Show(True)
    dual = False

    app.MainLoop()


More information about the Python-list mailing list