Beispiel #1
0
    def appLaunched_(self, app):
        super(AppVLC, self).appLaunched_(app)
        self.window = MediaWindow(title=self.video or self.title)

        if self.player:
            # the VLC player on macOS needs an NSView
            self.player.set_nsobject(self.window.NSview)
            self.player.set_mrl(self.video)

            menu = Menu('VLC')
            menu.append(
                # the action/method for each item is
                # 'menu' + item.title + '_', with
                # spaces and dots removed, see the
                # function pycocoa.title2action.
                menu.item('Open...', key='o'),
                menu.separator(),
                menu.item('Info', key='i'),
                menu.item('Close Windows', key='w'),
                menu.separator(),
                menu.item('Play',   key='p', ctrl=True),
                menu.item('Pause',  key='s', ctrl=True),
                menu.item('Rewind', key='r', ctrl=True),
                menu.separator(),
                menu.item('Zoom In',  key='+'),
                menu.item('Zoom Out', key='-'),
                menu.item('Faster', key='>', shift=True),
                menu.item('Slower', key='<', shift=True),
            )
            self.append(menu)

        self.menuPlay_(None)
        self.window.front()
        self._resize(True)
Beispiel #2
0
    def appLaunched_(self, app):
        super(AppVLC, self).appLaunched_(app)
        self.window = MediaWindow(title=self.video or self.title)

        if self.player and self.video and isfile(self.video):
            # the VLC player on macOS needs an ObjC NSView
            self.media = self.player.set_mrl(self.video)
            self.player.set_nsobject(self.window.NSview)

            # if this window is on an external screen,
            # move it to the built-in screen, aka 0
            # if not self.window.screen.isBuiltIn:
            #     self.window.screen = 0  # == BuiltIn

            if self.adjustr:  # preset video options
                for o in self.adjustr.lower().split(','):
                    o, v = o.strip().split('=')
                    o = getattr(_Adjust, o.capitalize(), None)
                    if o is not None:
                        self._VLCadjust(o, value=v)

            if self.marquee:  # set up marquee
                self._VLCmarquee()

            if self.logostr:  # show logo
                self._VLClogo(self.logostr)

            menu = Menu('VLC')
            menu.append(
                # the action/method name for each item
                # is string 'menu' + item.title + '_',
                # without any spaces and trailing dots,
                # see function pycocoa.title2action.
                Item('Open...', key='o'),
                ItemSeparator(),
                Item('Info', key='i'),
                Item('Close Windows', key='w'),
                ItemSeparator(),
                self.Toggle,  # Play >< Pause
                Item('Rewind', key='r', ctrl=True),
                ItemSeparator(),
                Item('Zoom In', key='+'),
                Item('Zoom Out', key='-'),
                ItemSeparator(),
                Item('Faster', key='>', shift=True),
                Item('Slower', key='<', shift=True))
            if _VLC_3_:
                menu.append(Item('Brighter', key='b', shift=True),
                            Item('Darker', key='d', shift=True))
            menu.append(
                ItemSeparator(),
                Item('Audio Filters', self.menuFilters_, key='a', shift=True),
                Item('Video Filters', self.menuFilters_, key='v', shift=True))
            menu.append(ItemSeparator(), self.Snapshot)
            self.append(menu)

        self.menuPlay_(None)
        self.window.front()
Beispiel #3
0
    def appLaunched_(self, app):
        super(AppVLC, self).appLaunched_(app)
        self.window = MediaWindow(title=self.video or self.title)

        if self.player:
            # the VLC player on macOS needs an NSView
            self.player.set_nsobject(self.window.NSview)
            self.player.set_mrl(self.video)

            if self.adjustr:  # preset video options
                for o in self.adjustr.lower().split(','):
                    o, v = o.strip().split('=')
                    o = getattr(_Adjust, o.capitalize(), None)
                    if o is not None:
                        self._VLCadjust(o, value=v)

            if self.marquee:  # set up marquee
                self._VLCmarquee()

            if self.logostr:  # show logo
                self._VLClogo(self.logostr)

            menu = Menu('VLC')
            menu.append(
                # the action/method for each item is
                # 'menu' + item.title + '_', with
                # spaces and dots removed, see the
                # function pycocoa.title2action.
                menu.item('Open...', key='o'),
                menu.separator(),
                menu.item('Info', key='i'),
                menu.item('Close Windows', key='w'),
                menu.separator(),
                menu.item('Play',   key='p', ctrl=True),
                menu.item('Pause',  key='s', ctrl=True),
                menu.item('Rewind', key='r', ctrl=True),
                menu.separator(),
                menu.item('Zoom In',  key='+'),
                menu.item('Zoom Out', key='-'),
                menu.item('Faster', key='>', shift=True),
                menu.item('Slower', key='<', shift=True))
            if _VLC_3_:
                menu.append(
                    menu.item('Brighter'),
                    menu.item('Darker'))
            self.append(menu)

        self.menuPlay_(None)
        self.window.front()
        self._resize(True)
Beispiel #4
0
class AppVLC(App):
    '''The application with callback methods for C{app..._},
       C{menu..._} and C{window..._} events.

       Set things up inside the C{.__init__} and C{.appLauched_}
       methods, start by calling the C{.run} method.
    '''
    adjustr = ''
    marquee = None
    logostr = ''
    player = None
    raiser = False
    scale = 1  # media zoom factor
    sized = None  # video width, height
    Snapshot = Item('Snapshot', key='s', alt=True)
    snapshot = '.png'  # default, or .jpg or .tiff
    snapshots = 0
    Toggle = None
    video = None
    window = None

    def __init__(
            self,
            video=None,  # video file name
            adjustr='',  # vlc.VideoAdjustOption
            logostr='',  # vlc.VideoLogoOption
            marquee=False,  # vlc.VideoMarqueeOption
            raiser=False,  # re-raise errors
            snapshot='png',  # png, jpg or tiff format
            title='AppVLC'):  # window title
        super(AppVLC, self).__init__(raiser=raiser, title=title)
        self.adjustr = adjustr
        self.logostr = logostr
        self.marquee = marquee
        self.media = None
        self.raiser = raiser
        self.snapshot = '.' + snapshot.lstrip('.').lower()
        self.Toggle = Item('Play', self.menuToggle_, key='p', ctrl=True)
        self.video = video

        if self.snapshot == '.png':
            self.player = vlc.MediaPlayer()


#       # XXX does not work, snapshots are always png
#       elif self.snapshot in ('.jpg', '.tiff'):
#           i = vlc.Instance('--snapshot-format', self.snapshot[1:])  # --verbose 2
#           self.player = i.media_player_new()
        else:
            raise ValueError('invalid %s format: %r' % ('snapshot', snapshot))

    def appLaunched_(self, app):
        super(AppVLC, self).appLaunched_(app)
        self.window = MediaWindow(title=self.video or self.title)

        if self.player and self.video and isfile(self.video):
            # the VLC player on macOS needs an ObjC NSView
            self.media = self.player.set_mrl(self.video)
            self.player.set_nsobject(self.window.NSview)

            # if this window is on an external screen,
            # move it to the built-in screen, aka 0
            # if not self.window.screen.isBuiltIn:
            #     self.window.screen = 0  # == BuiltIn

            if self.adjustr:  # preset video options
                for o in self.adjustr.lower().split(','):
                    o, v = o.strip().split('=')
                    o = getattr(_Adjust, o.capitalize(), None)
                    if o is not None:
                        self._VLCadjust(o, value=v)

            if self.marquee:  # set up marquee
                self._VLCmarquee()

            if self.logostr:  # show logo
                self._VLClogo(self.logostr)

            menu = Menu('VLC')
            menu.append(
                # the action/method name for each item
                # is string 'menu' + item.title + '_',
                # without any spaces and trailing dots,
                # see function pycocoa.title2action.
                Item('Open...', key='o'),
                ItemSeparator(),
                Item('Info', key='i'),
                Item('Close Windows', key='w'),
                ItemSeparator(),
                self.Toggle,  # Play >< Pause
                Item('Rewind', key='r', ctrl=True),
                ItemSeparator(),
                Item('Zoom In', key='+'),
                Item('Zoom Out', key='-'),
                ItemSeparator(),
                Item('Faster', key='>', shift=True),
                Item('Slower', key='<', shift=True))
            if _VLC_3_:
                menu.append(Item('Brighter', key='b', shift=True),
                            Item('Darker', key='d', shift=True))
            menu.append(
                ItemSeparator(),
                Item('Audio Filters', self.menuFilters_, key='a', shift=True),
                Item('Video Filters', self.menuFilters_, key='v', shift=True))
            menu.append(ItemSeparator(), self.Snapshot)
            self.append(menu)

        self.menuPlay_(None)
        self.window.front()

    def menuBrighter_(self, item):
        self._brightness(item, +0.1)

    def menuCloseWindows_(self, item):  # PYCHOK expected
        # close window(s) from menu Cmd+W
        # printf('%s %r', 'close_', item)
        if not closeTables():
            self.terminate()

    def menuDarker_(self, item):
        self._brightness(item, -0.1)

    def menuFaster_(self, item):
        self._rate(item, 1.25)

    def menuFilters_(self, item):
        try:
            self.menuPause_(item)
            # display a table of audio/video filters
            t = Table(' Name:150:bold', ' Short:150:Center:center',
                      ' Long:300', 'Help')
            i = self.player.get_instance()
            b = item.title.split()[0]
            for f in sorted(i.audio_filter_list_get() if b ==
                            'Audio' else i.video_filter_list_get()):
                while f and not f[-1]:  # "rstrip" None
                    f = f[:-1]
                t.append(*map(bytes2str, f))

            t.display('VLC %s Filters' % (b, ), width=800)

        except Exception as x:
            if self.raiser:
                raise
            printf('%s', x, nl=1, nt=1)

    def menuInfo_(self, item):
        try:
            self.menuPause_(item)
            # display Python, vlc, libVLC, media info table
            p = self.player
            m = p.get_media()

            t = Table(' Name:bold', ' Value:200:Center:center', ' Alt:100')
            t.append(_Argv0, __version__, '20' + __version__)
            t.append('PyCocoa', _pycocoa_version, '20' + _pycocoa_version)
            t.append('Python', *_Python)
            t.append(*_macOS())
            x = 'built-in' if self.window.screen.isBuiltIn else 'external'
            t.append('screen', x, str(self.window.screen.displayID))
            t.separator()

            t.append('vlc.py', vlc.__version__, hex(vlc.hex_version()))
            b = ' '.join(vlc.build_date.split()[:5])
            t.append('built', strftime('%x', strptime(b, '%c')),
                     vlc.build_date)
            t.separator()
            t.append('libVLC', bytes2str(vlc.libvlc_get_version()),
                     hex(vlc.libvlc_hex_version()))
            t.append('libVLC',
                     *bytes2str(vlc.libvlc_get_compiler()).split(None, 1))
            t.separator()

            f = mrl_unquote(bytes2str(m.get_mrl()))
            t.append('media', basename(f), f)
            if f.lower().startswith('file://'):
                z = getsize(f[7:])
                t.append('size', z1000str(z), zSIstr(z))
            t.append('state', str(p.get_state()))
            f = max(p.get_position(), 0)
            t.append('position/length', '%.2f%%' % (f * 100, ),
                     _ms2str(p.get_length()))
            f = map(_ms2str, (p.get_time(), m.get_duration()))
            t.append('time/duration', *f)
            t.append('track/count', z1000str(p.video_get_track()),
                     z1000str(p.video_get_track_count()))
            t.separator()

            f = p.get_fps()
            t.append('fps/mspf', '%.6f' % (f, ), '%.3f ms' % (_mspf(f), ))
            r = p.get_rate()
            t.append('rate', '%s%%' % (int(r * 100), ), r)
            w, h = p.video_get_size(0)
            t.append('video size', _ratio2str('x', w, h))  # num=0
            r = _ratio2str(':', *aspect_ratio(w,
                                              h))  # p.video_get_aspect_ratio()
            t.append('aspect ratio', r, _ratio2str(':', *self.window.ratio))
            t.append('scale', '%.3f' % (p.video_get_scale(), ),
                     '%.3f' % (self.scale, ))
            t.separator()

            def VLCadjustr2(option):  # get option value
                lo, _, hi = _Adjust3[option]
                f = self.player.video_get_adjust_float(option)
                p = max(0, (f - lo)) * 100.0 / (hi - lo)
                t = '%.2f %.1f%%' % (f, p)
                # return 2-tuple (value, percentage) as strings
                return t.replace('.0%', '%').replace('.00', '.0').split()

            t.append('brightness', *VLCadjustr2(_Adjust.Brightness))
            t.append('contrast', *VLCadjustr2(_Adjust.Contrast))
            t.append('gamma', *VLCadjustr2(_Adjust.Gamma))
            t.append('hue', *VLCadjustr2(_Adjust.Hue))
            t.append('saturation', *VLCadjustr2(_Adjust.Saturation))
            t.separator()

            s = vlc.MediaStats()  # re-use single MediaStats instance?
            if m.get_stats(s):

                def Kops2bpstr2(bitrate):  # convert Ko/s to bits/sec
                    # bitrates are conventionally in kilo-octets-per-sec
                    return zSIstr(bitrate * 8000, B='bps', K=1000).split()

                t.append('media read', *zSIstr(s.read_bytes).split())
                t.append('input bitrate', *Kops2bpstr2(s.input_bitrate))
                if s.input_bitrate > 0:  # XXX approximate caching, based
                    # on <https://GitHub.com/oaubert/python-vlc/issues/61>
                    b = s.read_bytes - s.demux_read_bytes
                    t.append('input caching', _ms2str(b / s.input_bitrate),
                             zSIstr(b))
                t.append('demux read', *zSIstr(s.demux_read_bytes).split())
                t.append('stream bitrate', *Kops2bpstr2(s.demux_bitrate))

                t.append('video decoded', z1000str(s.decoded_video), 'blocks')
                t.append('video played', z1000str(s.displayed_pictures),
                         'frames')
                t.append('video lost', z1000str(s.lost_pictures), 'frames')

                t.append('audio decoded', z1000str(s.decoded_audio), 'blocks')
                t.append('audio played', z1000str(s.played_abuffers),
                         'buffers')
                t.append('audio lost', z1000str(s.lost_abuffers), 'buffers')

            t.display('Python, VLC & Media Information', width=500)

        except Exception as x:
            if self.raiser:
                raise
            printf('%s', x, nl=1, nt=1)

    def menuOpen_(self, item):
        # stop the current video and show
        # the panel to select another video
        self.menuPause_(item)
        self.badge.label = 'O'
        v = OpenPanel(_Select).pick(_Movies)
        if v:
            self.window.title = self.video = v
            self.player.set_mrl(v)
            self.sized = None

    def menuPause_(self, item, pause=False):  # PYCHOK expected
        # note, .player.pause() pauses and un-pauses the video,
        # .player.stop() stops the video and blanks the window
        if pause or self.player.is_playing():
            self.player.pause()
            self.badge.label = 'S'  # stopped
            self.Toggle.title = 'Play'  # item.title = 'Play'

    def menuPlay_(self, item_or_None):  # PYCHOK expected
        self.player.play()
        self._resizer()
        self.badge.label = 'P'  # Playing
        self.Toggle.title = 'Pause'  # item.title = 'Pause'

    def menuRewind_(self, item):  # PYCHOK expected
        self.player.set_position(0.0)
        # note, can't re-play once at the end
        # self.menuPlay_()
        self.badge.label = 'R'
        self.sized = None

    def menuSlower_(self, item):
        self._rate(item, 0.80)

    def menuSnapshot_(self, item):  # PYCHOK expected
        w = self.lastWindow
        if w:
            self.snapshots += 1
            s = '-'.join((_Argv0, 'snapshot%d' % (self.snapshots, ),
                          w.__class__.__name__))
            if isinstance(w, MediaWindow):
                self.player.video_take_snapshot(0, s + self.snapshot, 0, 0)
            elif get_printer:  # in PyCocoa 18.08.04+
                get_printer().printView(w.PMview, toPDF=s + '.pdf')

    def menuToggle_(self, item):
        # toggle between Pause and Play
        if self.player.is_playing():
            self.menuPause_(item, pause=True)
        else:
            self.menuPlay_(item)

    def menuZoomIn_(self, item):
        self._zoom(item, 1.25)

    def menuZoomOut_(self, item):
        self._zoom(item, 0.80)

    def windowClose_(self, window):
        # quit or click of window close button
        if window is self.window:
            self.terminate()
        self.Snapshot.isEnabled = False
        super(AppVLC, self).windowClose_(window)

    def windowLast_(self, window):
        self.Snapshot.isEnabled = window.isPrintable or isinstance(
            window, MediaWindow)
        super(AppVLC, self).windowLast_(window)

    def windowResize_(self, window):
        if window is self.window:
            self._resizer()
        super(AppVLC, self).windowResize_(window)

    def windowScreen_(self, window, change):
        if window is self.window:
            self._resizer()
        super(AppVLC, self).windowScreen_(window, change)

    def _brightness(self, unused, fraction):  # change brightness
        self._VLCadjust(_Adjust.Brightness, fraction)

    def _contrast(self, unused, fraction):  # change contrast
        self._VLCadjust(_Adjust.Contrast, fraction)

    def _gamma(self, unused, fraction):  # change gamma
        self._VLCadjust(_Adjust.Gamma, fraction)

    def _hue(self, unused, fraction):  # change hue
        self._VLCadjust(_Adjust.Hue, fraction)

    def _saturation(self, unused, fraction):  # change saturation
        self._VLCadjust(_Adjust.Saturation, fraction)

    def _rate(self, unused, factor):  # change the video rate
        r = max(0.2, min(10.0, self.player.get_rate() * factor))
        self.player.set_rate(r)

    def _resizer(self):  # adjust aspect ratio and marquee height
        if self.sized:
            # window's contents' aspect ratio
            self.window.ratio = self.sized
        else:
            Thread(target=self._sizer).start()

    def _sizer(self, secs=0.1):
        while True:
            w, h = self.player.video_get_size(0)
            # the first call(s) returns (0, 0),
            # subsequent calls return (w, h)
            if h > 0 and w > 0:
                # window's contents' aspect ratio
                self.window.ratio = self.sized = w, h
                break
            elif secs > 0.001:
                sleep(secs)
            else:  # one-shot
                break

    def _VLCadjust(self, option, fraction=0, value=None):
        # adjust a video option like brightness, contrast, etc.
        p = self.player
        # <https://Wiki.VideoLan.org/Documentation:Modules/adjust>
        # note, .Enable must be set to 1, but once is sufficient
        p.video_set_adjust_int(_Adjust.Enable, 1)
        try:
            lo, _, hi = _Adjust3[option]
            if value is None:
                v = p.video_get_adjust_float(option)
            else:
                v = float(value)
            if fraction:
                v += fraction * (hi - lo)
            v = float(max(lo, min(hi, v)))
            p.video_set_adjust_float(option, v)
        except (KeyError, ValueError):
            pass

    def _VLClogo(self, logostr):
        # add a video logo, example "python cocoavlc.py -logo
        # cone-altglass2.png\;cone-icon-small.png ..."
        p = self.player
        g = vlc.VideoLogoOption  # Enum
        # <https://Wiki.VideoLan.org/Documentation:Modules/logo>
        p.video_set_logo_int(g.enable, 1)
        p.video_set_logo_int(g.position, vlc.Position.Center)
        p.video_set_logo_int(g.opacity, 128)  # 0-255
        # p.video_set_logo_int(g.delay, 1000)  # millisec
        # p.video_set_logo_int(g.repeat, -1)  # forever
        p.video_set_logo_string(g.file, logostr)

    def _VLCmarquee(self, size=36):
        # put video marquee at the bottom-center
        p = self.player
        m = vlc.VideoMarqueeOption  # Enum
        # <https://Wiki.VideoLan.org/Documentation:Modules/marq>
        p.video_set_marquee_int(m.Enable, 1)
        p.video_set_marquee_int(m.Size, int(size))  # pixels
        p.video_set_marquee_int(m.Position, vlc.Position.Bottom)
        p.video_set_marquee_int(m.Opacity, 255)  # 0-255
        p.video_set_marquee_int(m.Color, _Color.Yellow)
        p.video_set_marquee_int(m.Timeout, 0)  # millisec, 0==forever
        p.video_set_marquee_int(m.Refresh, 1000)  # millisec (or sec?)
        p.video_set_marquee_string(m.Text, str2bytes('%Y-%m-%d  %T  %z'))

    def _zoom(self, unused, factor):
        # zoom the video rate in/out
        if factor > 0:
            self.scale *= factor
            self.player.video_set_scale(
                self.scale)  # if abs(self.scale - 1.0) > 0.01 else 0.0)
Beispiel #5
0
class AppVLC(App):
    '''The application with callback methods for C{app..._},
       C{menu..._} and C{window..._} events.

       Set things up inside the C{.__init__} and C{.appLauched_}
       methods, start by calling the C{.run} method.
    '''
    marquee = None
    panel   = None
    player  = None
    resized = False
    scale   = 1  # media zoom factor
    video   = None
    window  = None

    def __init__(self, video=None, marquee=False, **kwds):
        super(AppVLC, self).__init__(**kwds)
        self.marquee = marquee
        self.panel   = OpenPanel(_Select)
        self.player  = _VLCplayer(marquee)
        self.video   = video

    def appLaunched_(self, app):
        super(AppVLC, self).appLaunched_(app)
        self.window = MediaWindow(title=self.video or self.title)

        if self.player:
            # the VLC player on macOS needs an NSView
            self.player.set_nsobject(self.window.NSview)
            self.player.set_mrl(self.video)

            menu = Menu('VLC')
            menu.append(
                # the action/method for each item is
                # 'menu' + item.title + '_', with
                # spaces and dots removed, see the
                # function pycocoa.title2action.
                menu.item('Open...', key='o'),
                menu.separator(),
                menu.item('Info', key='i'),
                menu.item('Close Windows', key='w'),
                menu.separator(),
                menu.item('Play',   key='p', ctrl=True),
                menu.item('Pause',  key='s', ctrl=True),
                menu.item('Rewind', key='r', ctrl=True),
                menu.separator(),
                menu.item('Zoom In',  key='+'),
                menu.item('Zoom Out', key='-'),
                menu.item('Faster', key='>', shift=True),
                menu.item('Slower', key='<', shift=True),
            )
            self.append(menu)

        self.menuPlay_(None)
        self.window.front()
        self._resize(True)

    def menuCloseWindows_(self, item):  # PYCHOK expected
        # close window(s) from menu Cmd+W
        # printf('%s %r', 'close_', item)
        if not closeTables():
            self.terminate()

    def menuFaster_(self, item):
        self._rate(item, 1.25)

    def menuInfo_(self, item):
        try:
            self.menuPause_(item)

            # display Python, vlc, libVLC, media info
            p = self.player
            m = p.get_media()

            t = Table(' Name', ' Value:200', ' Alt:300')
            t.append('PyCocoa', __PyCocoa__, '20' + __version__)
            t.append('Python', *_Python)
            t.append('macOS', *_macOS)
            t.separator()

            t.append('vlc.py', vlc.__version__, hex(vlc.hex_version()))
            b = ' '.join(vlc.build_date.split()[:5])
            t.append('built', strftime('%x', strptime(b, '%c')), vlc.build_date)
            t.separator()
            t.append('libVLC', bytes2str(vlc.libvlc_get_version()), hex(vlc.libvlc_hex_version()))
            t.append('libVLC', *bytes2str(vlc.libvlc_get_compiler()).split(None, 1))
            t.separator()

            f = bytes2str(m.get_mrl())
            t.append('media', os.path.basename(f), f)
            if f.startswith('file:///'):
                z = os.path.getsize(f[7:])
                t.append('size', z1000str(z), zSIstr(z))
            t.append('state', str(p.get_state()))
            t.append('track/count', z1000str(p.video_get_track()), z1000str(p.video_get_track_count()))
            t.append('time/duration', z1000str(p.get_time()), z1000str(m.get_duration()))
            f = max(p.get_position(), 0)
            t.append('position', '%.2f%%' % (f * 100,), f)
            t.separator()

            f = p.get_fps()
            t.append('fps/mspf', '%.6f' % (f,), '%.3f ms' % (_mspf(f),))
            r = p.get_rate()
            t.append('rate', '%s%%' % (int(r * 100),), r)
            w, h = p.video_get_size(0)
            r = aspect_ratio(w, h) or ''
            if r:
                r = '%s:%s' % r
            t.append('video size', '%sx%s' % (w, h))  # num=0
            t.append('aspect ratio', str(p.video_get_aspect_ratio()), r)
            t.append('scale', '%.3f' % (p.video_get_scale(),), '%.3f' % (self.scale,))
            t.display('Python, VLC & Media Information', width=600)

        except Exception as x:
            printf('%r', x, nl=1, nt=1)

    def menuOpen_(self, item):
        # stop the current video and show
        # the panel to select another video
        self.menuPause_(item)
        self.badge.label = 'O'
        video = self.panel.pick(_Movies)
        if video:
            self.window.title = self.video = video
            self.player.set_mrl(video)
            self.ratio = 3
            self._resize(True)

    def menuPause_(self, item):  # PYCHOK expected
        # note, .pause() pauses and un-pauses the video,
        # .stop() stops the video and blanks the window
        if self.player.is_playing():
            self.player.pause()
            self.badge.label = 'S'

    def menuPlay_(self, item_or_None):  # PYCHOK expected
        self.player.play()
        self.badge.label = 'P'

    def menuRewind_(self, item):  # PYCHOK expected
        self.player.set_position(0.0)
        # can't re-play once at the end
        # self.player.play()
        self.badge.label = 'R'
        self._resize(False)

    def menuSlower_(self, item):
        self._rate(item, 0.80)

    def menuZoomIn_(self, item):
        self._zoom(item, 1.25)

    def menuZoomOut_(self, item):
        self._zoom(item, 0.80)

    def windowClose_(self, window):
        # quit or click of window close button
        if window is self.window:
            self.terminate()
        super(AppVLC, self).windowClose_(window)

    def windowResize_(self, window):
        if window is self.window:
            self._resize(False)
        super(AppVLC, self).windowResize_(window)

    def _rate(self, unused, factor):
        # change the video rate
        r = self.player.get_rate() * factor
        if 0.2 < r < 10.0:
            self.player.set_rate(r)

    def _resize(self, force):
        # adjust aspect ratio and marquee height
        if force or not self.resized:
            w, h = self.player.video_get_size()
            # the first call returns (0, 0),
            # subsequent calls return (w, h)
            if h > 0 and w > 0:
                self.window.ratio = w, h
                if self.marquee:
                    h /= 24
                    if h > 0:
                        self.player.video_set_marquee_int(
                                vlc.VideoMarqueeOption.Size, h)
                self.resized = True
            else:
                self.resized = False

    def _zoom(self, unused, factor):
        # zoom the video rate in/out
        self.scale *= factor
        self.player.video_set_scale(self.scale)
Beispiel #6
0
class AppVLC(App):
    '''The application with callback methods for C{app..._},
       C{menu..._} and C{window..._} events.

       Set things up inside the C{.__init__} and C{.appLauched_}
       methods, start by calling the C{.run} method.
    '''
    adjustr = ''
    marquee = None
    logostr = ''
    panel   = None
    player  = None
    resized = False
    scale   = 1  # media zoom factor
    video   = None
    window  = None

    def __init__(self, video=None, adjustr='', logostr='', marquee=False, **kwds):
        super(AppVLC, self).__init__(**kwds)
        self.adjustr = adjustr
        self.logostr = logostr
        self.marquee = marquee
        self.panel   = OpenPanel(_Select)
        self.player  = vlc.MediaPlayer()
        self.video   = video

    def appLaunched_(self, app):
        super(AppVLC, self).appLaunched_(app)
        self.window = MediaWindow(title=self.video or self.title)

        if self.player:
            # the VLC player on macOS needs an NSView
            self.player.set_nsobject(self.window.NSview)
            self.player.set_mrl(self.video)

            if self.adjustr:  # preset video options
                for o in self.adjustr.lower().split(','):
                    o, v = o.strip().split('=')
                    o = getattr(_Adjust, o.capitalize(), None)
                    if o is not None:
                        self._VLCadjust(o, value=v)

            if self.marquee:  # set up marquee
                self._VLCmarquee()

            if self.logostr:  # show logo
                self._VLClogo(self.logostr)

            menu = Menu('VLC')
            menu.append(
                # the action/method for each item is
                # 'menu' + item.title + '_', with
                # spaces and dots removed, see the
                # function pycocoa.title2action.
                menu.item('Open...', key='o'),
                menu.separator(),
                menu.item('Info', key='i'),
                menu.item('Close Windows', key='w'),
                menu.separator(),
                menu.item('Play',   key='p', ctrl=True),
                menu.item('Pause',  key='s', ctrl=True),
                menu.item('Rewind', key='r', ctrl=True),
                menu.separator(),
                menu.item('Zoom In',  key='+'),
                menu.item('Zoom Out', key='-'),
                menu.item('Faster', key='>', shift=True),
                menu.item('Slower', key='<', shift=True))
            if _VLC_3_:
                menu.append(
                    menu.item('Brighter'),
                    menu.item('Darker'))
            self.append(menu)

        self.menuPlay_(None)
        self.window.front()
        self._resize(True)

    def menuBrighter_(self, item):
        self._brightness(item, +0.1)

    def menuCloseWindows_(self, item):  # PYCHOK expected
        # close window(s) from menu Cmd+W
        # printf('%s %r', 'close_', item)
        if not closeTables():
            self.terminate()

    def menuDarker_(self, item):
        self._brightness(item, -0.1)

    def menuFaster_(self, item):
        self._rate(item, 1.25)

    def menuInfo_(self, item):
        try:
            self.menuPause_(item)

            # display Python, vlc, libVLC, media info
            p = self.player
            m = p.get_media()

            t = Table(' Name:bold', ' Value:200:Center:center', ' Alt:300')
            t.append('cocoavlc', __version__, '20' + __version__)
            t.append('PyCocoa', __PyCocoa__, '20' + __PyCocoa__)
            t.append('Python', *_Python)
            t.append('macOS', *_macOS)
            t.separator()

            t.append('vlc.py', vlc.__version__, hex(vlc.hex_version()))
            b = ' '.join(vlc.build_date.split()[:5])
            t.append('built', strftime('%x', strptime(b, '%c')), vlc.build_date)
            t.separator()
            t.append('libVLC', bytes2str(vlc.libvlc_get_version()), hex(vlc.libvlc_hex_version()))
            t.append('libVLC', *bytes2str(vlc.libvlc_get_compiler()).split(None, 1))
            t.separator()

            f = bytes2str(m.get_mrl())
            t.append('media', os.path.basename(f), f)
            if f.startswith('file:///'):
                z = os.path.getsize(f[7:])
                t.append('size', z1000str(z), zSIstr(z))
            t.append('state', str(p.get_state()))
            t.append('track/count', z1000str(p.video_get_track()), z1000str(p.video_get_track_count()))
            t.append('time/duration', z1000str(p.get_time()), z1000str(m.get_duration()))
            f = max(p.get_position(), 0)
            t.append('position', '%.2f%%' % (f * 100,), f)
            t.separator()

            f = p.get_fps()
            t.append('fps/mspf', '%.6f' % (f,), '%.3f ms' % (_mspf(f),))
            r = p.get_rate()
            t.append('rate', '%s%%' % (int(r * 100),), r)
            w, h = p.video_get_size(0)
            r = aspect_ratio(w, h) or ''
            if r:
                r = '%s:%s' % r
            t.append('video size', '%sx%s' % (w, h))  # num=0
            t.append('aspect ratio', str(p.video_get_aspect_ratio()), r)
            t.append('scale', '%.3f' % (p.video_get_scale(),), '%.3f' % (self.scale,))
            t.separator()

            def _VLCadjustr2(option):
                lo, _, hi = _Adjust3[option]
                f = self.player.video_get_adjust_float(option)
                p = max(0, (f - lo)) * 100.0 / (hi - lo)
                t = '%.2f %.1f%%' % (f, p)
                return t.replace('.0%', '%').replace('.00', '.0').split()

            t.append('brightness', *_VLCadjustr2(_Adjust.Brightness))
            t.append('contrast',   *_VLCadjustr2(_Adjust.Contrast))
            t.append('gamma',      *_VLCadjustr2(_Adjust.Gamma))
            t.append('hue',        *_VLCadjustr2(_Adjust.Hue))
            t.append('saturation', *_VLCadjustr2(_Adjust.Saturation))
            t.separator()

            t.display('Python, VLC & Media Information', width=600)

        except Exception as x:
            printf('%r', x, nl=1, nt=1)

    def menuOpen_(self, item):
        # stop the current video and show
        # the panel to select another video
        self.menuPause_(item)
        self.badge.label = 'O'
        video = self.panel.pick(_Movies)
        if video:
            self.window.title = self.video = video
            self.player.set_mrl(video)
            self.ratio = 3
            self._resize(True)

    def menuPause_(self, item):  # PYCHOK expected
        # note, .pause() pauses and un-pauses the video,
        # .stop() stops the video and blanks the window
        if self.player.is_playing():
            self.player.pause()
            self.badge.label = 'S'

    def menuPlay_(self, item_or_None):  # PYCHOK expected
        self.player.play()
        self.badge.label = 'P'

    def menuRewind_(self, item):  # PYCHOK expected
        self.player.set_position(0.0)
        # can't re-play once at the end
        # self.player.play()
        self.badge.label = 'R'
        self._resize(False)

    def menuSlower_(self, item):
        self._rate(item, 0.80)

    def menuZoomIn_(self, item):
        self._zoom(item, 1.25)

    def menuZoomOut_(self, item):
        self._zoom(item, 0.80)

    def windowClose_(self, window):
        # quit or click of window close button
        if window is self.window:
            self.terminate()
        super(AppVLC, self).windowClose_(window)

    def windowResize_(self, window):
        if window is self.window:
            self._resize(False)
        super(AppVLC, self).windowResize_(window)

    def _brightness(self, unused, fraction):  # change brightness
        self._VLCadjust(_Adjust.Brightness, fraction)

    def _contrast(self, unused, fraction):  # change contrast
        self._VLCadjust(_Adjust.Contrast, fraction)

    def _gamma(self, unused, fraction):  # change gamma
        self._VLCadjust(_Adjust.Gamma, fraction)

    def _hue(self, unused, fraction):  # change hue
        self._VLCadjust(_Adjust.Hue, fraction)

    def _saturation(self, unused, fraction):  # change saturation
        self._VLCadjust(_Adjust.Saturation, fraction)

    def _rate(self, unused, factor):  # change the video rate
        r = max(0.2, min(10.0, self.player.get_rate() * factor))
        self.player.set_rate(r)

    def _resize(self, force):  # adjust aspect ratio and marquee height
        if force or not self.resized:
            w, h = self.player.video_get_size()
            # the first call returns (0, 0),
            # subsequent calls return (w, h)
            if h > 0 and w > 0:
                self.window.ratio = w, h
                self.resized = True
            else:
                self.resized = False

    def _VLCadjust(self, option, fraction=0, value=None):
        # adjust a video option like brightness, contrast, etc.
        p = self.player
        # <http://Wiki.VideoLan.org/Documentation:Modules/adjust>
        # note, .Enable must be set to 1, but once will suffices
        p.video_set_adjust_int(_Adjust.Enable, 1)
        try:
            lo, _, hi = _Adjust3[option]
            if value is None:
                v = p.video_get_adjust_float(option)
            else:
                v = float(value)
            if fraction:
                v += fraction * (hi - lo)
            v = float(max(lo, min(hi, v)))
            p.video_set_adjust_float(option, v)
        except (KeyError, ValueError):
            pass

    def _VLClogo(self, logostr):
        # add a video logo, example "python cocoavlc.py -logo
        # cone-altglass2.png\;cone-icon-small.png ..."
        p = self.player
        g = vlc.VideoLogoOption  # Enum
        # <http://Wiki.VideoLan.org/Documentation:Modules/logo>
        p.video_set_logo_int(g.enable, 1)
        p.video_set_logo_int(g.position, vlc.Position.Center)
        p.video_set_logo_int(g.opacity, 128)  # 0-255
        # p.video_set_logo_int(g.delay, 1000)  # millisec
        # p.video_set_logo_int(g.repeat, -1)  # forever
        p.video_set_logo_string(g.file, logostr)

    def _VLCmarquee(self, size=36):
        # put video marquee at the bottom-center
        p = self.player
        m = vlc.VideoMarqueeOption  # Enum
        # <http://Wiki.VideoLan.org/Documentation:Modules/marq/=>
        p.video_set_marquee_int(m.Enable, 1)
        p.video_set_marquee_int(m.Size, int(size))  # pixels
        p.video_set_marquee_int(m.Position, vlc.Position.Bottom)
        p.video_set_marquee_int(m.Opacity, 255)  # 0-255
        p.video_set_marquee_int(m.Timeout, 0)  # millisec, 0==forever
        p.video_set_marquee_int(m.Refresh, 1000)  # millisec (or sec?)
        p.video_set_marquee_string(m.Text, str2bytes('%Y-%m-%d  %T  %z'))

    def _zoom(self, unused, factor):
        # zoom the video rate in/out
        self.scale *= factor
        self.player.video_set_scale(self.scale)