Skip to content

Commit deb0e9d

Browse files
committed
Update bindngs for vlc 3.0.18
1 parent cb86a26 commit deb0e9d

File tree

7 files changed

+1370
-898
lines changed

7 files changed

+1370
-898
lines changed

generated/3.0/examples/cocoavlc.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1-
#! /usr/bin/env python3
1+
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
33

44
# Example of using PyCocoa <https://PyPI.org/project/PyCocoa> to create a
55
# window, table and an application menu to run a video using VLC on macOS.
66
# The Python-VLC binding <https://PyPI.Python.org/pypi/python-vlc> and the
77
# corresponding VLC App, see <https://www.VideoLan.org/index.html>.
88

9-
# PyCocoa version 21.8.18 or later must be installed.
9+
# PyCocoa version 21.11.02 or later must be installed (on macOS Monterey)
1010

11-
# This VLC player has been tested with VLC 3.0.10-12, 3.0.6-8, 3.0.4,
11+
# This VLC player has been tested with VLC 3.0.10-16, 3.0.6-8, 3.0.4,
1212
# 3.0.1-2, 2.2.8 and 2.2.6 and the compatible vlc.py Python-VLC binding
13-
# using 64-bit Python 3.10.0.rc1, 3.9.6, 3.9.0-1, 3.8.10, 3.8.6, 3.7.0-4,
14-
# 3.6.4-5 and 2.7.14-18 on macOS 11.5.2 Big Sur (aka 10.16), 10.15.6
15-
# Catalina, 10.14.6 Mojave and 10.13.4-6 High Sierra. This player
16-
# does not work with PyPy <https://PyPy.org> nor with Intel(R) Python
17-
# <https://Software.Intel.com/en-us/distribution-for-python>. Python
18-
# 3.10.0rc1, 3.9.6 and macOS' Python 2.7.16 run on Apple Silicon (C{arm64}),
19-
# all other Python versions run on Intel (C{x86_64}) or I{emulated} Intel
20-
# (C{"arm64_x86_64"}, see function C{pycocoa.machine}).
13+
# using 64-bit Python 3.10.0, 3.9.6, 3.9.0-1, 3.8.10, 3.8.6, 3.7.0-4,
14+
# 3.6.4-5 and 2.7.14-18 on macOS 12.0.1 Monterey, 11.5.2-6.1 Big Sur
15+
# (aka 10.16), 10.15.6 Catalina, 10.14.6 Mojave and 10.13.4-6 High Sierra.
16+
# This player does not work with PyPy <https://PyPy.org> nor with Intel(R)
17+
# Python <https://Software.Intel.com/en-us/distribution-for-python>.
18+
19+
# Python 3.10.0, 3.9.6 and macOS' Python 2.7.16 run on Apple Silicon
20+
# (C{arm64} I{natively}), all other Python versions run on Intel (C{x86_64})
21+
# or I{emulated} Intel (C{"arm64_x86_64"}, see function C{pycocoa.machine}).
2122

2223
# MIT License <https://OpenSource.org/licenses/MIT>
2324
#
@@ -45,7 +46,7 @@ def _PyPI(package):
4546
return 'see <https://PyPI.org/project/%s>' % (package,)
4647

4748
__all__ = ('AppVLC',) # PYCHOK expected
48-
__version__ = '21.08.18'
49+
__version__ = '21.11.02'
4950

5051
try:
5152
import vlc
@@ -479,11 +480,16 @@ def _resizer(self): # adjust aspect ratio and marquee height
479480
else:
480481
Thread(target=self._sizer).start()
481482

482-
def _sizer(self, secs=0.1):
483+
def _sizer(self, secs=0.25):
483484
while True:
484-
w, h = self.player.video_get_size(0)
485+
p = self.player
486+
# wiggle the video to fill the window
487+
s = p.video_get_scale()
488+
p.video_set_scale(0.0 if s else 1.0)
489+
p.video_set_scale(s)
485490
# the first call(s) returns (0, 0),
486491
# subsequent calls return (w, h)
492+
w, h = p.video_get_size(0)
487493
if h > 0 and w > 0:
488494
# window's contents' aspect ratio
489495
self.window.ratio = self.sized = w, h

generated/3.0/examples/glsurface.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#! /usr/bin/env python3
2+
3+
#
4+
# GlSurface example code for VLC Python bindings
5+
# Copyright (C) 2020 Daniël van Adrichem <daniel5gh@spiet.nl>
6+
7+
#
8+
# This program is free software; you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation; either version 2 of the License, or
11+
# (at your option) any later version.
12+
#
13+
# This program is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with this program; if not, write to the Free Software
20+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21+
#
22+
23+
"""VLC GlSurface example
24+
"""
25+
26+
import time
27+
import ctypes
28+
from threading import Lock
29+
30+
import numpy as np
31+
from OpenGL.GL import (GL_TEXTURE_2D, glTexSubImage2D, glTexImage2D,
32+
GL_BGR, GL_RGB,
33+
GL_UNSIGNED_BYTE)
34+
import vlc
35+
36+
class Surface(object):
37+
"""A lockable image buffer
38+
"""
39+
def __init__(self, w, h):
40+
self._width = w
41+
self._height = h
42+
43+
# size in bytes when RV32 *4 or RV24 * 3
44+
self._row_size = self._width * 3
45+
self._buf_size = self._height * self._row_size
46+
# allocate buffer
47+
self._buf1 = np.zeros(self._buf_size, dtype=np.ubyte)
48+
# get pointer to buffer
49+
self._buf_p = self._buf1.ctypes.data_as(ctypes.c_void_p)
50+
self._lock = Lock()
51+
52+
def update_gl(self):
53+
# with self._lock:
54+
glTexSubImage2D(GL_TEXTURE_2D,
55+
0, 0, 0,
56+
self._width,
57+
self._height,
58+
GL_BGR,
59+
GL_UNSIGNED_BYTE,
60+
self._buf1)
61+
62+
def create_texture_gl(self):
63+
glTexImage2D(GL_TEXTURE_2D,
64+
0,
65+
GL_RGB,
66+
self._width, # width
67+
self._height, # height
68+
0,
69+
GL_BGR,
70+
GL_UNSIGNED_BYTE,
71+
None)
72+
73+
@property
74+
def width(self):
75+
return self._width
76+
77+
@property
78+
def height(self):
79+
return self._height
80+
81+
@property
82+
def row_size(self):
83+
return self._row_size
84+
85+
@property
86+
def buf(self):
87+
return self._buf1
88+
89+
@property
90+
def buf_pointer(self):
91+
return self._buf_p
92+
93+
def lock(self):
94+
self._lock.acquire()
95+
96+
def unlock(self):
97+
self._lock.release()
98+
99+
def __enter__(self, *args):
100+
return self._lock.__enter__(*args)
101+
102+
def __exit__(self, *args):
103+
return self._lock.__exit__(*args)
104+
105+
def get_libvlc_lock_callback(self):
106+
@vlc.VideoLockCb
107+
def _cb(opaque, planes):
108+
self._lock.acquire()
109+
planes[0] = self._buf_p
110+
111+
return _cb
112+
113+
def get_libvlc_unlock_callback(self):
114+
@vlc.VideoUnlockCb
115+
def _cb(opaque, picta, planes):
116+
self._lock.release()
117+
118+
return _cb
119+
120+
if __name__ == '__main__':
121+
import sys
122+
player = vlc.MediaPlayer(sys.argv[1])
123+
# play and stop so video_get_size gets a correct value
124+
# setting all callbacks to None prevents a window being created on play
125+
player.video_set_callbacks(None, None, None, None)
126+
# play and stop so video_get_size gets a correct value
127+
player.play()
128+
time.sleep(1)
129+
player.stop()
130+
w, h = player.video_get_size()
131+
surface = Surface(w, h)
132+
# need to keep a reference to the CFUNCTYPEs or else it will get GCed
133+
_lock_cb = surface.get_libvlc_lock_callback()
134+
_unlock_cb = surface.get_libvlc_unlock_callback()
135+
player.video_set_callbacks(_lock_cb, _unlock_cb, None, None)
136+
player.video_set_format(
137+
"RV24",
138+
surface.width,
139+
surface.height,
140+
surface.row_size)
141+
# this starts populating the surface's buf with pixels, from another thread
142+
player.play()
143+
# in main thread, where gl context is current:
144+
# FIXME: add some code to embed the surface + a mainloop
145+
# v.surface.update_gl()

generated/3.0/examples/psgvlc.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#! /usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
u'''Bare Bones VLC Media Player Demo with Playlist.
5+
6+
1 - Originally the Demo_Media_Player_VLC_Based.py duplicated from
7+
<https://GitHub.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms>
8+
and modified to work and showing videos on recent macOS versions.
9+
10+
2 - This script uses PySimpleGUI under its LGPL3+ stipulations.
11+
12+
3 - You will need to install the Python bindings for VLC, for example
13+
using pip: python3 -m pip install python-vlc
14+
15+
4 - You need the VLC player itself from <https://www.VideoLan.org>.
16+
17+
5 - On macOS, you also need to get tkvlc.py from this location
18+
<https://GitHub.com/oaubert/python-vlc/tree/master/examples>
19+
to get video and audio.
20+
21+
6 - On macOS, the video plays full-frame, overwriting the buttons.
22+
23+
7 - Original <https://GitHub.com/israel-dryer/Media-Player> by Israel
24+
Dryer, modified to be a PySimpleGUI Demo Program and a python-vlc
25+
example for you to customize. Uses the VLC player to playback
26+
local media files (and YouTube streams).
27+
'''
28+
import sys
29+
if sys.version_info[0] < 3: # Python 3.4+ only
30+
sys.exit('%s requires Python 3.4 or later' % (sys.argv[0],))
31+
# import Tkinter as tk
32+
import PySimpleGUI as sg
33+
import vlc
34+
35+
__all__ = ('libtk',)
36+
__version__ = '22.11.07' # mrJean1 at Gmail
37+
38+
_Load_ = 'Load'
39+
_Next_ = 'Next'
40+
_Path_ = 'Media URL or local path:'
41+
_Pause_ = 'Pause'
42+
_Play_ = 'Play'
43+
_Prev_ = 'Previous'
44+
_Stop_ = 'Stop'
45+
46+
# GUI definition & setup
47+
sg.theme('DarkBlue')
48+
49+
def Bn(name): # a PySimpleGUI "User Defined Element" (see docs)
50+
return sg.Button(name, size=(8, 1), pad=(1, 1))
51+
52+
layout = [[sg.Input(default_text=_Path_, size=(40, 1), key='-VIDEO_PATH-'), sg.Button(_Load_)],
53+
[sg.Frame('', [], size=(300, 170), key='-VID_OUT-')], # was [sg.Image('', ...)],
54+
[Bn(_Prev_), Bn(_Play_), Bn(_Next_), Bn(_Pause_), Bn(_Stop_)],
55+
[sg.Text('Load media to start', key='-MESSAGE_AREA-')]]
56+
57+
window = sg.Window('PySimpleGUI VLC Player', layout, element_justification='center', finalize=True, resizable=True)
58+
59+
window['-VID_OUT-'].expand(True, True) # type: sg.Element
60+
61+
# Media Player Setup
62+
inst = vlc.Instance()
63+
list_player = inst.media_list_player_new()
64+
media_list = inst.media_list_new([])
65+
list_player.set_media_list(media_list)
66+
player = list_player.get_media_player()
67+
# tell VLC where to render the video(s)
68+
tk_id = window['-VID_OUT-'].Widget.winfo_id()
69+
libtk = ''
70+
if sg.running_linux():
71+
player.set_xwindow(tk_id)
72+
elif sg.running_windows():
73+
player.set_hwnd(tk_id)
74+
elif sg.running_mac():
75+
try:
76+
from tkvlc import _GetNSView, libtk
77+
ns = _GetNSView(tk_id)
78+
except ImportError:
79+
ns = None
80+
libtk = 'none, install tkvlc.py from <https://GitHub.com/oaubert/python-vlc> examples'
81+
if ns: # drawable NSview
82+
player.set_nsobject(ns)
83+
else: # no video, only audio
84+
player.set_xwindow(tk_id)
85+
else: # running trinket, etc.
86+
player.set_hwnd(tk_id) # TBD
87+
88+
if __name__ == '__main__': # MCCABE 20
89+
90+
if len(sys.argv) > 1:
91+
if sys.argv[1].lower() in ('-v', '--version'):
92+
# show all versions, this vlc.py, libvlc, etc. (sample output on macOS):
93+
# ...
94+
# % python3 ./psgvlc.py -v
95+
# psgvlc.py: 22.11.06
96+
# tkinter: 8.6
97+
# libTk: /Library/Frameworks/Python.framework/Versions/3.11/lib/libtk8.6.dylib
98+
# vlc.py: 3.0.12119 (Mon May 31 18:25:17 2021 3.0.12)
99+
# libVLC: 3.0.16 Vetinari (0x3001000)
100+
# plugins: /Applications/VLC.app/Contents/MacOS/plugins
101+
# Python: 3.11.0 (64bit) macOS 13.0 arm64
102+
for t in ((sys.argv[0], __version__), (sg.tk.__name__, sg.tk.TkVersion), ('libTk', libtk)):
103+
print('{}: {}'.format(*t))
104+
try:
105+
vlc.print_version()
106+
vlc.print_python()
107+
except AttributeError:
108+
pass
109+
sys.exit(0)
110+
111+
if sys.argv[1]:
112+
media_list.add_media(sys.argv[1])
113+
list_player.set_media_list(media_list)
114+
115+
# The Event Loop
116+
while True:
117+
# run with a timeout so that current location can be updated
118+
event, values = window.read(timeout=1000)
119+
120+
if event == sg.WIN_CLOSED:
121+
break
122+
123+
if event == _Pause_:
124+
list_player.pause()
125+
elif event == _Stop_:
126+
list_player.stop()
127+
elif event == _Next_:
128+
list_player.next()
129+
list_player.play()
130+
elif event == _Prev_:
131+
list_player.previous() # first call causes current video to start over
132+
list_player.previous() # second call moves back 1 video from current
133+
list_player.play()
134+
elif event == _Play_:
135+
list_player.play()
136+
elif event == _Load_:
137+
path = values['-VIDEO_PATH-']
138+
if path and _Path_ not in path:
139+
media_list.add_media(path)
140+
list_player.set_media_list(media_list)
141+
window['-VIDEO_PATH-'].update(_Path_) # only add a legit submit
142+
143+
# update elapsed time if a video loaded and playing
144+
if player.is_playing():
145+
text = '{:02d}:{:02d}'.format(*divmod(player.get_time() // 1000, 60)) + ' / ' + \
146+
'{:02d}:{:02d}'.format(*divmod(player.get_length() // 1000, 60))
147+
if sg.running_mac():
148+
print('{}: {}'.format(sys.argv[0], text))
149+
150+
elif not media_list.count():
151+
text = 'Load media to start'
152+
else:
153+
text = 'Ready to play media'
154+
window['-MESSAGE_AREA-'].update(text)
155+
156+
window.close()

0 commit comments

Comments
 (0)