Merge lp:~trb143/openlp/media_state into lp:openlp

Proposed by Tim Bentley
Status: Superseded
Proposed branch: lp:~trb143/openlp/media_state
Merge into: lp:openlp
Diff against target: 9469 lines (+3897/-2446)
59 files modified
openlp/core/app.py (+5/-1)
openlp/core/common/actions.py (+1/-1)
openlp/core/common/mixins.py (+2/-1)
openlp/core/common/registry.py (+7/-0)
openlp/core/lib/mediamanageritem.py (+37/-26)
openlp/core/lib/plugin.py (+5/-4)
openlp/core/lib/pluginmanager.py (+77/-55)
openlp/core/lib/serviceitem.py (+7/-2)
openlp/core/loader.py (+48/-0)
openlp/core/state.py (+175/-0)
openlp/core/ui/icons.py (+1/-1)
openlp/core/ui/maindisplay.py (+1/-108)
openlp/core/ui/mainwindow.py (+4/-26)
openlp/core/ui/media/__init__.py (+1/-38)
openlp/core/ui/media/mediacontroller.py (+70/-163)
openlp/core/ui/media/mediaplayer.py (+2/-1)
openlp/core/ui/media/playertab.py (+8/-9)
openlp/core/ui/media/vendor/mediainfoWrapper.py (+0/-128)
openlp/core/ui/media/vendor/vlc.py (+2900/-1193)
openlp/core/ui/media/vlcplayer.py (+4/-4)
openlp/core/ui/pluginform.py (+29/-27)
openlp/core/ui/settingsform.py (+0/-6)
openlp/core/ui/slidecontroller.py (+54/-108)
openlp/core/widgets/views.py (+1/-1)
openlp/plugins/alerts/alertsplugin.py (+3/-0)
openlp/plugins/alerts/lib/alertsmanager.py (+1/-1)
openlp/plugins/bibles/bibleplugin.py (+3/-0)
openlp/plugins/custom/customplugin.py (+3/-0)
openlp/plugins/images/imageplugin.py (+3/-0)
openlp/plugins/media/lib/mediaitem.py (+52/-149)
openlp/plugins/media/mediaplugin.py (+3/-52)
openlp/plugins/presentations/presentationplugin.py (+3/-0)
openlp/plugins/songs/lib/mediaitem.py (+12/-6)
openlp/plugins/songs/songsplugin.py (+3/-0)
openlp/plugins/songusage/songusageplugin.py (+3/-0)
scripts/check_dependencies.py (+2/-1)
scripts/jenkins_script.py (+7/-6)
tests/functional/openlp_core/api/endpoint/test_controller.py (+4/-0)
tests/functional/openlp_core/common/test_registry.py (+1/-1)
tests/functional/openlp_core/lib/test_mediamanageritem.py (+12/-0)
tests/functional/openlp_core/lib/test_pluginmanager.py (+70/-25)
tests/functional/openlp_core/lib/test_serviceitem.py (+9/-4)
tests/functional/openlp_core/test_state.py (+151/-0)
tests/functional/openlp_core/ui/media/test_mediacontroller.py (+33/-104)
tests/functional/openlp_core/ui/media/test_vlcplayer.py (+4/-4)
tests/functional/openlp_core/ui/test_maindisplay.py (+1/-19)
tests/functional/openlp_core/ui/test_mainwindow.py (+12/-7)
tests/functional/openlp_core/ui/test_media.py (+13/-11)
tests/functional/openlp_core/ui/test_slidecontroller.py (+3/-0)
tests/functional/openlp_core/widgets/test_views.py (+16/-13)
tests/functional/openlp_plugins/images/test_upgrade.py (+4/-2)
tests/functional/openlp_plugins/media/test_mediaplugin.py (+1/-27)
tests/functional/openlp_plugins/songs/test_mediaitem.py (+0/-1)
tests/interfaces/openlp_core/lib/test_pluginmanager.py (+16/-12)
tests/interfaces/openlp_core/ui/media/__init__.py (+0/-21)
tests/interfaces/openlp_core/ui/media/vendor/__init__.py (+0/-21)
tests/interfaces/openlp_core/ui/media/vendor/test_mediainfoWrapper.py (+0/-48)
tests/interfaces/openlp_core/ui/test_mainwindow.py (+10/-4)
tests/openlp_core/projectors/test_projector_db.py (+0/-4)
To merge this branch: bzr merge lp:~trb143/openlp/media_state
Reviewer Review Type Date Requested Status
Phill Needs Information
Review via email: mp+361389@code.launchpad.net

This proposal supersedes a proposal from 2019-01-01.

This proposal has been superseded by a proposal from 2019-01-10.

Commit message

This is to do a code review and see what mess is left

Description of the change

Refactor Media and add State management. (there is more to do!)

* Add Start of State management with dependency understanding. (works for VLC and PyMediaInfo)!
* refactor plugin manager to use this (part 1)
* move loading of static stuff from mainwindow.
* Only use VLC for media, remove other options (more cleanups to be done later)
* clean up pymediainfo usage
* remove audio and convert to vlc for song audio player
* fix many bugs discovered on my travels.
* upgraded vlc.py

lp:~trb143/openlp/media_state (revision 2914)
https://ci.openlp.io/job/Branch-01-Pull/2675/ [SUCCESS]
https://ci.openlp.io/job/Branch-02a-Linux-Tests/2569/ [SUCCESS]
https://ci.openlp.io/job/Branch-02b-macOS-Tests/339/ [SUCCESS]
https://ci.openlp.io/job/Branch-03a-Build-Source/181/ [SUCCESS]
https://ci.openlp.io/job/Branch-03b-Build-macOS/160/ [SUCCESS]
https://ci.openlp.io/job/Branch-04a-Code-Lint/1643/ [SUCCESS]
https://ci.openlp.io/job/Branch-04b-Test-Coverage/1456/ [SUCCESS]
https://ci.openlp.io/job/Branch-05-AppVeyor-Tests/346/ [FAILURE]
Stopping after failure

Failed builds:
 - Branch-05-AppVeyor-Tests #346: https://ci.openlp.io/job/Branch-05-AppVeyor-Tests/346/console

To post a comment you must log in.
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests failed, please see https://ci.openlp.io/job/MP-02-Linux_Tests/65/ for more details

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests failed, please see https://ci.openlp.io/job/MP-02-Linux_Tests/66/ for more details

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests failed, please see https://ci.openlp.io/job/MP-02-Linux_Tests/67/ for more details

Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

Linux tests passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

Linting passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

macOS tests passed!

Revision history for this message
Phill (phill-ridout) wrote :

Only got to line 1023, will take another look later, just a few minor issues with doc strings (see inline comments)

lp:~trb143/openlp/media_state updated
2915. By Tim Bentley

Fix doc strings

Revision history for this message
Phill (phill-ridout) wrote :

I assume the commented out code is a work in progress?

L7027: if statement not needed
L7953: I'm not convinced the user will want to see a dialog box every time the preview, go live, or edit a song that has audio....

Also it looks like you've removed the background audio controls from the live slide controller, but not replaced them with anything?

review: Needs Information
Revision history for this message
Phill (phill-ridout) wrote :

L7953: I'm not convinced the user will want to see a dialog box every time the preview, go live, or edit a song that has audio....

Could you comment this out for no, I'mo concerned that this would too easily be overlooked. (Its only going to happen for people who try to load a song with background audio and have the media tab disable / problems with VLC integration.

If you can do that and resub, I'll be happy to approve it!

lp:~trb143/openlp/media_state updated
2916. By Tim Bentley

fix code

2917. By Tim Bentley

fix code

2918. By Tim Bentley

fix

2919. By Tim Bentley

settings updates

2920. By Tim Bentley

Move settings

2921. By Tim Bentley

clean ups and settings

2922. By Tim Bentley

More stream stuff

2923. By Tim Bentley

Add settings tab

2924. By Tim Bentley

Head

2925. By Tim Bentley

Head 2

2926. By Tim Bentley

Media is now playing again - just

2927. By Tim Bentley

head

2928. By Tim Bentley

media now works and plays

2929. By Tim Bentley

vlc tests pass

2930. By Tim Bentley

fix pep8.5

2931. By Tim Bentley

fix pep8.5

2932. By Tim Bentley

Fixes and handle missing display

2933. By Tim Bentley

handle missing live display preserve prview

2934. By Tim Bentley

add experimental flag

2935. By Tim Bentley

pep8

2936. By Tim Bentley

head

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/app.py'
2--- openlp/core/app.py 2018-10-07 21:40:36 +0000
3+++ openlp/core/app.py 2019-01-10 21:21:29 +0000
4@@ -35,8 +35,10 @@
5
6 from PyQt5 import QtCore, QtWidgets
7
8+from openlp.core.state import State
9 from openlp.core.common import is_macosx, is_win
10 from openlp.core.common.applocation import AppLocation
11+from openlp.core.loader import loader
12 from openlp.core.common.i18n import LanguageManager, UiStrings, translate
13 from openlp.core.common.path import create_paths, copytree
14 from openlp.core.common.registry import Registry
15@@ -113,8 +115,10 @@
16 # Check if OpenLP has been upgrade and if a backup of data should be created
17 self.backup_on_upgrade(has_run_wizard, can_show_splash)
18 # start the main app window
19+ loader()
20 self.main_window = MainWindow()
21 Registry().execute('bootstrap_initialise')
22+ State().flush_preconditions()
23 Registry().execute('bootstrap_post_set_up')
24 Registry().initialise = False
25 self.main_window.show()
26@@ -132,7 +136,7 @@
27 if Settings().value('core/update check'):
28 check_for_update(self.main_window)
29 self.main_window.is_display_blank()
30- self.main_window.app_startup()
31+ Registry().execute('bootstrap_completion')
32 return self.exec()
33
34 @staticmethod
35
36=== modified file 'openlp/core/common/actions.py'
37--- openlp/core/common/actions.py 2018-06-28 15:37:37 +0000
38+++ openlp/core/common/actions.py 2019-01-10 21:21:29 +0000
39@@ -20,7 +20,7 @@
40 # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
41 ###############################################################################
42 """
43-The :mod:`~openlp.core.utils.actions` module provides action list classes used
44+The :mod:`~openlp.core.common.actions` module provides action list classes used
45 by the shortcuts system.
46 """
47 import logging
48
49=== modified file 'openlp/core/common/mixins.py'
50--- openlp/core/common/mixins.py 2018-02-03 11:24:39 +0000
51+++ openlp/core/common/mixins.py 2019-01-10 21:21:29 +0000
52@@ -49,7 +49,8 @@
53 setattr(self, name, self.logging_wrapper(m, self))
54 return self._logger
55
56- def logging_wrapper(self, func, parent):
57+ @staticmethod
58+ def logging_wrapper(func, parent):
59 """
60 Code to added debug wrapper to work on called functions within a decorated class.
61 """
62
63=== modified file 'openlp/core/common/registry.py'
64--- openlp/core/common/registry.py 2018-10-06 20:49:13 +0000
65+++ openlp/core/common/registry.py 2019-01-10 21:21:29 +0000
66@@ -203,6 +203,7 @@
67 Registry().register(de_hump(self.__class__.__name__), self)
68 Registry().register_function('bootstrap_initialise', self.bootstrap_initialise)
69 Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
70+ Registry().register_function('bootstrap_completion', self.bootstrap_completion)
71
72 def bootstrap_initialise(self):
73 """
74@@ -215,3 +216,9 @@
75 Dummy method to be overridden
76 """
77 pass
78+
79+ def bootstrap_completion(self):
80+ """
81+ Dummy method to be overridden
82+ """
83+ pass
84
85=== modified file 'openlp/core/lib/mediamanageritem.py'
86--- openlp/core/lib/mediamanageritem.py 2018-08-25 14:08:19 +0000
87+++ openlp/core/lib/mediamanageritem.py 2019-01-10 21:21:29 +0000
88@@ -129,6 +129,9 @@
89 self.has_file_icon = False
90 self.has_delete_icon = True
91 self.add_to_service_item = False
92+ self.can_preview = True
93+ self.can_make_live = True
94+ self.can_add_to_service = True
95
96 def retranslateUi(self):
97 """
98@@ -182,11 +185,14 @@
99 if self.has_delete_icon:
100 toolbar_actions.append(['Delete', StringContent.Delete, UiIcons().delete, self.on_delete_click])
101 # Preview
102- toolbar_actions.append(['Preview', StringContent.Preview, UiIcons().preview, self.on_preview_click])
103+ if self.can_preview:
104+ toolbar_actions.append(['Preview', StringContent.Preview, UiIcons().preview, self.on_preview_click])
105 # Live Button
106- toolbar_actions.append(['Live', StringContent.Live, UiIcons().live, self.on_live_click])
107+ if self.can_make_live:
108+ toolbar_actions.append(['Live', StringContent.Live, UiIcons().live, self.on_live_click])
109 # Add to service Button
110- toolbar_actions.append(['Service', StringContent.Service, UiIcons().add, self.on_add_click])
111+ if self.can_add_to_service:
112+ toolbar_actions.append(['Service', StringContent.Service, UiIcons().add, self.on_add_click])
113 for action in toolbar_actions:
114 if action[0] == StringContent.Preview:
115 self.toolbar.addSeparator()
116@@ -210,27 +216,30 @@
117 icon=UiIcons().edit,
118 triggers=self.on_edit_click)
119 create_widget_action(self.list_view, separator=True)
120- create_widget_action(self.list_view,
121- 'listView{plugin}{preview}Item'.format(plugin=self.plugin.name.title(),
122- preview=StringContent.Preview.title()),
123- text=self.plugin.get_string(StringContent.Preview)['title'],
124- icon=UiIcons().preview,
125- can_shortcuts=True,
126- triggers=self.on_preview_click)
127- create_widget_action(self.list_view,
128- 'listView{plugin}{live}Item'.format(plugin=self.plugin.name.title(),
129- live=StringContent.Live.title()),
130- text=self.plugin.get_string(StringContent.Live)['title'],
131- icon=UiIcons().live,
132- can_shortcuts=True,
133- triggers=self.on_live_click)
134- create_widget_action(self.list_view,
135- 'listView{plugin}{service}Item'.format(plugin=self.plugin.name.title(),
136- service=StringContent.Service.title()),
137- can_shortcuts=True,
138- text=self.plugin.get_string(StringContent.Service)['title'],
139- icon=UiIcons().add,
140- triggers=self.on_add_click)
141+ if self.can_preview:
142+ create_widget_action(self.list_view,
143+ 'listView{plugin}{preview}Item'.format(plugin=self.plugin.name.title(),
144+ preview=StringContent.Preview.title()),
145+ text=self.plugin.get_string(StringContent.Preview)['title'],
146+ icon=UiIcons().preview,
147+ can_shortcuts=True,
148+ triggers=self.on_preview_click)
149+ if self.can_make_live:
150+ create_widget_action(self.list_view,
151+ 'listView{plugin}{live}Item'.format(plugin=self.plugin.name.title(),
152+ live=StringContent.Live.title()),
153+ text=self.plugin.get_string(StringContent.Live)['title'],
154+ icon=UiIcons().live,
155+ can_shortcuts=True,
156+ triggers=self.on_live_click)
157+ if self.can_add_to_service:
158+ create_widget_action(self.list_view,
159+ 'listView{plugin}{service}Item'.format(plugin=self.plugin.name.title(),
160+ service=StringContent.Service.title()),
161+ can_shortcuts=True,
162+ text=self.plugin.get_string(StringContent.Service)['title'],
163+ icon=UiIcons().add,
164+ triggers=self.on_add_click)
165 if self.has_delete_icon:
166 create_widget_action(self.list_view, separator=True)
167 create_widget_action(self.list_view,
168@@ -461,10 +470,12 @@
169 Allows the list click action to be determined dynamically
170 """
171 if Settings().value('advanced/double click live'):
172- self.on_live_click()
173+ if self.can_make_live:
174+ self.on_live_click()
175 elif not Settings().value('advanced/single click preview'):
176 # NOTE: The above check is necessary to prevent bug #1419300
177- self.on_preview_click()
178+ if self.can_preview:
179+ self.on_preview_click()
180
181 def on_selection_change(self):
182 """
183
184=== modified file 'openlp/core/lib/plugin.py'
185--- openlp/core/lib/plugin.py 2017-12-29 09:15:48 +0000
186+++ openlp/core/lib/plugin.py 2019-01-10 21:21:29 +0000
187@@ -24,11 +24,9 @@
188 """
189 import logging
190
191-from PyQt5 import QtCore
192-
193 from openlp.core.common.i18n import UiStrings
194 from openlp.core.common.mixins import RegistryProperties
195-from openlp.core.common.registry import Registry
196+from openlp.core.common.registry import Registry, RegistryBase
197 from openlp.core.common.settings import Settings
198 from openlp.core.version import get_version
199
200@@ -60,7 +58,7 @@
201 VisibleName = 'visible_name'
202
203
204-class Plugin(QtCore.QObject, RegistryProperties):
205+class Plugin(RegistryBase, RegistryProperties):
206 """
207 Base class for openlp plugins to inherit from.
208
209@@ -325,6 +323,9 @@
210 """
211 return self.text_strings[name]
212
213+ def set_plugin_text_strings(self):
214+ pass
215+
216 def set_plugin_ui_text_strings(self, tooltips):
217 """
218 Called to define all translatable texts of the plugin
219
220=== modified file 'openlp/core/lib/pluginmanager.py'
221--- openlp/core/lib/pluginmanager.py 2018-08-25 14:08:19 +0000
222+++ openlp/core/lib/pluginmanager.py 2019-01-10 21:21:29 +0000
223@@ -24,8 +24,12 @@
224 """
225 import os
226
227+from PyQt5 import QtWidgets
228+
229+from openlp.core.state import State
230 from openlp.core.common import extension_loader
231 from openlp.core.common.applocation import AppLocation
232+from openlp.core.common.i18n import translate, UiStrings
233 from openlp.core.common.mixins import LogMixin, RegistryProperties
234 from openlp.core.common.registry import RegistryBase
235 from openlp.core.lib.plugin import Plugin, PluginStatus
236@@ -50,11 +54,22 @@
237 def bootstrap_initialise(self):
238 """
239 Bootstrap all the plugin manager functions
240- """
241- self.find_plugins()
242- # hook methods have to happen after find_plugins. Find plugins needs
243- # the controllers hence the hooks have moved from setupUI() to here
244- # Find and insert settings tabs
245+ Scan a directory for objects inheriting from the ``Plugin`` class.
246+ """
247+ glob_pattern = os.path.join('plugins', '*', '[!.]*plugin.py')
248+ extension_loader(glob_pattern)
249+ plugin_classes = Plugin.__subclasses__()
250+ for p in plugin_classes:
251+ try:
252+ p()
253+ self.log_debug('Loaded plugin {plugin}'.format(plugin=str(p)))
254+ except TypeError:
255+ self.log_exception('Failed to load plugin {plugin}'.format(plugin=str(p)))
256+
257+ def bootstrap_post_set_up(self):
258+ """
259+ Bootstrap all the plugin manager functions
260+ """
261 self.hook_settings_tabs()
262 # Find and insert media manager items
263 self.hook_media_manager()
264@@ -67,36 +82,23 @@
265 # Call the initialise method to setup plugins.
266 self.initialise_plugins()
267
268- def find_plugins(self):
269- """
270- Scan a directory for objects inheriting from the ``Plugin`` class.
271- """
272- glob_pattern = os.path.join('plugins', '*', '[!.]*plugin.py')
273- extension_loader(glob_pattern)
274- plugin_classes = Plugin.__subclasses__()
275- plugin_objects = []
276- for p in plugin_classes:
277- try:
278- plugin = p()
279- self.log_debug('Loaded plugin {plugin}'.format(plugin=str(p)))
280- plugin_objects.append(plugin)
281- except TypeError:
282- self.log_exception('Failed to load plugin {plugin}'.format(plugin=str(p)))
283- plugins_list = sorted(plugin_objects, key=lambda plugin: plugin.weight)
284- for plugin in plugins_list:
285- if plugin.check_pre_conditions():
286- self.log_debug('Plugin {plugin} active'.format(plugin=str(plugin.name)))
287- plugin.set_status()
288- else:
289- plugin.status = PluginStatus.Disabled
290- self.plugins.append(plugin)
291+ def bootstrap_completion(self):
292+ """
293+ Give all the plugins a chance to perform some tasks at startup
294+ """
295+ self.application.process_events()
296+ for plugin in State().list_plugins():
297+ if plugin and plugin.is_active():
298+ plugin.app_startup()
299+ self.application.process_events()
300
301- def hook_media_manager(self):
302+ @staticmethod
303+ def hook_media_manager():
304 """
305 Create the plugins' media manager items.
306 """
307- for plugin in self.plugins:
308- if plugin.status is not PluginStatus.Disabled:
309+ for plugin in State().list_plugins():
310+ if plugin and plugin.status is not PluginStatus.Disabled:
311 plugin.create_media_manager_item()
312
313 def hook_settings_tabs(self):
314@@ -106,8 +108,8 @@
315 Tabs are set for all plugins not just Active ones
316
317 """
318- for plugin in self.plugins:
319- if plugin.status is not PluginStatus.Disabled:
320+ for plugin in State().list_plugins():
321+ if plugin and plugin.status is not PluginStatus.Disabled:
322 plugin.create_settings_tab(self.settings_form)
323
324 def hook_import_menu(self):
325@@ -116,8 +118,8 @@
326 item to the import menu.
327
328 """
329- for plugin in self.plugins:
330- if plugin.status is not PluginStatus.Disabled:
331+ for plugin in State().list_plugins():
332+ if plugin and plugin.status is not PluginStatus.Disabled:
333 plugin.add_import_menu_item(self.main_window.file_import_menu)
334
335 def hook_export_menu(self):
336@@ -125,8 +127,8 @@
337 Loop through all the plugins and give them an opportunity to add an
338 item to the export menu.
339 """
340- for plugin in self.plugins:
341- if plugin.status is not PluginStatus.Disabled:
342+ for plugin in State().list_plugins():
343+ if plugin and plugin.status is not PluginStatus.Disabled:
344 plugin.add_export_menu_item(self.main_window.file_export_menu)
345
346 def hook_tools_menu(self):
347@@ -134,53 +136,73 @@
348 Loop through all the plugins and give them an opportunity to add an
349 item to the tools menu.
350 """
351- for plugin in self.plugins:
352- if plugin.status is not PluginStatus.Disabled:
353+ for plugin in State().list_plugins():
354+ if plugin and plugin.status is not PluginStatus.Disabled:
355 plugin.add_tools_menu_item(self.main_window.tools_menu)
356
357- def hook_upgrade_plugin_settings(self, settings):
358+ @staticmethod
359+ def hook_upgrade_plugin_settings(settings):
360 """
361 Loop through all the plugins and give them an opportunity to upgrade their settings.
362
363 :param settings: The Settings object containing the old settings.
364 """
365- for plugin in self.plugins:
366- if plugin.status is not PluginStatus.Disabled:
367+ for plugin in State().list_plugins():
368+ if plugin and plugin.status is not PluginStatus.Disabled:
369 plugin.upgrade_settings(settings)
370
371 def initialise_plugins(self):
372 """
373 Loop through all the plugins and give them an opportunity to initialise themselves.
374 """
375- for plugin in self.plugins:
376- self.log_info('initialising plugins {plugin} in a {state} state'.format(plugin=plugin.name,
377- state=plugin.is_active()))
378- if plugin.is_active():
379- plugin.initialise()
380- self.log_info('Initialisation Complete for {plugin}'.format(plugin=plugin.name))
381+ uninitialised_plugins = []
382+ for plugin in State().list_plugins():
383+ if plugin:
384+ self.log_info('initialising plugins {plugin} in a {state} state'.format(plugin=plugin.name,
385+ state=plugin.is_active()))
386+ if plugin.is_active():
387+ try:
388+ plugin.initialise()
389+ self.log_info('Initialisation Complete for {plugin}'.format(plugin=plugin.name))
390+ except Exception:
391+ uninitialised_plugins.append(plugin.name.title())
392+ self.log_exception('Unable to initialise plugin {plugin}'.format(plugin=plugin.name))
393+ display_text = ''
394+ if uninitialised_plugins:
395+ display_text = translate('OpenLP.PluginManager', 'Unable to initialise the following plugins:') + \
396+ '\n\n'.join(uninitialised_plugins) + '\n\n'
397+ error_text = State().get_text()
398+ if error_text:
399+ display_text = display_text + error_text + '\n'
400+ if display_text:
401+ display_text = display_text + translate('OpenLP.PluginManager', 'See the log file for more details')
402+ QtWidgets.QMessageBox.critical(None, UiStrings().Error, display_text,
403+ QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
404
405 def finalise_plugins(self):
406 """
407 Loop through all the plugins and give them an opportunity to clean themselves up
408 """
409- for plugin in self.plugins:
410- if plugin.is_active():
411+ for plugin in State().list_plugins():
412+ if plugin and plugin.is_active():
413 plugin.finalise()
414 self.log_info('Finalisation Complete for {plugin}'.format(plugin=plugin.name))
415
416- def get_plugin_by_name(self, name):
417+ @staticmethod
418+ def get_plugin_by_name(name):
419 """
420 Return the plugin which has a name with value ``name``.
421 """
422- for plugin in self.plugins:
423- if plugin.name == name:
424+ for plugin in State().list_plugins():
425+ if plugin and plugin.name == name:
426 return plugin
427 return None
428
429- def new_service_created(self):
430+ @staticmethod
431+ def new_service_created():
432 """
433 Loop through all the plugins and give them an opportunity to handle a new service
434 """
435- for plugin in self.plugins:
436+ for plugin in State().list_plugins():
437 if plugin.is_active():
438 plugin.new_service_created()
439
440=== modified file 'openlp/core/lib/serviceitem.py'
441--- openlp/core/lib/serviceitem.py 2018-10-27 01:40:20 +0000
442+++ openlp/core/lib/serviceitem.py 2019-01-10 21:21:29 +0000
443@@ -32,6 +32,7 @@
444
445 from PyQt5 import QtGui
446
447+from openlp.core.state import State
448 from openlp.core.common import md5_hash
449 from openlp.core.common.applocation import AppLocation
450 from openlp.core.common.i18n import translate
451@@ -441,7 +442,7 @@
452 self.processor = header.get('processor', None)
453 self.has_original_files = True
454 self.metadata = header.get('item_meta_data', [])
455- if 'background_audio' in header:
456+ if 'background_audio' in header and State().check_preconditions('media'):
457 self.background_audio = []
458 for file_path in header['background_audio']:
459 # In OpenLP 3.0 we switched to storing Path objects in JSON files
460@@ -616,6 +617,10 @@
461 path_from = frame['path']
462 else:
463 path_from = os.path.join(frame['path'], frame['title'])
464+ if isinstance(path_from, str):
465+ # Handle service files prior to OpenLP 3.0
466+ # Windows can handle both forward and backward slashes, so we use ntpath to get the basename
467+ path_from = Path(path_from)
468 return path_from
469
470 def remove_frame(self, frame):
471@@ -684,7 +689,7 @@
472 self.is_valid = False
473 break
474 elif self.is_command():
475- if self.is_capable(ItemCapabilities.IsOptical):
476+ if self.is_capable(ItemCapabilities.IsOptical) and State().check_preconditions('media'):
477 if not os.path.exists(frame['title']):
478 self.is_valid = False
479 break
480
481=== added file 'openlp/core/loader.py'
482--- openlp/core/loader.py 1970-01-01 00:00:00 +0000
483+++ openlp/core/loader.py 2019-01-10 21:21:29 +0000
484@@ -0,0 +1,48 @@
485+# -*- coding: utf-8 -*-
486+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
487+
488+###############################################################################
489+# OpenLP - Open Source Lyrics Projection #
490+# --------------------------------------------------------------------------- #
491+# Copyright (c) 2008-2018 OpenLP Developers #
492+# --------------------------------------------------------------------------- #
493+# This program is free software; you can redistribute it and/or modify it #
494+# under the terms of the GNU General Public License as published by the Free #
495+# Software Foundation; version 2 of the License. #
496+# #
497+# This program is distributed in the hope that it will be useful, but WITHOUT #
498+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
499+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
500+# more details. #
501+# #
502+# You should have received a copy of the GNU General Public License along #
503+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
504+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
505+###############################################################################
506+"""
507+The :mod:`~openlp.core.loader` module provides a bootstrap for the singleton classes
508+"""
509+
510+from openlp.core.state import State
511+from openlp.core.ui.media.mediacontroller import MediaController
512+from openlp.core.lib.pluginmanager import PluginManager
513+from openlp.core.display.renderer import Renderer
514+from openlp.core.lib.imagemanager import ImageManager
515+from openlp.core.ui.slidecontroller import LiveController, PreviewController
516+
517+
518+def loader():
519+ """
520+ God class to load all the components which are registered with the Registry
521+
522+ :return: None
523+ """
524+ State().load_settings()
525+ MediaController()
526+ PluginManager()
527+ # Set up the path with plugins
528+ ImageManager()
529+ Renderer()
530+ # Create slide controllers
531+ PreviewController()
532+ LiveController()
533
534=== added file 'openlp/core/state.py'
535--- openlp/core/state.py 1970-01-01 00:00:00 +0000
536+++ openlp/core/state.py 2019-01-10 21:21:29 +0000
537@@ -0,0 +1,175 @@
538+# -*- coding: utf-8 -*-
539+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
540+
541+###############################################################################
542+# OpenLP - Open Source Lyrics Projection #
543+# --------------------------------------------------------------------------- #
544+# Copyright (c) 2008-2018 OpenLP Developers #
545+# --------------------------------------------------------------------------- #
546+# This program is free software; you can redistribute it and/or modify it #
547+# under the terms of the GNU General Public License as published by the Free #
548+# Software Foundation; version 2 of the License. #
549+# #
550+# This program is distributed in the hope that it will be useful, but WITHOUT #
551+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
552+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
553+# more details. #
554+# #
555+# You should have received a copy of the GNU General Public License along #
556+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
557+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
558+###############################################################################
559+
560+"""
561+The :mod:`core` module provides state management
562+
563+All the core functions of the OpenLP application including the GUI, settings, logging and a plugin framework are
564+contained within the openlp.core module.
565+"""
566+import logging
567+
568+from openlp.core.common.registry import Registry
569+from openlp.core.common.mixins import LogMixin
570+from openlp.core.lib.plugin import PluginStatus
571+
572+
573+log = logging.getLogger()
574+
575+
576+class StateModule(LogMixin):
577+ def __init__(self):
578+ """
579+ Holder of State information per module
580+ """
581+ super(StateModule, self).__init__()
582+ self.name = None
583+ self.order = 0
584+ self.is_plugin = None
585+ self.status = PluginStatus.Inactive
586+ self.pass_preconditions = False
587+ self.requires = None
588+ self.required_by = None
589+ self.text = None
590+
591+
592+class State(LogMixin):
593+
594+ __instance__ = None
595+
596+ def __new__(cls):
597+ """
598+ Re-implement the __new__ method to make sure we create a true singleton.
599+ """
600+ if not cls.__instance__:
601+ cls.__instance__ = object.__new__(cls)
602+ return cls.__instance__
603+
604+ def load_settings(self):
605+ self.modules = {}
606+
607+ def save_settings(self):
608+ pass
609+
610+ def add_service(self, name, order, is_plugin=False, status=PluginStatus.Active, requires=None):
611+ """
612+ Add a module to the array and load dependencies. There will only be one item per module
613+ :param name: Module name
614+ :param order: Order to display
615+ :param is_plugin: Am I a plugin
616+ :param status: The active status
617+ :param requires: Module name this requires
618+ :return:
619+ """
620+ if name not in self.modules:
621+ state = StateModule()
622+ state.name = name
623+ state.order = order
624+ state.is_plugin = is_plugin
625+ state.status = status
626+ state.requires = requires
627+ state.required_by = []
628+ self.modules[name] = state
629+ if requires and requires in self.modules:
630+ if requires not in self.modules[requires].required_by:
631+ self.modules[requires].required_by.append(name)
632+
633+ def missing_text(self, name, text):
634+ """
635+ Updates the preconditions state of a module
636+
637+ :param name: Module name
638+ :param text: Module missing text
639+ :return:
640+ """
641+ self.modules[name].text = text
642+
643+ def get_text(self):
644+ """
645+ return an string of error text
646+ :return: a string of text
647+ """
648+ error_text = ''
649+ for mod in self.modules:
650+ if self.modules[mod].text:
651+ error_text = error_text + self.modules[mod].text + '\n'
652+ return error_text
653+
654+ def update_pre_conditions(self, name, status):
655+ """
656+ Updates the preconditions state of a module
657+
658+ :param name: Module name
659+ :param status: Module new status
660+ :return:
661+ """
662+ self.modules[name].pass_preconditions = status
663+ if self.modules[name].is_plugin:
664+ plugin = Registry().get('{mod}_plugin'.format(mod=name))
665+ if status:
666+ self.log_debug('Plugin {plugin} active'.format(plugin=str(plugin.name)))
667+ plugin.set_status()
668+ else:
669+ plugin.status = PluginStatus.Disabled
670+
671+ def flush_preconditions(self):
672+ """
673+ Now all modules are loaded lets update all the preconditions.
674+
675+ :return:
676+ """
677+ for mods in self.modules:
678+ for req in self.modules[mods].required_by:
679+ self.modules[req].pass_preconditions = self.modules[mods].pass_preconditions
680+ plugins_list = sorted(self.modules, key=lambda state: self.modules[state].order)
681+ mdl = {}
682+ for pl in plugins_list:
683+ mdl[pl] = self.modules[pl]
684+ self.modules = mdl
685+
686+ def is_module_active(self, name):
687+ return self.modules[name].status == PluginStatus.Active
688+
689+ def check_preconditions(self, name):
690+ """
691+ Checks if a modules preconditions have been met.
692+
693+ :param name: Module name
694+ :return: Have the preconditions been met.
695+ :rtype: bool
696+ """
697+ if self.modules[name].requires is None:
698+ return self.modules[name].pass_preconditions
699+ else:
700+ mod = self.modules[name].requires
701+ return self.modules[mod].pass_preconditions
702+
703+ def list_plugins(self):
704+ """
705+ Return a list of plugins
706+ :return: an array of plugins
707+ """
708+ plugins = []
709+ for mod in self.modules:
710+ if self.modules[mod].is_plugin:
711+ plugins.append(Registry().get('{mod}_plugin'.format(mod=mod)))
712+ return plugins
713
714=== modified file 'openlp/core/ui/icons.py'
715--- openlp/core/ui/icons.py 2018-10-27 01:53:43 +0000
716+++ openlp/core/ui/icons.py 2019-01-10 21:21:29 +0000
717@@ -78,7 +78,7 @@
718 'book': {'icon': 'fa.book'},
719 'bottom': {'icon': 'fa.angle-double-down'},
720 'box': {'icon': 'fa.briefcase'},
721- 'clapperboard': {'icon': 'fa.chess-board'},
722+ 'clapperboard': {'icon': 'fa.film'},
723 'clock': {'icon': 'fa.clock-o'},
724 'clone': {'icon': 'fa.clone'},
725 'close': {'icon': 'fa.times-circle-o'},
726
727=== modified file 'openlp/core/ui/maindisplay.py'
728--- openlp/core/ui/maindisplay.py 2018-10-27 01:40:20 +0000
729+++ openlp/core/ui/maindisplay.py 2019-01-10 21:21:29 +0000
730@@ -30,7 +30,7 @@
731 import html
732 import logging
733
734-from PyQt5 import QtCore, QtWidgets, QtWebKit, QtWebKitWidgets, QtGui, QtMultimedia
735+from PyQt5 import QtCore, QtWidgets, QtWebKit, QtWebKitWidgets, QtGui
736
737 from openlp.core.common import is_macosx, is_win
738 from openlp.core.common.applocation import AppLocation
739@@ -148,10 +148,6 @@
740 self.override = {}
741 self.retranslateUi()
742 self.media_object = None
743- if self.is_live:
744- self.audio_player = AudioPlayer(self)
745- else:
746- self.audio_player = None
747 self.first_time = True
748 self.web_loaded = True
749 self.setStyleSheet(OPAQUE_STYLESHEET)
750@@ -604,106 +600,3 @@
751 """
752 self.web_view.setGeometry(0, 0, self.width(), self.height() - 1)
753 self.web_view.setGeometry(0, 0, self.width(), self.height())
754-
755-
756-class AudioPlayer(LogMixin, QtCore.QObject):
757- """
758- This Class will play audio only allowing components to work with a soundtrack independent of the user interface.
759- """
760- position_changed = QtCore.pyqtSignal(int)
761-
762- def __init__(self, parent):
763- """
764- The constructor for the display form.
765-
766- :param parent: The parent widget.
767- """
768- super(AudioPlayer, self).__init__(parent)
769- self.player = QtMultimedia.QMediaPlayer()
770- self.playlist = QtMultimedia.QMediaPlaylist(self.player)
771- self.volume_slider = None
772- self.player.setPlaylist(self.playlist)
773- self.player.positionChanged.connect(self._on_position_changed)
774-
775- def __del__(self):
776- """
777- Shutting down so clean up connections
778- """
779- self.stop()
780-
781- def _on_position_changed(self, position):
782- """
783- Emit a signal when the position of the media player updates
784- """
785- self.position_changed.emit(position)
786-
787- def set_volume_slider(self, slider):
788- """
789- Connect the volume slider to the media player
790- :param slider:
791- """
792- self.volume_slider = slider
793- self.volume_slider.setMinimum(0)
794- self.volume_slider.setMaximum(100)
795- self.volume_slider.setValue(self.player.volume())
796- self.volume_slider.valueChanged.connect(self.set_volume)
797-
798- def set_volume(self, volume):
799- """
800- Set the volume of the media player
801-
802- :param volume:
803- """
804- self.player.setVolume(volume)
805-
806- def reset(self):
807- """
808- Reset the audio player, clearing the playlist and the queue.
809- """
810- self.stop()
811- self.playlist.clear()
812-
813- def play(self):
814- """
815- We want to play the file so start it
816- """
817- self.player.play()
818-
819- def pause(self):
820- """
821- Pause the Audio
822- """
823- self.player.pause()
824-
825- def stop(self):
826- """
827- Stop the Audio and clean up
828- """
829- self.player.stop()
830-
831- def add_to_playlist(self, file_names):
832- """
833- Add another file to the playlist.
834-
835- :param file_names: A list with files to be added to the playlist.
836- """
837- if not isinstance(file_names, list):
838- file_names = [file_names]
839- for file_name in file_names:
840- self.playlist.addMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(str(file_name))))
841-
842- def next(self):
843- """
844- Skip forward to the next track in the list
845- """
846- self.playlist.next()
847-
848- def go_to(self, index):
849- """
850- Go to a particular track in the list
851-
852- :param index: The track to go to
853- """
854- self.playlist.setCurrentIndex(index)
855- if self.player.state() == QtMultimedia.QMediaPlayer.PlayingState:
856- self.player.play()
857
858=== modified file 'openlp/core/ui/mainwindow.py'
859--- openlp/core/ui/mainwindow.py 2018-10-27 01:53:43 +0000
860+++ openlp/core/ui/mainwindow.py 2019-01-10 21:21:29 +0000
861@@ -30,6 +30,7 @@
862
863 from PyQt5 import QtCore, QtGui, QtWidgets
864
865+from openlp.core.state import State
866 from openlp.core.api import websockets
867 from openlp.core.api.http import server
868 from openlp.core.common import is_win, is_macosx, add_actions
869@@ -41,11 +42,8 @@
870 from openlp.core.common.path import Path, copyfile, create_paths
871 from openlp.core.common.registry import Registry
872 from openlp.core.common.settings import Settings
873-from openlp.core.display.renderer import Renderer
874 from openlp.core.display.screens import ScreenList
875-from openlp.core.lib.imagemanager import ImageManager
876 from openlp.core.lib.plugin import PluginStatus
877-from openlp.core.lib.pluginmanager import PluginManager
878 from openlp.core.lib.ui import create_action
879 from openlp.core.projectors.manager import ProjectorManager
880 from openlp.core.ui.shortcutlistform import ShortcutListForm
881@@ -54,10 +52,8 @@
882 from openlp.core.ui.servicemanager import ServiceManager
883 from openlp.core.ui.aboutform import AboutForm
884 from openlp.core.ui.pluginform import PluginForm
885-from openlp.core.ui.slidecontroller import LiveController, PreviewController
886 from openlp.core.ui.settingsform import SettingsForm
887 from openlp.core.ui.firsttimeform import FirstTimeForm
888-from openlp.core.ui.media.mediacontroller import MediaController
889 from openlp.core.ui.printserviceform import PrintServiceForm
890 from openlp.core.ui.style import PROGRESSBAR_STYLE, get_library_stylesheet
891 from openlp.core.version import get_version
892@@ -90,9 +86,6 @@
893 self.control_splitter.setOrientation(QtCore.Qt.Horizontal)
894 self.control_splitter.setObjectName('control_splitter')
895 self.main_content_layout.addWidget(self.control_splitter)
896- # Create slide controllers
897- PreviewController(self)
898- LiveController(self)
899 preview_visible = Settings().value('user interface/preview panel')
900 live_visible = Settings().value('user interface/live panel')
901 panel_locked = Settings().value('user interface/lock panel')
902@@ -501,16 +494,11 @@
903 self.copy_data = False
904 Settings().set_up_default_values()
905 self.about_form = AboutForm(self)
906- MediaController()
907 self.ws_server = websockets.WebSocketServer()
908 self.http_server = server.HttpServer(self)
909 SettingsForm(self)
910 self.formatting_tag_form = FormattingTagForm(self)
911 self.shortcut_form = ShortcutListForm(self)
912- # Set up the path with plugins
913- PluginManager(self)
914- ImageManager()
915- Renderer()
916 # Set up the interface
917 self.setupUi(self)
918 # Define the media Dock Manager
919@@ -660,22 +648,12 @@
920 self.set_view_mode(False, True, False, False, True, True)
921 self.mode_live_item.setChecked(True)
922
923- def app_startup(self):
924- """
925- Give all the plugins a chance to perform some tasks at startup
926- """
927- self.application.process_events()
928- for plugin in self.plugin_manager.plugins:
929- if plugin.is_active():
930- plugin.app_startup()
931- self.application.process_events()
932-
933 def first_time(self):
934 """
935 Import themes if first time
936 """
937 self.application.process_events()
938- for plugin in self.plugin_manager.plugins:
939+ for plugin in State().list_plugins():
940 if hasattr(plugin, 'first_time'):
941 self.application.process_events()
942 plugin.first_time()
943@@ -713,7 +691,7 @@
944 self.projector_manager_dock.setVisible(True)
945 else:
946 self.projector_manager_dock.setVisible(False)
947- for plugin in self.plugin_manager.plugins:
948+ for plugin in State().list_plugins():
949 self.active_plugin = plugin
950 old_status = self.active_plugin.status
951 self.active_plugin.set_status()
952@@ -887,7 +865,7 @@
953 setting_sections.extend([self.header_section])
954 setting_sections.extend(['crashreport'])
955 # Add plugin sections.
956- setting_sections.extend([plugin.name for plugin in self.plugin_manager.plugins])
957+ setting_sections.extend([plugin.name for plugin in State().list_plugins()])
958 # Copy the settings file to the tmp dir, because we do not want to change the original one.
959 temp_dir_path = Path(gettempdir(), 'openlp')
960 create_paths(temp_dir_path)
961
962=== modified file 'openlp/core/ui/media/__init__.py'
963--- openlp/core/ui/media/__init__.py 2018-10-27 01:40:20 +0000
964+++ openlp/core/ui/media/__init__.py 2019-01-10 21:21:29 +0000
965@@ -24,10 +24,6 @@
966 """
967 import logging
968
969-from PyQt5 import QtCore
970-
971-from openlp.core.common.settings import Settings
972-
973 log = logging.getLogger(__name__ + '.__init__')
974
975
976@@ -54,7 +50,7 @@
977 Folder = 5
978
979
980-class MediaInfo(object):
981+class ItemMediaInfo(object):
982 """
983 This class hold the media related info
984 """
985@@ -73,39 +69,6 @@
986 media_type = MediaType()
987
988
989-def get_media_players():
990- """
991- This method extracts the configured media players and overridden player
992- from the settings.
993- """
994- log.debug('get_media_players')
995- saved_players = Settings().value('media/players')
996- reg_ex = QtCore.QRegExp(r'.*\[(.*)\].*')
997- if Settings().value('media/override player') == QtCore.Qt.Checked:
998- if reg_ex.exactMatch(saved_players):
999- overridden_player = '{text}'.format(text=reg_ex.cap(1))
1000- else:
1001- overridden_player = 'auto'
1002- else:
1003- overridden_player = ''
1004- saved_players_list = saved_players.replace('[', '').replace(']', '').split(',') if saved_players else []
1005- return saved_players_list, overridden_player
1006-
1007-
1008-def set_media_players(players_list, overridden_player='auto'):
1009- """
1010- This method saves the configured media players and overridden player to the settings
1011-
1012- :param players_list: A list with all active media players.
1013- :param overridden_player: Here an special media player is chosen for all media actions.
1014- """
1015- log.debug('set_media_players')
1016- players = ','.join(players_list)
1017- if Settings().value('media/override player') == QtCore.Qt.Checked and overridden_player != 'auto':
1018- players = players.replace(overridden_player, '[{text}]'.format(text=overridden_player))
1019- Settings().setValue('media/players', players)
1020-
1021-
1022 def parse_optical_path(input_string):
1023 """
1024 Split the optical path info.
1025
1026=== modified file 'openlp/core/ui/media/mediacontroller.py'
1027--- openlp/core/ui/media/mediacontroller.py 2018-08-25 14:08:19 +0000
1028+++ openlp/core/ui/media/mediacontroller.py 2019-01-10 21:21:29 +0000
1029@@ -25,13 +25,19 @@
1030 """
1031 import datetime
1032 import logging
1033-import os
1034-
1035+
1036+try:
1037+ from pymediainfo import MediaInfo
1038+ pymediainfo_available = True
1039+except ImportError:
1040+ pymediainfo_available = False
1041+
1042+from subprocess import check_output
1043 from PyQt5 import QtCore, QtWidgets
1044
1045+from openlp.core.state import State
1046 from openlp.core.api.http import register_endpoint
1047-from openlp.core.common import extension_loader
1048-from openlp.core.common.i18n import UiStrings, translate
1049+from openlp.core.common.i18n import translate
1050 from openlp.core.common.mixins import LogMixin, RegistryProperties
1051 from openlp.core.common.registry import Registry, RegistryBase
1052 from openlp.core.common.settings import Settings
1053@@ -39,11 +45,9 @@
1054 from openlp.core.lib.ui import critical_error_message_box
1055 from openlp.core.ui import DisplayControllerType
1056 from openlp.core.ui.icons import UiIcons
1057-from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players, \
1058- parse_optical_path
1059+from openlp.core.ui.media import MediaState, ItemMediaInfo, MediaType, parse_optical_path
1060 from openlp.core.ui.media.endpoint import media_endpoint
1061-from openlp.core.ui.media.mediaplayer import MediaPlayer
1062-from openlp.core.ui.media.vendor.mediainfoWrapper import MediaInfoWrapper
1063+from openlp.core.ui.media.vlcplayer import VlcPlayer, get_vlc
1064 from openlp.core.widgets.toolbar import OpenLPToolbar
1065
1066 log = logging.getLogger(__name__)
1067@@ -62,7 +66,6 @@
1068 super(MediaSlider, self).__init__(direction)
1069 self.manager = manager
1070 self.controller = controller
1071- self.no_matching_player = translate('MediaPlugin.MediaItem', 'File %s not supported using player %s')
1072
1073 def mouseMoveEvent(self, event):
1074 """
1075@@ -77,7 +80,6 @@
1076 def mousePressEvent(self, event):
1077 """
1078 Mouse Press event no new functionality
1079-
1080 :param event: The triggering event
1081 """
1082 QtWidgets.QSlider.mousePressEvent(self, event)
1083@@ -110,7 +112,9 @@
1084 Constructor
1085 """
1086 super(MediaController, self).__init__(parent)
1087- self.media_players = {}
1088+
1089+ def setup(self):
1090+ self.vlc_player = None
1091 self.display_controllers = {}
1092 self.current_media_players = {}
1093 # Timer for video state
1094@@ -134,70 +138,40 @@
1095 Registry().register_function('songs_hide', self.media_hide)
1096 Registry().register_function('songs_blank', self.media_blank)
1097 Registry().register_function('songs_unblank', self.media_unblank)
1098- Registry().register_function('mediaitem_media_rebuild', self._set_active_players)
1099 Registry().register_function('mediaitem_suffixes', self._generate_extensions_lists)
1100 register_endpoint(media_endpoint)
1101
1102- def _set_active_players(self):
1103- """
1104- Set the active players and available media files
1105- """
1106- saved_players = get_media_players()[0]
1107- for player in list(self.media_players.keys()):
1108- self.media_players[player].is_active = player in saved_players
1109-
1110 def _generate_extensions_lists(self):
1111 """
1112 Set the active players and available media files
1113 """
1114 suffix_list = []
1115 self.audio_extensions_list = []
1116- for player in list(self.media_players.values()):
1117- if player.is_active:
1118- for item in player.audio_extensions_list:
1119- if item not in self.audio_extensions_list:
1120- self.audio_extensions_list.append(item)
1121- suffix_list.append(item[2:])
1122+ if self.vlc_player.is_active:
1123+ for item in self.vlc_player.audio_extensions_list:
1124+ if item not in self.audio_extensions_list:
1125+ self.audio_extensions_list.append(item)
1126+ suffix_list.append(item[2:])
1127 self.video_extensions_list = []
1128- for player in list(self.media_players.values()):
1129- if player.is_active:
1130- for item in player.video_extensions_list:
1131- if item not in self.video_extensions_list:
1132- self.video_extensions_list.append(item)
1133- suffix_list.append(item[2:])
1134+ if self.vlc_player.is_active:
1135+ for item in self.vlc_player.video_extensions_list:
1136+ if item not in self.video_extensions_list:
1137+ self.video_extensions_list.append(item)
1138+ suffix_list.append(item[2:])
1139 self.service_manager.supported_suffixes(suffix_list)
1140
1141- def register_players(self, player):
1142- """
1143- Register each media Player (Webkit, Phonon, etc) and store
1144- for later use
1145-
1146- :param player: Individual player class which has been enabled
1147- """
1148- self.media_players[player.name] = player
1149-
1150 def bootstrap_initialise(self):
1151 """
1152 Check to see if we have any media Player's available.
1153 """
1154- controller_dir = os.path.join('core', 'ui', 'media')
1155- # Find all files that do not begin with '.' (lp:#1738047) and end with player.py
1156- glob_pattern = os.path.join(controller_dir, '[!.]*player.py')
1157- extension_loader(glob_pattern, ['mediaplayer.py'])
1158- player_classes = MediaPlayer.__subclasses__()
1159- for player_class in player_classes:
1160- self.register_players(player_class(self))
1161- if not self.media_players:
1162- return False
1163- saved_players, overridden_player = get_media_players()
1164- invalid_media_players = \
1165- [media_player for media_player in saved_players if media_player not in self.media_players or
1166- not self.media_players[media_player].check_available()]
1167- if invalid_media_players:
1168- for invalidPlayer in invalid_media_players:
1169- saved_players.remove(invalidPlayer)
1170- set_media_players(saved_players, overridden_player)
1171- self._set_active_players()
1172+ self.setup()
1173+ self.vlc_player = VlcPlayer(self)
1174+ State().add_service("mediacontroller", 0)
1175+ if get_vlc() and pymediainfo_available:
1176+ State().update_pre_conditions("mediacontroller", True)
1177+ else:
1178+ State().missing_text("mediacontroller", translate('OpenLP.SlideController',
1179+ "VLC or pymediainfo are missing, so you are unable to play any media"))
1180 self._generate_extensions_lists()
1181 return True
1182
1183@@ -235,36 +209,6 @@
1184 if self.display_controllers[DisplayControllerType.Preview].media_info.can_loop_playback:
1185 self.media_play(self.display_controllers[DisplayControllerType.Preview], True)
1186
1187- def get_media_display_css(self):
1188- """
1189- Add css style sheets to htmlbuilder
1190- """
1191- css = ''
1192- for player in list(self.media_players.values()):
1193- if player.is_active:
1194- css += player.get_media_display_css()
1195- return css
1196-
1197- def get_media_display_javascript(self):
1198- """
1199- Add javascript functions to htmlbuilder
1200- """
1201- js = ''
1202- for player in list(self.media_players.values()):
1203- if player.is_active:
1204- js += player.get_media_display_javascript()
1205- return js
1206-
1207- def get_media_display_html(self):
1208- """
1209- Add html code to htmlbuilder
1210- """
1211- html = ''
1212- for player in list(self.media_players.values()):
1213- if player.is_active:
1214- html += player.get_media_display_html()
1215- return html
1216-
1217 def register_controller(self, controller):
1218 """
1219 Registers media controls where the players will be placed to run.
1220@@ -280,7 +224,7 @@
1221
1222 :param controller: First element is the controller which should be used
1223 """
1224- controller.media_info = MediaInfo()
1225+ controller.media_info = ItemMediaInfo()
1226 # Build a Media ToolBar
1227 controller.mediabar = OpenLPToolbar(controller)
1228 controller.mediabar.add_toolbar_action('playbackPlay', text='media_playback_play',
1229@@ -344,16 +288,12 @@
1230 """
1231 # clean up possible running old media files
1232 self.finalise()
1233- # update player status
1234- self._set_active_players()
1235 display.has_audio = True
1236 if display.is_live and preview:
1237 return
1238 if preview:
1239 display.has_audio = False
1240- for player in list(self.media_players.values()):
1241- if player.is_active:
1242- player.setup(display)
1243+ self.vlc_player.setup(display)
1244
1245 def set_controls_visible(self, controller, value):
1246 """
1247@@ -366,8 +306,7 @@
1248 controller.mediabar.setVisible(value)
1249 if controller.is_live and controller.display:
1250 if self.current_media_players and value:
1251- if self.current_media_players[controller.controller_type] != self.media_players['webkit']:
1252- controller.display.set_transparency(False)
1253+ controller.display.set_transparency(False)
1254
1255 @staticmethod
1256 def resize(display, player):
1257@@ -388,16 +327,19 @@
1258 :param hidden: The player which is doing the playing
1259 :param video_behind_text: Is the video to be played behind text.
1260 """
1261- is_valid = False
1262+ is_valid = True
1263 controller = self.display_controllers[source]
1264 # stop running videos
1265 self.media_reset(controller)
1266- controller.media_info = MediaInfo()
1267+ controller.media_info = ItemMediaInfo()
1268 controller.media_info.volume = controller.volume_slider.value()
1269 controller.media_info.is_background = video_behind_text
1270 # background will always loop video.
1271 controller.media_info.can_loop_playback = video_behind_text
1272- controller.media_info.file_info = QtCore.QFileInfo(service_item.get_frame_path())
1273+ if service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
1274+ controller.media_info.file_info = service_item.background_audio
1275+ else:
1276+ controller.media_info.file_info = [service_item.get_frame_path()]
1277 display = self._define_display(controller)
1278 if controller.is_live:
1279 # if this is an optical device use special handling
1280@@ -410,7 +352,7 @@
1281 else:
1282 log.debug('video is not optical and live')
1283 controller.media_info.length = service_item.media_length
1284- is_valid = self._check_file_type(controller, display, service_item)
1285+ is_valid = self._check_file_type(controller, display)
1286 display.override['theme'] = ''
1287 display.override['video'] = True
1288 if controller.media_info.is_background:
1289@@ -430,7 +372,7 @@
1290 else:
1291 log.debug('video is not optical and preview')
1292 controller.media_info.length = service_item.media_length
1293- is_valid = self._check_file_type(controller, display, service_item)
1294+ is_valid = self._check_file_type(controller, display)
1295 if not is_valid:
1296 # Media could not be loaded correctly
1297 critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
1298@@ -461,19 +403,21 @@
1299 return True
1300
1301 @staticmethod
1302- def media_length(service_item):
1303+ def media_length(media_path):
1304 """
1305 Uses Media Info to obtain the media length
1306
1307- :param service_item: The ServiceItem containing the details to be played.
1308+ :param media_path: The file path to be checked..
1309 """
1310- media_info = MediaInfo()
1311- media_info.volume = 0
1312- media_info.file_info = QtCore.QFileInfo(service_item.get_frame_path())
1313- media_data = MediaInfoWrapper.parse(service_item.get_frame_path())
1314+ if MediaInfo.can_parse():
1315+ media_data = MediaInfo.parse(media_path)
1316+ else:
1317+ xml = check_output(['mediainfo', '-f', '--Output=XML', '--Inform=OLDXML', media_path])
1318+ if not xml.startswith(b'<?xml'):
1319+ xml = check_output(['mediainfo', '-f', '--Output=XML', media_path])
1320+ media_data = MediaInfo(xml.decode("utf-8"))
1321 # duration returns in milli seconds
1322- service_item.set_media_length(media_data.tracks[0].duration)
1323- return True
1324+ return media_data.tracks[0].duration
1325
1326 def media_setup_optical(self, filename, title, audio_track, subtitle_track, start, end, display, controller):
1327 """
1328@@ -492,7 +436,7 @@
1329 # stop running videos
1330 self.media_reset(controller)
1331 # Setup media info
1332- controller.media_info = MediaInfo()
1333+ controller.media_info = ItemMediaInfo()
1334 controller.media_info.file_info = QtCore.QFileInfo(filename)
1335 if audio_track == -1 and subtitle_track == -1:
1336 controller.media_info.media_type = MediaType.CD
1337@@ -507,86 +451,49 @@
1338 # When called from mediaitem display is None
1339 if display is None:
1340 display = controller.preview_display
1341- # Find vlc player
1342- used_players = get_media_players()[0]
1343- vlc_player = None
1344- for title in used_players:
1345- player = self.media_players[title]
1346- if player.name == 'vlc':
1347- vlc_player = player
1348- if vlc_player is None:
1349- critical_error_message_box(translate('MediaPlugin.MediaItem', 'VLC player required'),
1350- translate('MediaPlugin.MediaItem',
1351- 'VLC player required for playback of optical devices'))
1352- return False
1353- vlc_player.load(display)
1354- self.resize(display, vlc_player)
1355- self.current_media_players[controller.controller_type] = vlc_player
1356+ self.vlc_player.load(display)
1357+ self.resize(display, self.vlc_player)
1358+ self.current_media_players[controller.controller_type] = self.vlc_player
1359 if audio_track == -1 and subtitle_track == -1:
1360 controller.media_info.media_type = MediaType.CD
1361 else:
1362 controller.media_info.media_type = MediaType.DVD
1363 return True
1364
1365- @staticmethod
1366- def _get_used_players(service_item):
1367- """
1368- Find the player for a given service item
1369-
1370- :param service_item: where the information is about the media and required player
1371- :return: player description
1372- """
1373- used_players = get_media_players()[0]
1374- # If no player, we can't play
1375- if not used_players:
1376- return False
1377- default_player = [used_players[0]]
1378- if service_item.processor and service_item.processor != UiStrings().Automatic:
1379- # check to see if the player is usable else use the default one.
1380- if service_item.processor.lower() not in used_players:
1381- used_players = default_player
1382- else:
1383- used_players = [service_item.processor.lower()]
1384- return used_players
1385-
1386- def _check_file_type(self, controller, display, service_item):
1387+ def _check_file_type(self, controller, display):
1388 """
1389 Select the correct media Player type from the prioritized Player list
1390
1391 :param controller: First element is the controller which should be used
1392 :param display: Which display to use
1393- :param service_item: The ServiceItem containing the details to be played.
1394 """
1395- used_players = self._get_used_players(service_item)
1396- if controller.media_info.file_info.isFile():
1397- suffix = '*.%s' % controller.media_info.file_info.suffix().lower()
1398- for title in used_players:
1399- if not title:
1400- continue
1401- player = self.media_players[title]
1402+ for file in controller.media_info.file_info:
1403+ if file.is_file:
1404+ suffix = '*%s' % file.suffix.lower()
1405+ player = self.vlc_player
1406+ file = str(file)
1407 if suffix in player.video_extensions_list:
1408 if not controller.media_info.is_background or controller.media_info.is_background and \
1409 player.can_background:
1410 self.resize(display, player)
1411- if player.load(display):
1412+ if player.load(display, file):
1413 self.current_media_players[controller.controller_type] = player
1414 controller.media_info.media_type = MediaType.Video
1415 return True
1416 if suffix in player.audio_extensions_list:
1417- if player.load(display):
1418+ if player.load(display, file):
1419 self.current_media_players[controller.controller_type] = player
1420 controller.media_info.media_type = MediaType.Audio
1421 return True
1422- else:
1423- for title in used_players:
1424- player = self.media_players[title]
1425+ else:
1426+ player = self.vlc_player
1427+ file = str(file)
1428 if player.can_folder:
1429 self.resize(display, player)
1430- if player.load(display):
1431+ if player.load(display, file):
1432 self.current_media_players[controller.controller_type] = player
1433 controller.media_info.media_type = MediaType.Video
1434 return True
1435- # no valid player found
1436 return False
1437
1438 def media_play_msg(self, msg, status=True):
1439
1440=== modified file 'openlp/core/ui/media/mediaplayer.py'
1441--- openlp/core/ui/media/mediaplayer.py 2017-12-29 09:15:48 +0000
1442+++ openlp/core/ui/media/mediaplayer.py 2019-01-10 21:21:29 +0000
1443@@ -60,11 +60,12 @@
1444 """
1445 pass
1446
1447- def load(self, display):
1448+ def load(self, display, file):
1449 """
1450 Load a new media file and check if it is valid
1451
1452 :param display: The display to be updated.
1453+ :param file: The file to be loaded
1454 """
1455 return True
1456
1457
1458=== modified file 'openlp/core/ui/media/playertab.py'
1459--- openlp/core/ui/media/playertab.py 2018-08-25 14:08:19 +0000
1460+++ openlp/core/ui/media/playertab.py 2019-01-10 21:21:29 +0000
1461@@ -32,7 +32,6 @@
1462 from openlp.core.lib.settingstab import SettingsTab
1463 from openlp.core.lib.ui import create_button
1464 from openlp.core.ui.icons import UiIcons
1465-from openlp.core.ui.media import get_media_players, set_media_players
1466 from openlp.core.widgets.buttons import ColorButton
1467
1468
1469@@ -202,7 +201,7 @@
1470 """
1471 if self.saved_used_players:
1472 self.used_players = self.saved_used_players
1473- self.used_players = get_media_players()[0]
1474+ # self.used_players = get_media_players()[0]
1475 self.saved_used_players = self.used_players
1476 settings = Settings()
1477 settings.beginGroup(self.settings_section)
1478@@ -220,13 +219,13 @@
1479 settings.beginGroup(self.settings_section)
1480 settings.setValue('background color', self.background_color)
1481 settings.endGroup()
1482- old_players, override_player = get_media_players()
1483- if self.used_players != old_players:
1484- # clean old Media stuff
1485- set_media_players(self.used_players, override_player)
1486- self.settings_form.register_post_process('mediaitem_suffix_reset')
1487- self.settings_form.register_post_process('mediaitem_media_rebuild')
1488- self.settings_form.register_post_process('config_screen_changed')
1489+ # old_players, override_player = get_media_players()
1490+ # if self.used_players != old_players:
1491+ # # clean old Media stuff
1492+ # set_media_players(self.used_players, override_player)
1493+ # self.settings_form.register_post_process('mediaitem_suffix_reset')
1494+ # self.settings_form.register_post_process('mediaitem_media_rebuild')
1495+ # self.settings_form.register_post_process('config_screen_changed')
1496
1497 def post_set_up(self, post_update=False):
1498 """
1499
1500=== removed file 'openlp/core/ui/media/vendor/mediainfoWrapper.py'
1501--- openlp/core/ui/media/vendor/mediainfoWrapper.py 2018-10-27 01:40:20 +0000
1502+++ openlp/core/ui/media/vendor/mediainfoWrapper.py 1970-01-01 00:00:00 +0000
1503@@ -1,128 +0,0 @@
1504-# -*- coding: utf-8 -*-
1505-# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
1506-
1507-###############################################################################
1508-# OpenLP - Open Source Lyrics Projection #
1509-# --------------------------------------------------------------------------- #
1510-# Copyright (c) 2008-2018 OpenLP Developers #
1511-# --------------------------------------------------------------------------- #
1512-# This program is free software; you can redistribute it and/or modify it #
1513-# under the terms of the GNU General Public License as published by the Free #
1514-# Software Foundation; version 2 of the License. #
1515-# #
1516-# This program is distributed in the hope that it will be useful, but WITHOUT #
1517-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
1518-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
1519-# more details. #
1520-# #
1521-# You should have received a copy of the GNU General Public License along #
1522-# with this program; if not, write to the Free Software Foundation, Inc., 59 #
1523-# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
1524-###############################################################################
1525-"""
1526-The :mod:`~openlp.core.ui.media.mediainfo` module contains code to run mediainfo on a media file and obtain
1527-information related to the rwquested media.
1528-"""
1529-import json
1530-import os
1531-from subprocess import check_output
1532-
1533-from bs4 import BeautifulSoup, NavigableString
1534-
1535-ENV_DICT = os.environ
1536-
1537-
1538-class Track(object):
1539-
1540- def __getattribute__(self, name):
1541- try:
1542- return object.__getattribute__(self, name)
1543- except Exception:
1544- pass
1545- return None
1546-
1547- def __init__(self, xml_dom_fragment):
1548- self.xml_dom_fragment = xml_dom_fragment
1549- self.track_type = xml_dom_fragment.attrs['type']
1550- for el in self.xml_dom_fragment.children:
1551- if not isinstance(el, NavigableString):
1552- node_name = el.name.lower().strip().strip('_')
1553- if node_name == 'id':
1554- node_name = 'track_id'
1555- node_value = el.string
1556- other_node_name = "other_%s" % node_name
1557- if getattr(self, node_name) is None:
1558- setattr(self, node_name, node_value)
1559- else:
1560- if getattr(self, other_node_name) is None:
1561- setattr(self, other_node_name, [node_value, ])
1562- else:
1563- getattr(self, other_node_name).append(node_value)
1564-
1565- for o in [d for d in self.__dict__.keys() if d.startswith('other_')]:
1566- try:
1567- primary = o.replace('other_', '')
1568- setattr(self, primary, int(getattr(self, primary)))
1569- except Exception:
1570- for v in getattr(self, o):
1571- try:
1572- current = getattr(self, primary)
1573- setattr(self, primary, int(v))
1574- getattr(self, o).append(current)
1575- break
1576- except Exception:
1577- pass
1578-
1579- def __repr__(self):
1580- return "<Track track_id='{0}', track_type='{1}'>".format(self.track_id, self.track_type)
1581-
1582- def to_data(self):
1583- data = {}
1584- for k, v in self.__dict__.items():
1585- if k != 'xml_dom_fragment':
1586- data[k] = v
1587- return data
1588-
1589-
1590-class MediaInfoWrapper(object):
1591-
1592- def __init__(self, xml):
1593- self.xml_dom = xml
1594- xml_types = (str,) # no unicode type in python3
1595- if isinstance(xml, xml_types):
1596- self.xml_dom = MediaInfoWrapper.parse_xml_data_into_dom(xml)
1597-
1598- @staticmethod
1599- def parse_xml_data_into_dom(xml_data):
1600- return BeautifulSoup(xml_data, "xml")
1601-
1602- @staticmethod
1603- def parse(filename, environment=ENV_DICT):
1604- xml = check_output(['mediainfo', '-f', '--Output=XML', '--Inform=OLDXML', filename])
1605- if not xml.startswith(b'<?xml'):
1606- xml = check_output(['mediainfo', '-f', '--Output=XML', filename])
1607- xml_dom = MediaInfoWrapper.parse_xml_data_into_dom(xml)
1608- return MediaInfoWrapper(xml_dom)
1609-
1610- def _populate_tracks(self):
1611- if self.xml_dom is None:
1612- return
1613- for xml_track in self.xml_dom.Mediainfo.File.find_all("track"):
1614- self._tracks.append(Track(xml_track))
1615-
1616- @property
1617- def tracks(self):
1618- if not hasattr(self, "_tracks"):
1619- self._tracks = []
1620- if len(self._tracks) == 0:
1621- self._populate_tracks()
1622- return self._tracks
1623-
1624- def to_data(self):
1625- data = {'tracks': []}
1626- for track in self.tracks:
1627- data['tracks'].append(track.to_data())
1628- return data
1629-
1630- def to_json(self):
1631- return json.dumps(self.to_data())
1632
1633=== modified file 'openlp/core/ui/media/vendor/vlc.py'
1634--- openlp/core/ui/media/vendor/vlc.py 2017-12-28 08:27:44 +0000
1635+++ openlp/core/ui/media/vendor/vlc.py 2019-01-10 21:21:29 +0000
1636@@ -1,8 +1,9 @@
1637 #! /usr/bin/python
1638+# -*- coding: utf-8 -*-
1639
1640 # Python ctypes bindings for VLC
1641 #
1642-# Copyright (C) 2009-2012 the VideoLAN team
1643+# Copyright (C) 2009-2017 the VideoLAN team
1644 # $Id: $
1645 #
1646 # Authors: Olivier Aubert <contact at olivieraubert.net>
1647@@ -27,7 +28,7 @@
1648 U{http://wiki.videolan.org/LibVLC}.
1649
1650 You can find the documentation and a README file with some examples
1651-at U{http://www.advene.org/download/python-ctypes/}.
1652+at U{http://www.olivieraubert.net/vlc/python-ctypes/}.
1653
1654 Basically, the most important class is L{Instance}, which is used
1655 to create a libvlc instance. From this instance, you then create
1656@@ -40,15 +41,21 @@
1657 """
1658
1659 import ctypes
1660-import functools
1661+from ctypes.util import find_library
1662 import os
1663 import sys
1664-from ctypes.util import find_library
1665+import functools
1666+
1667 # Used by EventManager in override.py
1668 from inspect import getargspec
1669
1670-__version__ = "N/A"
1671-build_date = "Mon Jan 25 19:40:05 2016"
1672+import logging
1673+logger = logging.getLogger(__name__)
1674+
1675+__version__ = "3.0.3104"
1676+__libvlc_version__ = "3.0.3"
1677+__generator_version__ = "1.4"
1678+build_date = "Fri Jul 13 15:18:27 2018 3.0.3"
1679
1680 # The libvlc doc states that filenames are expected to be in UTF8, do
1681 # not rely on sys.getfilesystemencoding() which will be confused,
1682@@ -104,7 +111,19 @@
1683
1684 def find_lib():
1685 dll = None
1686- plugin_path = None
1687+ plugin_path = os.environ.get('PYTHON_VLC_MODULE_PATH', None)
1688+ if 'PYTHON_VLC_LIB_PATH' in os.environ:
1689+ try:
1690+ dll = ctypes.CDLL(os.environ['PYTHON_VLC_LIB_PATH'])
1691+ except OSError:
1692+ logger.error("Cannot load lib specified by PYTHON_VLC_LIB_PATH env. variable")
1693+ sys.exit(1)
1694+ if plugin_path and not os.path.isdir(plugin_path):
1695+ logger.error("Invalid PYTHON_VLC_MODULE_PATH specified. Please fix.")
1696+ sys.exit(1)
1697+ if dll is not None:
1698+ return dll, plugin_path
1699+
1700 if sys.platform.startswith('linux'):
1701 p = find_library('vlc')
1702 try:
1703@@ -112,7 +131,8 @@
1704 except OSError: # may fail
1705 dll = ctypes.CDLL('libvlc.so.5')
1706 elif sys.platform.startswith('win'):
1707- p = find_library('libvlc.dll')
1708+ libname = 'libvlc.dll'
1709+ p = find_library(libname)
1710 if p is None:
1711 try: # some registry settings
1712 # leaner than win32api, win32con
1713@@ -131,10 +151,14 @@
1714 except ImportError: # no PyWin32
1715 pass
1716 if plugin_path is None:
1717- # try some standard locations.
1718- for p in ('Program Files\\VideoLan\\', 'VideoLan\\',
1719- 'Program Files\\', ''):
1720- p = 'C:\\' + p + 'VLC\\libvlc.dll'
1721+ # try some standard locations.
1722+ programfiles = os.environ["ProgramFiles"]
1723+ homedir = os.environ["HOMEDRIVE"]
1724+ for p in ('{programfiles}\\VideoLan{libname}', '{homedir}:\\VideoLan{libname}',
1725+ '{programfiles}{libname}', '{homedir}:{libname}'):
1726+ p = p.format(homedir = homedir,
1727+ programfiles = programfiles,
1728+ libname = '\\VLC\\' + libname)
1729 if os.path.exists(p):
1730 plugin_path = os.path.dirname(p)
1731 break
1732@@ -142,11 +166,11 @@
1733 p = os.getcwd()
1734 os.chdir(plugin_path)
1735 # if chdir failed, this will raise an exception
1736- dll = ctypes.CDLL('libvlc.dll')
1737+ dll = ctypes.CDLL(libname)
1738 # restore cwd after dll has been loaded
1739 os.chdir(p)
1740 else: # may fail
1741- dll = ctypes.CDLL('libvlc.dll')
1742+ dll = ctypes.CDLL(libname)
1743 else:
1744 plugin_path = os.path.dirname(p)
1745 dll = ctypes.CDLL(p)
1746@@ -154,13 +178,20 @@
1747 elif sys.platform.startswith('darwin'):
1748 # FIXME: should find a means to configure path
1749 d = '/Applications/VLC.app/Contents/MacOS/'
1750+ c = d + 'lib/libvlccore.dylib'
1751 p = d + 'lib/libvlc.dylib'
1752- if os.path.exists(p):
1753+ if os.path.exists(p) and os.path.exists(c):
1754+ # pre-load libvlccore VLC 2.2.8+
1755+ ctypes.CDLL(c)
1756 dll = ctypes.CDLL(p)
1757- d += 'modules'
1758- if os.path.isdir(d):
1759- plugin_path = d
1760- else: # hope, some PATH is set...
1761+ for p in ('modules', 'plugins'):
1762+ p = d + p
1763+ if os.path.isdir(p):
1764+ plugin_path = p
1765+ break
1766+ else: # hope, some [DY]LD_LIBRARY_PATH is set...
1767+ # pre-load libvlccore VLC 2.2.8+
1768+ ctypes.CDLL('libvlccore.dylib')
1769 dll = ctypes.CDLL('libvlc.dylib')
1770
1771 else:
1772@@ -292,6 +323,8 @@
1773 def from_param(self, param):
1774 if isinstance(param, _Seqs):
1775 return (self.etype * len(param))(*param)
1776+ else:
1777+ return ctypes.POINTER(param)
1778
1779 # errcheck functions for some native functions.
1780 def string_result(result, func, arguments):
1781@@ -393,6 +426,37 @@
1782 LogLevel.NOTICE = LogLevel(2)
1783 LogLevel.WARNING = LogLevel(3)
1784
1785+class MediaDiscovererCategory(_Enum):
1786+ '''Category of a media discoverer
1787+See libvlc_media_discoverer_list_get().
1788+ '''
1789+ _enum_names_ = {
1790+ 0: 'devices',
1791+ 1: 'lan',
1792+ 2: 'podcasts',
1793+ 3: 'localdirs',
1794+ }
1795+MediaDiscovererCategory.devices = MediaDiscovererCategory(0)
1796+MediaDiscovererCategory.lan = MediaDiscovererCategory(1)
1797+MediaDiscovererCategory.localdirs = MediaDiscovererCategory(3)
1798+MediaDiscovererCategory.podcasts = MediaDiscovererCategory(2)
1799+
1800+class DialogQuestionType(_Enum):
1801+ '''@defgroup libvlc_dialog libvlc dialog
1802+@ingroup libvlc
1803+@{
1804+@file
1805+libvlc dialog external api.
1806+ '''
1807+ _enum_names_ = {
1808+ 0: 'NORMAL',
1809+ 1: 'WARNING',
1810+ 2: 'CRITICAL',
1811+ }
1812+DialogQuestionType.CRITICAL = DialogQuestionType(2)
1813+DialogQuestionType.NORMAL = DialogQuestionType(0)
1814+DialogQuestionType.WARNING = DialogQuestionType(1)
1815+
1816 class EventType(_Enum):
1817 '''Event types.
1818 '''
1819@@ -424,10 +488,21 @@
1820 273: 'MediaPlayerLengthChanged',
1821 274: 'MediaPlayerVout',
1822 275: 'MediaPlayerScrambledChanged',
1823+ 276: 'MediaPlayerESAdded',
1824+ 277: 'MediaPlayerESDeleted',
1825+ 278: 'MediaPlayerESSelected',
1826+ 279: 'MediaPlayerCorked',
1827+ 280: 'MediaPlayerUncorked',
1828+ 281: 'MediaPlayerMuted',
1829+ 282: 'MediaPlayerUnmuted',
1830+ 283: 'MediaPlayerAudioVolume',
1831+ 284: 'MediaPlayerAudioDevice',
1832+ 285: 'MediaPlayerChapterChanged',
1833 0x200: 'MediaListItemAdded',
1834 513: 'MediaListWillAddItem',
1835 514: 'MediaListItemDeleted',
1836 515: 'MediaListWillDeleteItem',
1837+ 516: 'MediaListEndReached',
1838 0x300: 'MediaListViewItemAdded',
1839 769: 'MediaListViewWillAddItem',
1840 770: 'MediaListViewItemDeleted',
1841@@ -437,6 +512,8 @@
1842 1026: 'MediaListPlayerStopped',
1843 0x500: 'MediaDiscovererStarted',
1844 1281: 'MediaDiscovererEnded',
1845+ 1282: 'RendererDiscovererItemAdded',
1846+ 1283: 'RendererDiscovererItemDeleted',
1847 0x600: 'VlmMediaAdded',
1848 1537: 'VlmMediaRemoved',
1849 1538: 'VlmMediaChanged',
1850@@ -453,6 +530,7 @@
1851 EventType.MediaDiscovererStarted = EventType(0x500)
1852 EventType.MediaDurationChanged = EventType(2)
1853 EventType.MediaFreed = EventType(4)
1854+EventType.MediaListEndReached = EventType(516)
1855 EventType.MediaListItemAdded = EventType(0x200)
1856 EventType.MediaListItemDeleted = EventType(514)
1857 EventType.MediaListPlayerNextItemSet = EventType(1025)
1858@@ -466,13 +544,21 @@
1859 EventType.MediaListWillDeleteItem = EventType(515)
1860 EventType.MediaMetaChanged = EventType(0)
1861 EventType.MediaParsedChanged = EventType(3)
1862+EventType.MediaPlayerAudioDevice = EventType(284)
1863+EventType.MediaPlayerAudioVolume = EventType(283)
1864 EventType.MediaPlayerBackward = EventType(264)
1865 EventType.MediaPlayerBuffering = EventType(259)
1866+EventType.MediaPlayerChapterChanged = EventType(285)
1867+EventType.MediaPlayerCorked = EventType(279)
1868+EventType.MediaPlayerESAdded = EventType(276)
1869+EventType.MediaPlayerESDeleted = EventType(277)
1870+EventType.MediaPlayerESSelected = EventType(278)
1871 EventType.MediaPlayerEncounteredError = EventType(266)
1872 EventType.MediaPlayerEndReached = EventType(265)
1873 EventType.MediaPlayerForward = EventType(263)
1874 EventType.MediaPlayerLengthChanged = EventType(273)
1875 EventType.MediaPlayerMediaChanged = EventType(0x100)
1876+EventType.MediaPlayerMuted = EventType(281)
1877 EventType.MediaPlayerNothingSpecial = EventType(257)
1878 EventType.MediaPlayerOpening = EventType(258)
1879 EventType.MediaPlayerPausableChanged = EventType(270)
1880@@ -485,10 +571,14 @@
1881 EventType.MediaPlayerStopped = EventType(262)
1882 EventType.MediaPlayerTimeChanged = EventType(267)
1883 EventType.MediaPlayerTitleChanged = EventType(271)
1884+EventType.MediaPlayerUncorked = EventType(280)
1885+EventType.MediaPlayerUnmuted = EventType(282)
1886 EventType.MediaPlayerVout = EventType(274)
1887 EventType.MediaStateChanged = EventType(5)
1888 EventType.MediaSubItemAdded = EventType(1)
1889 EventType.MediaSubItemTreeAdded = EventType(6)
1890+EventType.RendererDiscovererItemAdded = EventType(1282)
1891+EventType.RendererDiscovererItemDeleted = EventType(1283)
1892 EventType.VlmMediaAdded = EventType(0x600)
1893 EventType.VlmMediaChanged = EventType(1538)
1894 EventType.VlmMediaInstanceStarted = EventType(1539)
1895@@ -528,15 +618,21 @@
1896 20: 'Episode',
1897 21: 'ShowName',
1898 22: 'Actors',
1899+ 23: 'AlbumArtist',
1900+ 24: 'DiscNumber',
1901+ 25: 'DiscTotal',
1902 }
1903 Meta.Actors = Meta(22)
1904 Meta.Album = Meta(4)
1905+Meta.AlbumArtist = Meta(23)
1906 Meta.Artist = Meta(1)
1907 Meta.ArtworkURL = Meta(15)
1908 Meta.Copyright = Meta(3)
1909 Meta.Date = Meta(8)
1910 Meta.Description = Meta(6)
1911 Meta.Director = Meta(18)
1912+Meta.DiscNumber = Meta(24)
1913+Meta.DiscTotal = Meta(25)
1914 Meta.EncodedBy = Meta(14)
1915 Meta.Episode = Meta(20)
1916 Meta.Genre = Meta(2)
1917@@ -558,7 +654,7 @@
1918 See mediacontrol_playerstatus, See input_state_e enums,
1919 and videolan.libvlc.state (at bindings/cil/src/media.cs).
1920 expected states by web plugins are:
1921-idle/close=0, opening=1, buffering=2, playing=3, paused=4,
1922+idle/close=0, opening=1, playing=3, paused=4,
1923 stopping=5, ended=6, error=7.
1924 '''
1925 _enum_names_ = {
1926@@ -594,17 +690,102 @@
1927 TrackType.unknown = TrackType(-1)
1928 TrackType.video = TrackType(1)
1929
1930-class PlaybackMode(_Enum):
1931- '''Defines playback modes for playlist.
1932- '''
1933- _enum_names_ = {
1934- 0: 'default',
1935- 1: 'loop',
1936- 2: 'repeat',
1937- }
1938-PlaybackMode.default = PlaybackMode(0)
1939-PlaybackMode.loop = PlaybackMode(1)
1940-PlaybackMode.repeat = PlaybackMode(2)
1941+class VideoOrient(_Enum):
1942+ '''N/A
1943+ '''
1944+ _enum_names_ = {
1945+ 0: 'left',
1946+ 1: 'right',
1947+ 2: 'left',
1948+ 3: 'right',
1949+ 4: 'top',
1950+ 5: 'bottom',
1951+ 6: 'top',
1952+ 7: 'bottom',
1953+ }
1954+VideoOrient.bottom = VideoOrient(5)
1955+VideoOrient.bottom = VideoOrient(7)
1956+VideoOrient.left = VideoOrient(0)
1957+VideoOrient.left = VideoOrient(2)
1958+VideoOrient.right = VideoOrient(1)
1959+VideoOrient.right = VideoOrient(3)
1960+VideoOrient.top = VideoOrient(4)
1961+VideoOrient.top = VideoOrient(6)
1962+
1963+class VideoProjection(_Enum):
1964+ '''N/A
1965+ '''
1966+ _enum_names_ = {
1967+ 0: 'rectangular',
1968+ 1: 'equirectangular',
1969+ 0x100: 'standard',
1970+ }
1971+VideoProjection.equirectangular = VideoProjection(1)
1972+VideoProjection.rectangular = VideoProjection(0)
1973+VideoProjection.standard = VideoProjection(0x100)
1974+
1975+class MediaType(_Enum):
1976+ '''Media type
1977+See libvlc_media_get_type.
1978+ '''
1979+ _enum_names_ = {
1980+ 0: 'unknown',
1981+ 1: 'file',
1982+ 2: 'directory',
1983+ 3: 'disc',
1984+ 4: 'stream',
1985+ 5: 'playlist',
1986+ }
1987+MediaType.directory = MediaType(2)
1988+MediaType.disc = MediaType(3)
1989+MediaType.file = MediaType(1)
1990+MediaType.playlist = MediaType(5)
1991+MediaType.stream = MediaType(4)
1992+MediaType.unknown = MediaType(0)
1993+
1994+class MediaParseFlag(_Enum):
1995+ '''Parse flags used by libvlc_media_parse_with_options()
1996+See libvlc_media_parse_with_options.
1997+ '''
1998+ _enum_names_ = {
1999+ 0x0: 'local',
2000+ 0x1: 'network',
2001+ 0x2: 'local',
2002+ 0x4: 'network',
2003+ 0x8: 'interact',
2004+ }
2005+MediaParseFlag.interact = MediaParseFlag(0x8)
2006+MediaParseFlag.local = MediaParseFlag(0x0)
2007+MediaParseFlag.local = MediaParseFlag(0x2)
2008+MediaParseFlag.network = MediaParseFlag(0x1)
2009+MediaParseFlag.network = MediaParseFlag(0x4)
2010+
2011+class MediaParsedStatus(_Enum):
2012+ '''Parse status used sent by libvlc_media_parse_with_options() or returned by
2013+libvlc_media_get_parsed_status()
2014+See libvlc_media_parse_with_options
2015+See libvlc_media_get_parsed_status.
2016+ '''
2017+ _enum_names_ = {
2018+ 1: 'skipped',
2019+ 2: 'failed',
2020+ 3: 'timeout',
2021+ 4: 'done',
2022+ }
2023+MediaParsedStatus.done = MediaParsedStatus(4)
2024+MediaParsedStatus.failed = MediaParsedStatus(2)
2025+MediaParsedStatus.skipped = MediaParsedStatus(1)
2026+MediaParsedStatus.timeout = MediaParsedStatus(3)
2027+
2028+class MediaSlaveType(_Enum):
2029+ '''Type of a media slave: subtitle or audio.
2030+ '''
2031+ _enum_names_ = {
2032+ 0: 'subtitle',
2033+ 1: 'audio',
2034+ }
2035+MediaSlaveType.audio = MediaSlaveType(1)
2036+MediaSlaveType.subtitle = MediaSlaveType(0)
2037
2038 class VideoMarqueeOption(_Enum):
2039 '''Marq options definition.
2040@@ -641,10 +822,12 @@
2041 2: 'down',
2042 3: 'left',
2043 4: 'right',
2044+ 5: 'popup',
2045 }
2046 NavigateMode.activate = NavigateMode(0)
2047 NavigateMode.down = NavigateMode(2)
2048 NavigateMode.left = NavigateMode(3)
2049+NavigateMode.popup = NavigateMode(5)
2050 NavigateMode.right = NavigateMode(4)
2051 NavigateMode.up = NavigateMode(1)
2052
2053@@ -674,6 +857,23 @@
2054 Position.right = Position(8)
2055 Position.top = Position(3)
2056
2057+class TeletextKey(_Enum):
2058+ '''Enumeration of teletext keys than can be passed via
2059+libvlc_video_set_teletext().
2060+ '''
2061+ _enum_names_ = {
2062+ 7471104: 'red',
2063+ 6750208: 'green',
2064+ 7929856: 'yellow',
2065+ 6422528: 'blue',
2066+ 6881280: 'index',
2067+ }
2068+TeletextKey.blue = TeletextKey(6422528)
2069+TeletextKey.green = TeletextKey(6750208)
2070+TeletextKey.index = TeletextKey(6881280)
2071+TeletextKey.red = TeletextKey(7471104)
2072+TeletextKey.yellow = TeletextKey(7929856)
2073+
2074 class VideoLogoOption(_Enum):
2075 '''Option values for libvlc_video_{get,set}_logo_{int,string}.
2076 '''
2077@@ -756,276 +956,366 @@
2078 AudioOutputChannel.Right = AudioOutputChannel(4)
2079 AudioOutputChannel.Stereo = AudioOutputChannel(1)
2080
2081+class MediaPlayerRole(_Enum):
2082+ '''Media player roles.
2083+\version libvlc 3.0.0 and later.
2084+see \ref libvlc_media_player_set_role().
2085+ '''
2086+ _enum_names_ = {
2087+ 0: '_None',
2088+ 1: 'Music',
2089+ 2: 'Video',
2090+ 3: 'Communication',
2091+ 4: 'Game',
2092+ 5: 'Notification',
2093+ 6: 'Animation',
2094+ 7: 'Production',
2095+ 8: 'Accessibility',
2096+ 9: 'Test',
2097+ }
2098+MediaPlayerRole.Accessibility = MediaPlayerRole(8)
2099+MediaPlayerRole.Animation = MediaPlayerRole(6)
2100+MediaPlayerRole.Communication = MediaPlayerRole(3)
2101+MediaPlayerRole.Game = MediaPlayerRole(4)
2102+MediaPlayerRole.Music = MediaPlayerRole(1)
2103+MediaPlayerRole.Notification = MediaPlayerRole(5)
2104+MediaPlayerRole.Production = MediaPlayerRole(7)
2105+MediaPlayerRole.Test = MediaPlayerRole(9)
2106+MediaPlayerRole.Video = MediaPlayerRole(2)
2107+MediaPlayerRole._None = MediaPlayerRole(0)
2108+
2109+class PlaybackMode(_Enum):
2110+ '''Defines playback modes for playlist.
2111+ '''
2112+ _enum_names_ = {
2113+ 0: 'default',
2114+ 1: 'loop',
2115+ 2: 'repeat',
2116+ }
2117+PlaybackMode.default = PlaybackMode(0)
2118+PlaybackMode.loop = PlaybackMode(1)
2119+PlaybackMode.repeat = PlaybackMode(2)
2120+
2121 class Callback(ctypes.c_void_p):
2122- """Callback function notification
2123-\param p_event the event triggering the callback
2124+ """Callback function notification.
2125+ @param p_event: the event triggering the callback.
2126 """
2127 pass
2128 class LogCb(ctypes.c_void_p):
2129 """Callback prototype for LibVLC log message handler.
2130-\param data data pointer as given to L{libvlc_log_set}()
2131-\param level message level (@ref enum libvlc_log_level)
2132-\param ctx message context (meta-information about the message)
2133-\param fmt printf() format string (as defined by ISO C11)
2134-\param args variable argument list for the format
2135-\note Log message handlers <b>must</b> be thread-safe.
2136-\warning The message context pointer, the format string parameters and the
2137- variable arguments are only valid until the callback returns.
2138+ @param data: data pointer as given to L{libvlc_log_set}().
2139+ @param level: message level (@ref L{LogLevel}).
2140+ @param ctx: message context (meta-information about the message).
2141+ @param fmt: printf() format string (as defined by ISO C11).
2142+ @param args: variable argument list for the format @note Log message handlers B{must} be thread-safe. @warning The message context pointer, the format string parameters and the variable arguments are only valid until the callback returns.
2143+ """
2144+ pass
2145+class MediaOpenCb(ctypes.c_void_p):
2146+ """Callback prototype to open a custom bitstream input media.
2147+ The same media item can be opened multiple times. Each time, this callback
2148+ is invoked. It should allocate and initialize any instance-specific
2149+ resources, then store them in *datap. The instance resources can be freed
2150+ in the @ref libvlc_media_close_cb callback.
2151+ @param opaque: private pointer as passed to L{libvlc_media_new_callbacks}().
2152+ @return: datap storage space for a private data pointer, sizep byte length of the bitstream or UINT64_MAX if unknown.
2153+ """
2154+ pass
2155+class MediaReadCb(ctypes.c_void_p):
2156+ """Callback prototype to read data from a custom bitstream input media.
2157+ @param opaque: private pointer as set by the @ref libvlc_media_open_cb callback.
2158+ @param buf: start address of the buffer to read data into.
2159+ @param len: bytes length of the buffer.
2160+ @return: strictly positive number of bytes read, 0 on end-of-stream, or -1 on non-recoverable error @note If no data is immediately available, then the callback should sleep. @warning The application is responsible for avoiding deadlock situations. In particular, the callback should return an error if playback is stopped; if it does not return, then L{libvlc_media_player_stop}() will never return.
2161+ """
2162+ pass
2163+class MediaSeekCb(ctypes.c_void_p):
2164+ """Callback prototype to seek a custom bitstream input media.
2165+ @param opaque: private pointer as set by the @ref libvlc_media_open_cb callback.
2166+ @param offset: absolute byte offset to seek to.
2167+ @return: 0 on success, -1 on error.
2168+ """
2169+ pass
2170+class MediaCloseCb(ctypes.c_void_p):
2171+ """Callback prototype to close a custom bitstream input media.
2172+ @param opaque: private pointer as set by the @ref libvlc_media_open_cb callback.
2173 """
2174 pass
2175 class VideoLockCb(ctypes.c_void_p):
2176 """Callback prototype to allocate and lock a picture buffer.
2177-Whenever a new video frame needs to be decoded, the lock callback is
2178-invoked. Depending on the video chroma, one or three pixel planes of
2179-adequate dimensions must be returned via the second parameter. Those
2180-planes must be aligned on 32-bytes boundaries.
2181-\param opaque private pointer as passed to L{libvlc_video_set_callbacks}() [IN]
2182-\param planes start address of the pixel planes (LibVLC allocates the array
2183- of void pointers, this callback must initialize the array) [OUT]
2184-\return a private pointer for the display and unlock callbacks to identify
2185- the picture buffers
2186+ Whenever a new video frame needs to be decoded, the lock callback is
2187+ invoked. Depending on the video chroma, one or three pixel planes of
2188+ adequate dimensions must be returned via the second parameter. Those
2189+ planes must be aligned on 32-bytes boundaries.
2190+ @param opaque: private pointer as passed to L{libvlc_video_set_callbacks}() [IN].
2191+ @param planes: start address of the pixel planes (LibVLC allocates the array of void pointers, this callback must initialize the array) [OUT].
2192+ @return: a private pointer for the display and unlock callbacks to identify the picture buffers.
2193 """
2194 pass
2195 class VideoUnlockCb(ctypes.c_void_p):
2196 """Callback prototype to unlock a picture buffer.
2197-When the video frame decoding is complete, the unlock callback is invoked.
2198-This callback might not be needed at all. It is only an indication that the
2199-application can now read the pixel values if it needs to.
2200-\warning A picture buffer is unlocked after the picture is decoded,
2201-but before the picture is displayed.
2202-\param opaque private pointer as passed to L{libvlc_video_set_callbacks}() [IN]
2203-\param picture private pointer returned from the @ref libvlc_video_lock_cb
2204- callback [IN]
2205-\param planes pixel planes as defined by the @ref libvlc_video_lock_cb
2206- callback (this parameter is only for convenience) [IN]
2207+ When the video frame decoding is complete, the unlock callback is invoked.
2208+ This callback might not be needed at all. It is only an indication that the
2209+ application can now read the pixel values if it needs to.
2210+ @note: A picture buffer is unlocked after the picture is decoded,
2211+ but before the picture is displayed.
2212+ @param opaque: private pointer as passed to L{libvlc_video_set_callbacks}() [IN].
2213+ @param picture: private pointer returned from the @ref libvlc_video_lock_cb callback [IN].
2214+ @param planes: pixel planes as defined by the @ref libvlc_video_lock_cb callback (this parameter is only for convenience) [IN].
2215 """
2216 pass
2217 class VideoDisplayCb(ctypes.c_void_p):
2218 """Callback prototype to display a picture.
2219-When the video frame needs to be shown, as determined by the media playback
2220-clock, the display callback is invoked.
2221-\param opaque private pointer as passed to L{libvlc_video_set_callbacks}() [IN]
2222-\param picture private pointer returned from the @ref libvlc_video_lock_cb
2223- callback [IN]
2224+ When the video frame needs to be shown, as determined by the media playback
2225+ clock, the display callback is invoked.
2226+ @param opaque: private pointer as passed to L{libvlc_video_set_callbacks}() [IN].
2227+ @param picture: private pointer returned from the @ref libvlc_video_lock_cb callback [IN].
2228 """
2229 pass
2230 class VideoFormatCb(ctypes.c_void_p):
2231 """Callback prototype to configure picture buffers format.
2232-This callback gets the format of the video as output by the video decoder
2233-and the chain of video filters (if any). It can opt to change any parameter
2234-as it needs. In that case, LibVLC will attempt to convert the video format
2235-(rescaling and chroma conversion) but these operations can be CPU intensive.
2236-\param opaque pointer to the private pointer passed to
2237- L{libvlc_video_set_callbacks}() [IN/OUT]
2238-\param chroma pointer to the 4 bytes video format identifier [IN/OUT]
2239-\param width pointer to the pixel width [IN/OUT]
2240-\param height pointer to the pixel height [IN/OUT]
2241-\param pitches table of scanline pitches in bytes for each pixel plane
2242- (the table is allocated by LibVLC) [OUT]
2243-\param lines table of scanlines count for each plane [OUT]
2244-\return the number of picture buffers allocated, 0 indicates failure
2245-\note
2246-For each pixels plane, the scanline pitch must be bigger than or equal to
2247-the number of bytes per pixel multiplied by the pixel width.
2248-Similarly, the number of scanlines must be bigger than of equal to
2249-the pixel height.
2250-Furthermore, we recommend that pitches and lines be multiple of 32
2251-to not break assumption that might be made by various optimizations
2252-in the video decoders, video filters and/or video converters.
2253+ This callback gets the format of the video as output by the video decoder
2254+ and the chain of video filters (if any). It can opt to change any parameter
2255+ as it needs. In that case, LibVLC will attempt to convert the video format
2256+ (rescaling and chroma conversion) but these operations can be CPU intensive.
2257+ @param opaque: pointer to the private pointer passed to L{libvlc_video_set_callbacks}() [IN/OUT].
2258+ @param chroma: pointer to the 4 bytes video format identifier [IN/OUT].
2259+ @param width: pointer to the pixel width [IN/OUT].
2260+ @param height: pointer to the pixel height [IN/OUT].
2261+ @param pitches: table of scanline pitches in bytes for each pixel plane (the table is allocated by LibVLC) [OUT].
2262+ @return: lines table of scanlines count for each plane.
2263 """
2264 pass
2265 class VideoCleanupCb(ctypes.c_void_p):
2266 """Callback prototype to configure picture buffers format.
2267-\param opaque private pointer as passed to L{libvlc_video_set_callbacks}()
2268- (and possibly modified by @ref libvlc_video_format_cb) [IN]
2269+ @param opaque: private pointer as passed to L{libvlc_video_set_callbacks}() (and possibly modified by @ref libvlc_video_format_cb) [IN].
2270 """
2271 pass
2272 class AudioPlayCb(ctypes.c_void_p):
2273 """Callback prototype for audio playback.
2274-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2275-\param samples pointer to the first audio sample to play back [IN]
2276-\param count number of audio samples to play back
2277-\param pts expected play time stamp (see libvlc_delay())
2278+ The LibVLC media player decodes and post-processes the audio signal
2279+ asynchronously (in an internal thread). Whenever audio samples are ready
2280+ to be queued to the output, this callback is invoked.
2281+ The number of samples provided per invocation may depend on the file format,
2282+ the audio coding algorithm, the decoder plug-in, the post-processing
2283+ filters and timing. Application must not assume a certain number of samples.
2284+ The exact format of audio samples is determined by L{libvlc_audio_set_format}()
2285+ or L{libvlc_audio_set_format_callbacks}() as is the channels layout.
2286+ Note that the number of samples is per channel. For instance, if the audio
2287+ track sampling rate is 48000 Hz, then 1200 samples represent 25 milliseconds
2288+ of audio signal - regardless of the number of audio channels.
2289+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2290+ @param samples: pointer to a table of audio samples to play back [IN].
2291+ @param count: number of audio samples to play back.
2292+ @param pts: expected play time stamp (see libvlc_delay()).
2293 """
2294 pass
2295 class AudioPauseCb(ctypes.c_void_p):
2296 """Callback prototype for audio pause.
2297-\note The pause callback is never called if the audio is already paused.
2298-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2299-\param pts time stamp of the pause request (should be elapsed already)
2300+ LibVLC invokes this callback to pause audio playback.
2301+ @note: The pause callback is never called if the audio is already paused.
2302+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2303+ @param pts: time stamp of the pause request (should be elapsed already).
2304 """
2305 pass
2306 class AudioResumeCb(ctypes.c_void_p):
2307- """Callback prototype for audio resumption (i.e. restart from pause).
2308-\note The resume callback is never called if the audio is not paused.
2309-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2310-\param pts time stamp of the resumption request (should be elapsed already)
2311+ """Callback prototype for audio resumption.
2312+ LibVLC invokes this callback to resume audio playback after it was
2313+ previously paused.
2314+ @note: The resume callback is never called if the audio is not paused.
2315+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2316+ @param pts: time stamp of the resumption request (should be elapsed already).
2317 """
2318 pass
2319 class AudioFlushCb(ctypes.c_void_p):
2320- """Callback prototype for audio buffer flush
2321-(i.e. discard all pending buffers and stop playback as soon as possible).
2322-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2323+ """Callback prototype for audio buffer flush.
2324+ LibVLC invokes this callback if it needs to discard all pending buffers and
2325+ stop playback as soon as possible. This typically occurs when the media is
2326+ stopped.
2327+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2328 """
2329 pass
2330 class AudioDrainCb(ctypes.c_void_p):
2331- """Callback prototype for audio buffer drain
2332-(i.e. wait for pending buffers to be played).
2333-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2334+ """Callback prototype for audio buffer drain.
2335+ LibVLC may invoke this callback when the decoded audio track is ending.
2336+ There will be no further decoded samples for the track, but playback should
2337+ nevertheless continue until all already pending buffers are rendered.
2338+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2339 """
2340 pass
2341 class AudioSetVolumeCb(ctypes.c_void_p):
2342 """Callback prototype for audio volume change.
2343-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2344-\param volume software volume (1. = nominal, 0. = mute)
2345-\param mute muted flag
2346+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2347+ @param volume: software volume (1. = nominal, 0. = mute).
2348+ @param mute: muted flag.
2349 """
2350 pass
2351 class AudioSetupCb(ctypes.c_void_p):
2352 """Callback prototype to setup the audio playback.
2353-This is called when the media player needs to create a new audio output.
2354-\param opaque pointer to the data pointer passed to
2355- L{libvlc_audio_set_callbacks}() [IN/OUT]
2356-\param format 4 bytes sample format [IN/OUT]
2357-\param rate sample rate [IN/OUT]
2358-\param channels channels count [IN/OUT]
2359-\return 0 on success, anything else to skip audio playback
2360+ This is called when the media player needs to create a new audio output.
2361+ @param opaque: pointer to the data pointer passed to L{libvlc_audio_set_callbacks}() [IN/OUT].
2362+ @param format: 4 bytes sample format [IN/OUT].
2363+ @param rate: sample rate [IN/OUT].
2364+ @param channels: channels count [IN/OUT].
2365+ @return: 0 on success, anything else to skip audio playback.
2366 """
2367 pass
2368 class AudioCleanupCb(ctypes.c_void_p):
2369 """Callback prototype for audio playback cleanup.
2370-This is called when the media player no longer needs an audio output.
2371-\param opaque data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2372+ This is called when the media player no longer needs an audio output.
2373+ @param opaque: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2374 """
2375 pass
2376 class CallbackDecorators(object):
2377 "Class holding various method decorators for callback functions."
2378 Callback = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)
2379- Callback.__doc__ = '''Callback function notification
2380-\param p_event the event triggering the callback
2381+ Callback.__doc__ = '''Callback function notification.
2382+ @param p_event: the event triggering the callback.
2383 '''
2384 LogCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, Log_ptr, ctypes.c_char_p, ctypes.c_void_p)
2385 LogCb.__doc__ = '''Callback prototype for LibVLC log message handler.
2386-\param data data pointer as given to L{libvlc_log_set}()
2387-\param level message level (@ref enum libvlc_log_level)
2388-\param ctx message context (meta-information about the message)
2389-\param fmt printf() format string (as defined by ISO C11)
2390-\param args variable argument list for the format
2391-\note Log message handlers <b>must</b> be thread-safe.
2392-\warning The message context pointer, the format string parameters and the
2393- variable arguments are only valid until the callback returns.
2394- '''
2395- VideoLockCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ListPOINTER(ctypes.c_void_p))
2396+ @param data: data pointer as given to L{libvlc_log_set}().
2397+ @param level: message level (@ref L{LogLevel}).
2398+ @param ctx: message context (meta-information about the message).
2399+ @param fmt: printf() format string (as defined by ISO C11).
2400+ @param args: variable argument list for the format @note Log message handlers B{must} be thread-safe. @warning The message context pointer, the format string parameters and the variable arguments are only valid until the callback returns.
2401+ '''
2402+ MediaOpenCb = ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.c_int), ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_uint64))
2403+ MediaOpenCb.__doc__ = '''Callback prototype to open a custom bitstream input media.
2404+ The same media item can be opened multiple times. Each time, this callback
2405+ is invoked. It should allocate and initialize any instance-specific
2406+ resources, then store them in *datap. The instance resources can be freed
2407+ in the @ref libvlc_media_close_cb callback.
2408+ @param opaque: private pointer as passed to L{libvlc_media_new_callbacks}().
2409+ @return: datap storage space for a private data pointer, sizep byte length of the bitstream or UINT64_MAX if unknown.
2410+ '''
2411+ MediaReadCb = ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.c_ssize_t), ctypes.c_void_p, ctypes.c_char_p, ctypes.c_size_t)
2412+ MediaReadCb.__doc__ = '''Callback prototype to read data from a custom bitstream input media.
2413+ @param opaque: private pointer as set by the @ref libvlc_media_open_cb callback.
2414+ @param buf: start address of the buffer to read data into.
2415+ @param len: bytes length of the buffer.
2416+ @return: strictly positive number of bytes read, 0 on end-of-stream, or -1 on non-recoverable error @note If no data is immediately available, then the callback should sleep. @warning The application is responsible for avoiding deadlock situations. In particular, the callback should return an error if playback is stopped; if it does not return, then L{libvlc_media_player_stop}() will never return.
2417+ '''
2418+ MediaSeekCb = ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.c_int), ctypes.c_void_p, ctypes.c_uint64)
2419+ MediaSeekCb.__doc__ = '''Callback prototype to seek a custom bitstream input media.
2420+ @param opaque: private pointer as set by the @ref libvlc_media_open_cb callback.
2421+ @param offset: absolute byte offset to seek to.
2422+ @return: 0 on success, -1 on error.
2423+ '''
2424+ MediaCloseCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p)
2425+ MediaCloseCb.__doc__ = '''Callback prototype to close a custom bitstream input media.
2426+ @param opaque: private pointer as set by the @ref libvlc_media_open_cb callback.
2427+ '''
2428+ VideoLockCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p))
2429 VideoLockCb.__doc__ = '''Callback prototype to allocate and lock a picture buffer.
2430-Whenever a new video frame needs to be decoded, the lock callback is
2431-invoked. Depending on the video chroma, one or three pixel planes of
2432-adequate dimensions must be returned via the second parameter. Those
2433-planes must be aligned on 32-bytes boundaries.
2434-\param opaque private pointer as passed to L{libvlc_video_set_callbacks}() [IN]
2435-\param planes start address of the pixel planes (LibVLC allocates the array
2436- of void pointers, this callback must initialize the array) [OUT]
2437-\return a private pointer for the display and unlock callbacks to identify
2438- the picture buffers
2439+ Whenever a new video frame needs to be decoded, the lock callback is
2440+ invoked. Depending on the video chroma, one or three pixel planes of
2441+ adequate dimensions must be returned via the second parameter. Those
2442+ planes must be aligned on 32-bytes boundaries.
2443+ @param opaque: private pointer as passed to L{libvlc_video_set_callbacks}() [IN].
2444+ @param planes: start address of the pixel planes (LibVLC allocates the array of void pointers, this callback must initialize the array) [OUT].
2445+ @return: a private pointer for the display and unlock callbacks to identify the picture buffers.
2446 '''
2447- VideoUnlockCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ListPOINTER(ctypes.c_void_p))
2448+ VideoUnlockCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p))
2449 VideoUnlockCb.__doc__ = '''Callback prototype to unlock a picture buffer.
2450-When the video frame decoding is complete, the unlock callback is invoked.
2451-This callback might not be needed at all. It is only an indication that the
2452-application can now read the pixel values if it needs to.
2453-\warning A picture buffer is unlocked after the picture is decoded,
2454-but before the picture is displayed.
2455-\param opaque private pointer as passed to L{libvlc_video_set_callbacks}() [IN]
2456-\param picture private pointer returned from the @ref libvlc_video_lock_cb
2457- callback [IN]
2458-\param planes pixel planes as defined by the @ref libvlc_video_lock_cb
2459- callback (this parameter is only for convenience) [IN]
2460+ When the video frame decoding is complete, the unlock callback is invoked.
2461+ This callback might not be needed at all. It is only an indication that the
2462+ application can now read the pixel values if it needs to.
2463+ @note: A picture buffer is unlocked after the picture is decoded,
2464+ but before the picture is displayed.
2465+ @param opaque: private pointer as passed to L{libvlc_video_set_callbacks}() [IN].
2466+ @param picture: private pointer returned from the @ref libvlc_video_lock_cb callback [IN].
2467+ @param planes: pixel planes as defined by the @ref libvlc_video_lock_cb callback (this parameter is only for convenience) [IN].
2468 '''
2469 VideoDisplayCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)
2470 VideoDisplayCb.__doc__ = '''Callback prototype to display a picture.
2471-When the video frame needs to be shown, as determined by the media playback
2472-clock, the display callback is invoked.
2473-\param opaque private pointer as passed to L{libvlc_video_set_callbacks}() [IN]
2474-\param picture private pointer returned from the @ref libvlc_video_lock_cb
2475- callback [IN]
2476+ When the video frame needs to be shown, as determined by the media playback
2477+ clock, the display callback is invoked.
2478+ @param opaque: private pointer as passed to L{libvlc_video_set_callbacks}() [IN].
2479+ @param picture: private pointer returned from the @ref libvlc_video_lock_cb callback [IN].
2480 '''
2481- VideoFormatCb = ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.c_uint), ListPOINTER(ctypes.c_void_p), ctypes.c_char_p, ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_uint))
2482+ VideoFormatCb = ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_void_p), ctypes.c_char_p, ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_uint))
2483 VideoFormatCb.__doc__ = '''Callback prototype to configure picture buffers format.
2484-This callback gets the format of the video as output by the video decoder
2485-and the chain of video filters (if any). It can opt to change any parameter
2486-as it needs. In that case, LibVLC will attempt to convert the video format
2487-(rescaling and chroma conversion) but these operations can be CPU intensive.
2488-\param opaque pointer to the private pointer passed to
2489- L{libvlc_video_set_callbacks}() [IN/OUT]
2490-\param chroma pointer to the 4 bytes video format identifier [IN/OUT]
2491-\param width pointer to the pixel width [IN/OUT]
2492-\param height pointer to the pixel height [IN/OUT]
2493-\param pitches table of scanline pitches in bytes for each pixel plane
2494- (the table is allocated by LibVLC) [OUT]
2495-\param lines table of scanlines count for each plane [OUT]
2496-\return the number of picture buffers allocated, 0 indicates failure
2497-\note
2498-For each pixels plane, the scanline pitch must be bigger than or equal to
2499-the number of bytes per pixel multiplied by the pixel width.
2500-Similarly, the number of scanlines must be bigger than of equal to
2501-the pixel height.
2502-Furthermore, we recommend that pitches and lines be multiple of 32
2503-to not break assumption that might be made by various optimizations
2504-in the video decoders, video filters and/or video converters.
2505+ This callback gets the format of the video as output by the video decoder
2506+ and the chain of video filters (if any). It can opt to change any parameter
2507+ as it needs. In that case, LibVLC will attempt to convert the video format
2508+ (rescaling and chroma conversion) but these operations can be CPU intensive.
2509+ @param opaque: pointer to the private pointer passed to L{libvlc_video_set_callbacks}() [IN/OUT].
2510+ @param chroma: pointer to the 4 bytes video format identifier [IN/OUT].
2511+ @param width: pointer to the pixel width [IN/OUT].
2512+ @param height: pointer to the pixel height [IN/OUT].
2513+ @param pitches: table of scanline pitches in bytes for each pixel plane (the table is allocated by LibVLC) [OUT].
2514+ @return: lines table of scanlines count for each plane.
2515 '''
2516 VideoCleanupCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p)
2517 VideoCleanupCb.__doc__ = '''Callback prototype to configure picture buffers format.
2518-\param opaque private pointer as passed to L{libvlc_video_set_callbacks}()
2519- (and possibly modified by @ref libvlc_video_format_cb) [IN]
2520+ @param opaque: private pointer as passed to L{libvlc_video_set_callbacks}() (and possibly modified by @ref libvlc_video_format_cb) [IN].
2521 '''
2522 AudioPlayCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint, ctypes.c_int64)
2523 AudioPlayCb.__doc__ = '''Callback prototype for audio playback.
2524-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2525-\param samples pointer to the first audio sample to play back [IN]
2526-\param count number of audio samples to play back
2527-\param pts expected play time stamp (see libvlc_delay())
2528+ The LibVLC media player decodes and post-processes the audio signal
2529+ asynchronously (in an internal thread). Whenever audio samples are ready
2530+ to be queued to the output, this callback is invoked.
2531+ The number of samples provided per invocation may depend on the file format,
2532+ the audio coding algorithm, the decoder plug-in, the post-processing
2533+ filters and timing. Application must not assume a certain number of samples.
2534+ The exact format of audio samples is determined by L{libvlc_audio_set_format}()
2535+ or L{libvlc_audio_set_format_callbacks}() as is the channels layout.
2536+ Note that the number of samples is per channel. For instance, if the audio
2537+ track sampling rate is 48000 Hz, then 1200 samples represent 25 milliseconds
2538+ of audio signal - regardless of the number of audio channels.
2539+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2540+ @param samples: pointer to a table of audio samples to play back [IN].
2541+ @param count: number of audio samples to play back.
2542+ @param pts: expected play time stamp (see libvlc_delay()).
2543 '''
2544 AudioPauseCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int64)
2545 AudioPauseCb.__doc__ = '''Callback prototype for audio pause.
2546-\note The pause callback is never called if the audio is already paused.
2547-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2548-\param pts time stamp of the pause request (should be elapsed already)
2549+ LibVLC invokes this callback to pause audio playback.
2550+ @note: The pause callback is never called if the audio is already paused.
2551+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2552+ @param pts: time stamp of the pause request (should be elapsed already).
2553 '''
2554 AudioResumeCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int64)
2555- AudioResumeCb.__doc__ = '''Callback prototype for audio resumption (i.e. restart from pause).
2556-\note The resume callback is never called if the audio is not paused.
2557-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2558-\param pts time stamp of the resumption request (should be elapsed already)
2559+ AudioResumeCb.__doc__ = '''Callback prototype for audio resumption.
2560+ LibVLC invokes this callback to resume audio playback after it was
2561+ previously paused.
2562+ @note: The resume callback is never called if the audio is not paused.
2563+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2564+ @param pts: time stamp of the resumption request (should be elapsed already).
2565 '''
2566 AudioFlushCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int64)
2567- AudioFlushCb.__doc__ = '''Callback prototype for audio buffer flush
2568-(i.e. discard all pending buffers and stop playback as soon as possible).
2569-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2570+ AudioFlushCb.__doc__ = '''Callback prototype for audio buffer flush.
2571+ LibVLC invokes this callback if it needs to discard all pending buffers and
2572+ stop playback as soon as possible. This typically occurs when the media is
2573+ stopped.
2574+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2575 '''
2576 AudioDrainCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p)
2577- AudioDrainCb.__doc__ = '''Callback prototype for audio buffer drain
2578-(i.e. wait for pending buffers to be played).
2579-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2580+ AudioDrainCb.__doc__ = '''Callback prototype for audio buffer drain.
2581+ LibVLC may invoke this callback when the decoded audio track is ending.
2582+ There will be no further decoded samples for the track, but playback should
2583+ nevertheless continue until all already pending buffers are rendered.
2584+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2585 '''
2586 AudioSetVolumeCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_float, ctypes.c_bool)
2587 AudioSetVolumeCb.__doc__ = '''Callback prototype for audio volume change.
2588-\param data data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2589-\param volume software volume (1. = nominal, 0. = mute)
2590-\param mute muted flag
2591+ @param data: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2592+ @param volume: software volume (1. = nominal, 0. = mute).
2593+ @param mute: muted flag.
2594 '''
2595- AudioSetupCb = ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.c_int), ListPOINTER(ctypes.c_void_p), ctypes.c_char_p, ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_uint))
2596+ AudioSetupCb = ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_void_p), ctypes.c_char_p, ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_uint))
2597 AudioSetupCb.__doc__ = '''Callback prototype to setup the audio playback.
2598-This is called when the media player needs to create a new audio output.
2599-\param opaque pointer to the data pointer passed to
2600- L{libvlc_audio_set_callbacks}() [IN/OUT]
2601-\param format 4 bytes sample format [IN/OUT]
2602-\param rate sample rate [IN/OUT]
2603-\param channels channels count [IN/OUT]
2604-\return 0 on success, anything else to skip audio playback
2605+ This is called when the media player needs to create a new audio output.
2606+ @param opaque: pointer to the data pointer passed to L{libvlc_audio_set_callbacks}() [IN/OUT].
2607+ @param format: 4 bytes sample format [IN/OUT].
2608+ @param rate: sample rate [IN/OUT].
2609+ @param channels: channels count [IN/OUT].
2610+ @return: 0 on success, anything else to skip audio playback.
2611 '''
2612 AudioCleanupCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p)
2613 AudioCleanupCb.__doc__ = '''Callback prototype for audio playback cleanup.
2614-This is called when the media player no longer needs an audio output.
2615-\param opaque data pointer as passed to L{libvlc_audio_set_callbacks}() [IN]
2616+ This is called when the media player no longer needs an audio output.
2617+ @param opaque: data pointer as passed to L{libvlc_audio_set_callbacks}() [IN].
2618 '''
2619 cb = CallbackDecorators
2620 # End of generated enum types #
2621@@ -1277,21 +1567,54 @@
2622 ]
2623
2624 class TitleDescription(_Cstruct):
2625- _fields = [
2626+ _fields_ = [
2627 ('duration', ctypes.c_longlong),
2628 ('name', ctypes.c_char_p),
2629 ('menu', ctypes.c_bool),
2630 ]
2631
2632 class ChapterDescription(_Cstruct):
2633- _fields = [
2634+ _fields_ = [
2635 ('time_offset', ctypes.c_longlong),
2636 ('duration', ctypes.c_longlong),
2637 ('name', ctypes.c_char_p),
2638 ]
2639
2640- # End of header.py #
2641-
2642+class VideoViewpoint(_Cstruct):
2643+ _fields_ = [
2644+ ('yaw', ctypes.c_float),
2645+ ('pitch', ctypes.c_float),
2646+ ('roll', ctypes.c_float),
2647+ ('field_of_view', ctypes.c_float),
2648+ ]
2649+
2650+class MediaDiscovererDescription(_Cstruct):
2651+ _fields_ = [
2652+ ('name', ctypes.c_char_p),
2653+ ('longname', ctypes.c_char_p),
2654+ ('cat', MediaDiscovererCategory),
2655+ ]
2656+
2657+ def __str__(self):
2658+ return '%s %s (%d) - %s' % (self.__class__.__name__, self.name, self.cat, self.longname)
2659+
2660+# This struct depends on the MediaSlaveType enum that is defined only
2661+# in > 2.2
2662+if 'MediaSlaveType' in locals():
2663+ class MediaSlave(_Cstruct):
2664+ _fields_ = [
2665+ ('psz_uri', ctypes.c_char_p),
2666+ ('i_type', MediaSlaveType),
2667+ ('i_priority', ctypes.c_uint)
2668+ ]
2669+
2670+class RDDescription(_Cstruct):
2671+ _fields_ = [
2672+ ('name', ctypes.c_char_p),
2673+ ('longname', ctypes.c_char_p)
2674+ ]
2675+
2676+# End of header.py #
2677 class EventManager(_Ctype):
2678 '''Create an event manager with callback handler.
2679
2680@@ -1397,14 +1720,22 @@
2681 elif isinstance(i, basestring):
2682 args = i.strip().split()
2683 elif isinstance(i, _Seqs):
2684- args = i
2685+ args = list(i)
2686 else:
2687 raise VLCException('Instance %r' % (args,))
2688-
2689- if not args and plugin_path is not None:
2690- # no parameters passed, for win32 and MacOS,
2691- # specify the plugin_path if detected earlier
2692- args = ['vlc', '--plugin-path=' + plugin_path]
2693+ else:
2694+ args = list(args)
2695+
2696+ if not args: # no parameters passed
2697+ args = ['vlc']
2698+ elif args[0] != 'vlc':
2699+ args.insert(0, 'vlc')
2700+
2701+ if plugin_path is not None:
2702+ # set plugin_path if detected, win32 and MacOS,
2703+ # if the user did not specify it itself.
2704+ os.environ.setdefault('VLC_PLUGIN_PATH', plugin_path)
2705+
2706 if PYTHON3:
2707 args = [ str_to_bytes(a) for a in args ]
2708 return libvlc_new(len(args), args)
2709@@ -1547,16 +1878,18 @@
2710
2711
2712 def log_unset(self):
2713- '''Unsets the logging callback for a LibVLC instance. This is rarely needed:
2714- the callback is implicitly unset when the instance is destroyed.
2715- This function will wait for any pending callbacks invocation to complete
2716- (causing a deadlock if called from within the callback).
2717+ '''Unsets the logging callback.
2718+ This function deregisters the logging callback for a LibVLC instance.
2719+ This is rarely needed as the callback is implicitly unset when the instance
2720+ is destroyed.
2721+ @note: This function will wait for any pending callbacks invocation to
2722+ complete (causing a deadlock if called from within the callback).
2723 @version: LibVLC 2.1.0 or later.
2724 '''
2725 return libvlc_log_unset(self)
2726
2727
2728- def log_set(self, data, p_instance):
2729+ def log_set(self, cb, data):
2730 '''Sets the logging callback for a LibVLC instance.
2731 This function is thread-safe: it will wait for any pending callbacks
2732 invocation to complete.
2733@@ -1564,7 +1897,7 @@
2734 @param p_instance: libvlc instance.
2735 @version: LibVLC 2.1.0 or later.
2736 '''
2737- return libvlc_log_set(self, data, p_instance)
2738+ return libvlc_log_set(self, cb, data)
2739
2740
2741 def log_set_file(self, stream):
2742@@ -1575,65 +1908,30 @@
2743 return libvlc_log_set_file(self, stream)
2744
2745
2746- def media_new_location(self, psz_mrl):
2747- '''Create a media with a certain given media resource location,
2748- for instance a valid URL.
2749- @note: To refer to a local file with this function,
2750- the file://... URI syntax B{must} be used (see IETF RFC3986).
2751- We recommend using L{media_new_path}() instead when dealing with
2752- local files.
2753- See L{media_release}.
2754- @param psz_mrl: the media location.
2755- @return: the newly created media or None on error.
2756- '''
2757- return libvlc_media_new_location(self, str_to_bytes(psz_mrl))
2758-
2759-
2760- def media_new_path(self, path):
2761- '''Create a media for a certain file path.
2762- See L{media_release}.
2763- @param path: local filesystem path.
2764- @return: the newly created media or None on error.
2765- '''
2766- return libvlc_media_new_path(self, str_to_bytes(path))
2767-
2768-
2769- def media_new_fd(self, fd):
2770- '''Create a media for an already open file descriptor.
2771- The file descriptor shall be open for reading (or reading and writing).
2772- Regular file descriptors, pipe read descriptors and character device
2773- descriptors (including TTYs) are supported on all platforms.
2774- Block device descriptors are supported where available.
2775- Directory descriptors are supported on systems that provide fdopendir().
2776- Sockets are supported on all platforms where they are file descriptors,
2777- i.e. all except Windows.
2778- @note: This library will B{not} automatically close the file descriptor
2779- under any circumstance. Nevertheless, a file descriptor can usually only be
2780- rendered once in a media player. To render it a second time, the file
2781- descriptor should probably be rewound to the beginning with lseek().
2782- See L{media_release}.
2783- @param fd: open file descriptor.
2784- @return: the newly created media or None on error.
2785- @version: LibVLC 1.1.5 and later.
2786- '''
2787- return libvlc_media_new_fd(self, fd)
2788-
2789-
2790- def media_new_as_node(self, psz_name):
2791- '''Create a media as an empty node with a given name.
2792- See L{media_release}.
2793- @param psz_name: the name of the node.
2794- @return: the new empty media or None on error.
2795- '''
2796- return libvlc_media_new_as_node(self, str_to_bytes(psz_name))
2797-
2798-
2799- def media_discoverer_new_from_name(self, psz_name):
2800- '''Discover media service by name.
2801- @param psz_name: service name.
2802+ def media_discoverer_new(self, psz_name):
2803+ '''Create a media discoverer object by name.
2804+ After this object is created, you should attach to media_list events in
2805+ order to be notified of new items discovered.
2806+ You need to call L{media_discoverer_start}() in order to start the
2807+ discovery.
2808+ See L{media_discoverer_media_list}
2809+ See L{media_discoverer_event_manager}
2810+ See L{media_discoverer_start}.
2811+ @param psz_name: service name; use L{media_discoverer_list_get}() to get a list of the discoverer names available in this libVLC instance.
2812 @return: media discover object or None in case of error.
2813- '''
2814- return libvlc_media_discoverer_new_from_name(self, str_to_bytes(psz_name))
2815+ @version: LibVLC 3.0.0 or later.
2816+ '''
2817+ return libvlc_media_discoverer_new(self, str_to_bytes(psz_name))
2818+
2819+
2820+ def media_discoverer_list_get(self, i_cat, ppp_services):
2821+ '''Get media discoverer services by category.
2822+ @param i_cat: category of services to fetch.
2823+ @param ppp_services: address to store an allocated array of media discoverer services (must be freed with L{media_discoverer_list_release}() by the caller) [OUT].
2824+ @return: the number of media discoverer services (0 on error).
2825+ @version: LibVLC 3.0.0 and later.
2826+ '''
2827+ return libvlc_media_discoverer_list_get(self, i_cat, ppp_services)
2828
2829
2830 def media_library_new(self):
2831@@ -1643,30 +1941,6 @@
2832 return libvlc_media_library_new(self)
2833
2834
2835- def audio_output_list_get(self):
2836- '''Gets the list of available audio output modules.
2837- @return: list of available audio outputs. It must be freed it with In case of error, None is returned.
2838- '''
2839- return libvlc_audio_output_list_get(self)
2840-
2841-
2842- def audio_output_device_list_get(self, aout):
2843- '''Gets a list of audio output devices for a given audio output module,
2844- See L{audio_output_device_set}().
2845- @note: Not all audio outputs support this. In particular, an empty (None)
2846- list of devices does B{not} imply that the specified audio output does
2847- not work.
2848- @note: The list might not be exhaustive.
2849- @warning: Some audio output devices in the list might not actually work in
2850- some circumstances. By default, it is recommended to not specify any
2851- explicit audio device.
2852- @param psz_aout: audio output name (as returned by L{audio_output_list_get}()).
2853- @return: A None-terminated linked list of potential audio output devices. It must be freed it with L{audio_output_device_list_release}().
2854- @version: LibVLC 2.1.0 or later.
2855- '''
2856- return libvlc_audio_output_device_list_get(self, str_to_bytes(aout))
2857-
2858-
2859 def vlm_release(self):
2860 '''Release the vlm instance related to the given L{Instance}.
2861 '''
2862@@ -1899,9 +2173,234 @@
2863 '''
2864 return libvlc_vlm_get_event_manager(self)
2865
2866+
2867+ def media_new_location(self, psz_mrl):
2868+ '''Create a media with a certain given media resource location,
2869+ for instance a valid URL.
2870+ @note: To refer to a local file with this function,
2871+ the file://... URI syntax B{must} be used (see IETF RFC3986).
2872+ We recommend using L{media_new_path}() instead when dealing with
2873+ local files.
2874+ See L{media_release}.
2875+ @param psz_mrl: the media location.
2876+ @return: the newly created media or None on error.
2877+ '''
2878+ return libvlc_media_new_location(self, str_to_bytes(psz_mrl))
2879+
2880+
2881+ def media_new_path(self, path):
2882+ '''Create a media for a certain file path.
2883+ See L{media_release}.
2884+ @param path: local filesystem path.
2885+ @return: the newly created media or None on error.
2886+ '''
2887+ return libvlc_media_new_path(self, str_to_bytes(path))
2888+
2889+
2890+ def media_new_fd(self, fd):
2891+ '''Create a media for an already open file descriptor.
2892+ The file descriptor shall be open for reading (or reading and writing).
2893+ Regular file descriptors, pipe read descriptors and character device
2894+ descriptors (including TTYs) are supported on all platforms.
2895+ Block device descriptors are supported where available.
2896+ Directory descriptors are supported on systems that provide fdopendir().
2897+ Sockets are supported on all platforms where they are file descriptors,
2898+ i.e. all except Windows.
2899+ @note: This library will B{not} automatically close the file descriptor
2900+ under any circumstance. Nevertheless, a file descriptor can usually only be
2901+ rendered once in a media player. To render it a second time, the file
2902+ descriptor should probably be rewound to the beginning with lseek().
2903+ See L{media_release}.
2904+ @param fd: open file descriptor.
2905+ @return: the newly created media or None on error.
2906+ @version: LibVLC 1.1.5 and later.
2907+ '''
2908+ return libvlc_media_new_fd(self, fd)
2909+
2910+
2911+ def media_new_callbacks(self, open_cb, read_cb, seek_cb, close_cb, opaque):
2912+ '''Create a media with custom callbacks to read the data from.
2913+ @param open_cb: callback to open the custom bitstream input media.
2914+ @param read_cb: callback to read data (must not be None).
2915+ @param seek_cb: callback to seek, or None if seeking is not supported.
2916+ @param close_cb: callback to close the media, or None if unnecessary.
2917+ @param opaque: data pointer for the open callback.
2918+ @return: the newly created media or None on error @note If open_cb is None, the opaque pointer will be passed to read_cb, seek_cb and close_cb, and the stream size will be treated as unknown. @note The callbacks may be called asynchronously (from another thread). A single stream instance need not be reentrant. However the open_cb needs to be reentrant if the media is used by multiple player instances. @warning The callbacks may be used until all or any player instances that were supplied the media item are stopped. See L{media_release}.
2919+ @version: LibVLC 3.0.0 and later.
2920+ '''
2921+ return libvlc_media_new_callbacks(self, open_cb, read_cb, seek_cb, close_cb, opaque)
2922+
2923+
2924+ def media_new_as_node(self, psz_name):
2925+ '''Create a media as an empty node with a given name.
2926+ See L{media_release}.
2927+ @param psz_name: the name of the node.
2928+ @return: the new empty media or None on error.
2929+ '''
2930+ return libvlc_media_new_as_node(self, str_to_bytes(psz_name))
2931+
2932+
2933+ def renderer_discoverer_new(self, psz_name):
2934+ '''Create a renderer discoverer object by name
2935+ After this object is created, you should attach to events in order to be
2936+ notified of the discoverer events.
2937+ You need to call L{renderer_discoverer_start}() in order to start the
2938+ discovery.
2939+ See L{renderer_discoverer_event_manager}()
2940+ See L{renderer_discoverer_start}().
2941+ @param psz_name: service name; use L{renderer_discoverer_list_get}() to get a list of the discoverer names available in this libVLC instance.
2942+ @return: media discover object or None in case of error.
2943+ @version: LibVLC 3.0.0 or later.
2944+ '''
2945+ return libvlc_renderer_discoverer_new(self, str_to_bytes(psz_name))
2946+
2947+
2948+ def renderer_discoverer_list_get(self, ppp_services):
2949+ '''Get media discoverer services
2950+ See libvlc_renderer_list_release().
2951+ @param ppp_services: address to store an allocated array of renderer discoverer services (must be freed with libvlc_renderer_list_release() by the caller) [OUT].
2952+ @return: the number of media discoverer services (0 on error).
2953+ @version: LibVLC 3.0.0 and later.
2954+ '''
2955+ return libvlc_renderer_discoverer_list_get(self, ppp_services)
2956+
2957+
2958+ def audio_output_device_count(self, psz_audio_output):
2959+ '''Backward compatibility stub. Do not use in new code.
2960+ \deprecated Use L{audio_output_device_list_get}() instead.
2961+ @return: always 0.
2962+ '''
2963+ return libvlc_audio_output_device_count(self, str_to_bytes(psz_audio_output))
2964+
2965+
2966+ def audio_output_device_longname(self, psz_output, i_device):
2967+ '''Backward compatibility stub. Do not use in new code.
2968+ \deprecated Use L{audio_output_device_list_get}() instead.
2969+ @return: always None.
2970+ '''
2971+ return libvlc_audio_output_device_longname(self, str_to_bytes(psz_output), i_device)
2972+
2973+
2974+ def audio_output_device_id(self, psz_audio_output, i_device):
2975+ '''Backward compatibility stub. Do not use in new code.
2976+ \deprecated Use L{audio_output_device_list_get}() instead.
2977+ @return: always None.
2978+ '''
2979+ return libvlc_audio_output_device_id(self, str_to_bytes(psz_audio_output), i_device)
2980+
2981+
2982+ def media_discoverer_new_from_name(self, psz_name):
2983+ '''\deprecated Use L{media_discoverer_new}() and L{media_discoverer_start}().
2984+ '''
2985+ return libvlc_media_discoverer_new_from_name(self, str_to_bytes(psz_name))
2986+
2987+
2988+ def wait(self):
2989+ '''Waits until an interface causes the instance to exit.
2990+ You should start at least one interface first, using L{add_intf}().
2991+ '''
2992+ return libvlc_wait(self)
2993+
2994+
2995+ def get_log_verbosity(self):
2996+ '''Always returns minus one.
2997+ This function is only provided for backward compatibility.
2998+ @return: always -1.
2999+ '''
3000+ return libvlc_get_log_verbosity(self)
3001+
3002+
3003+ def set_log_verbosity(self, level):
3004+ '''This function does nothing.
3005+ It is only provided for backward compatibility.
3006+ @param level: ignored.
3007+ '''
3008+ return libvlc_set_log_verbosity(self, level)
3009+
3010+
3011+ def log_open(self):
3012+ '''This function does nothing useful.
3013+ It is only provided for backward compatibility.
3014+ @return: an unique pointer or None on error.
3015+ '''
3016+ return libvlc_log_open(self)
3017+
3018+
3019+ def playlist_play(self, i_id, i_options, ppsz_options):
3020+ '''Start playing (if there is any item in the playlist).
3021+ Additionnal playlist item options can be specified for addition to the
3022+ item before it is played.
3023+ @param i_id: the item to play. If this is a negative number, the next item will be selected. Otherwise, the item with the given ID will be played.
3024+ @param i_options: the number of options to add to the item.
3025+ @param ppsz_options: the options to add to the item.
3026+ '''
3027+ return libvlc_playlist_play(self, i_id, i_options, ppsz_options)
3028+
3029+
3030+ def audio_output_list_get(self):
3031+ '''Gets the list of available audio output modules.
3032+ @return: list of available audio outputs. It must be freed with In case of error, None is returned.
3033+ '''
3034+ return libvlc_audio_output_list_get(self)
3035+
3036+
3037+ def audio_output_device_list_get(self, aout):
3038+ '''Gets a list of audio output devices for a given audio output module,
3039+ See L{audio_output_device_set}().
3040+ @note: Not all audio outputs support this. In particular, an empty (None)
3041+ list of devices does B{not} imply that the specified audio output does
3042+ not work.
3043+ @note: The list might not be exhaustive.
3044+ @warning: Some audio output devices in the list might not actually work in
3045+ some circumstances. By default, it is recommended to not specify any
3046+ explicit audio device.
3047+ @param aout: audio output name (as returned by L{audio_output_list_get}()).
3048+ @return: A None-terminated linked list of potential audio output devices. It must be freed with L{audio_output_device_list_release}().
3049+ @version: LibVLC 2.1.0 or later.
3050+ '''
3051+ return libvlc_audio_output_device_list_get(self, str_to_bytes(aout))
3052+
3053+class LogIterator(_Ctype):
3054+ '''Create a new VLC log iterator.
3055+
3056+ '''
3057+
3058+ def __new__(cls, ptr=_internal_guard):
3059+ '''(INTERNAL) ctypes wrapper constructor.
3060+ '''
3061+ return _Constructor(cls, ptr)
3062+
3063+ def __iter__(self):
3064+ return self
3065+
3066+ def next(self):
3067+ if self.has_next():
3068+ b = LogMessage()
3069+ i = libvlc_log_iterator_next(self, b)
3070+ return i.contents
3071+ raise StopIteration
3072+
3073+ def __next__(self):
3074+ return self.next()
3075+
3076+
3077+
3078+ def free(self):
3079+ '''Frees memory allocated by L{log_get_iterator}().
3080+ '''
3081+ return libvlc_log_iterator_free(self)
3082+
3083+
3084+ def has_next(self):
3085+ '''Always returns zero.
3086+ This function is only provided for backward compatibility.
3087+ @return: always zero.
3088+ '''
3089+ return libvlc_log_iterator_has_next(self)
3090+
3091 class Media(_Ctype):
3092 '''Create a new Media instance.
3093-
3094+
3095 Usage: Media(MRL, *options)
3096
3097 See vlc.Instance.media_new documentation for details.
3098@@ -1945,8 +2444,15 @@
3099 """
3100 mediaTrack_pp = ctypes.POINTER(MediaTrack)()
3101 n = libvlc_media_tracks_get(self, ctypes.byref(mediaTrack_pp))
3102- info = ctypes.cast(ctypes.mediaTrack_pp, ctypes.POINTER(ctypes.POINTER(MediaTrack) * n))
3103- return info
3104+ info = ctypes.cast(mediaTrack_pp, ctypes.POINTER(ctypes.POINTER(MediaTrack) * n))
3105+ try:
3106+ contents = info.contents
3107+ except ValueError:
3108+ # Media not parsed, no info.
3109+ return None
3110+ tracks = ( contents[i].contents for i in range(len(contents)) )
3111+ # libvlc_media_tracks_release(mediaTrack_pp, n)
3112+ return tracks
3113
3114
3115
3116@@ -1984,7 +2490,7 @@
3117
3118
3119 def retain(self):
3120- '''Retain a reference to a media descriptor object (libvlc_media_t). Use
3121+ '''Retain a reference to a media descriptor object (L{Media}). Use
3122 L{release}() to decrement the reference count of a
3123 media descriptor object.
3124 '''
3125@@ -2017,11 +2523,8 @@
3126 def get_meta(self, e_meta):
3127 '''Read the meta of the media.
3128 If the media has not yet been parsed this will return None.
3129- This methods automatically calls L{parse_async}(), so after calling
3130- it you may receive a libvlc_MediaMetaChanged event. If you prefer a synchronous
3131- version ensure that you call L{parse}() before get_meta().
3132 See L{parse}
3133- See L{parse_async}
3134+ See L{parse_with_options}
3135 See libvlc_MediaMetaChanged.
3136 @param e_meta: the meta to read.
3137 @return: the media's meta.
3138@@ -2046,12 +2549,10 @@
3139
3140
3141 def get_state(self):
3142- '''Get current state of media descriptor object. Possible media states
3143- are defined in libvlc_structures.c ( libvlc_NothingSpecial=0,
3144- libvlc_Opening, libvlc_Buffering, libvlc_Playing, libvlc_Paused,
3145- libvlc_Stopped, libvlc_Ended,
3146- libvlc_Error).
3147- See libvlc_state_t.
3148+ '''Get current state of media descriptor object. Possible media states are
3149+ libvlc_NothingSpecial=0, libvlc_Opening, libvlc_Playing, libvlc_Paused,
3150+ libvlc_Stopped, libvlc_Ended, libvlc_Error.
3151+ See L{State}.
3152 @return: state of media descriptor object.
3153 '''
3154 return libvlc_media_get_state(self)
3155@@ -2089,55 +2590,162 @@
3156 return libvlc_media_get_duration(self)
3157
3158
3159+ def parse_with_options(self, parse_flag, timeout):
3160+ '''Parse the media asynchronously with options.
3161+ This fetches (local or network) art, meta data and/or tracks information.
3162+ This method is the extended version of L{parse_with_options}().
3163+ To track when this is over you can listen to libvlc_MediaParsedChanged
3164+ event. However if this functions returns an error, you will not receive any
3165+ events.
3166+ It uses a flag to specify parse options (see L{MediaParseFlag}). All
3167+ these flags can be combined. By default, media is parsed if it's a local
3168+ file.
3169+ @note: Parsing can be aborted with L{parse_stop}().
3170+ See libvlc_MediaParsedChanged
3171+ See L{get_meta}
3172+ See L{tracks_get}
3173+ See L{get_parsed_status}
3174+ See L{MediaParseFlag}.
3175+ @param parse_flag: parse options:
3176+ @param timeout: maximum time allowed to preparse the media. If -1, the default "preparse-timeout" option will be used as a timeout. If 0, it will wait indefinitely. If > 0, the timeout will be used (in milliseconds).
3177+ @return: -1 in case of error, 0 otherwise.
3178+ @version: LibVLC 3.0.0 or later.
3179+ '''
3180+ return libvlc_media_parse_with_options(self, parse_flag, timeout)
3181+
3182+
3183+ def parse_stop(self):
3184+ '''Stop the parsing of the media
3185+ When the media parsing is stopped, the libvlc_MediaParsedChanged event will
3186+ be sent with the libvlc_media_parsed_status_timeout status.
3187+ See L{parse_with_options}.
3188+ @version: LibVLC 3.0.0 or later.
3189+ '''
3190+ return libvlc_media_parse_stop(self)
3191+
3192+
3193+ def get_parsed_status(self):
3194+ '''Get Parsed status for media descriptor object.
3195+ See libvlc_MediaParsedChanged
3196+ See L{MediaParsedStatus}.
3197+ @return: a value of the L{MediaParsedStatus} enum.
3198+ @version: LibVLC 3.0.0 or later.
3199+ '''
3200+ return libvlc_media_get_parsed_status(self)
3201+
3202+
3203+ def set_user_data(self, p_new_user_data):
3204+ '''Sets media descriptor's user_data. user_data is specialized data
3205+ accessed by the host application, VLC.framework uses it as a pointer to
3206+ an native object that references a L{Media} pointer.
3207+ @param p_new_user_data: pointer to user data.
3208+ '''
3209+ return libvlc_media_set_user_data(self, p_new_user_data)
3210+
3211+
3212+ def get_user_data(self):
3213+ '''Get media descriptor's user_data. user_data is specialized data
3214+ accessed by the host application, VLC.framework uses it as a pointer to
3215+ an native object that references a L{Media} pointer.
3216+ '''
3217+ return libvlc_media_get_user_data(self)
3218+
3219+
3220+ def get_type(self):
3221+ '''Get the media type of the media descriptor object.
3222+ @return: media type.
3223+ @version: LibVLC 3.0.0 and later. See L{MediaType}.
3224+ '''
3225+ return libvlc_media_get_type(self)
3226+
3227+
3228+ def slaves_add(self, i_type, i_priority, psz_uri):
3229+ '''Add a slave to the current media.
3230+ A slave is an external input source that may contains an additional subtitle
3231+ track (like a .srt) or an additional audio track (like a .ac3).
3232+ @note: This function must be called before the media is parsed (via
3233+ L{parse_with_options}()) or before the media is played (via
3234+ L{player_play}()).
3235+ @param i_type: subtitle or audio.
3236+ @param i_priority: from 0 (low priority) to 4 (high priority).
3237+ @param psz_uri: Uri of the slave (should contain a valid scheme).
3238+ @return: 0 on success, -1 on error.
3239+ @version: LibVLC 3.0.0 and later.
3240+ '''
3241+ return libvlc_media_slaves_add(self, i_type, i_priority, str_to_bytes(psz_uri))
3242+
3243+
3244+ def slaves_clear(self):
3245+ '''Clear all slaves previously added by L{slaves_add}() or
3246+ internally.
3247+ @version: LibVLC 3.0.0 and later.
3248+ '''
3249+ return libvlc_media_slaves_clear(self)
3250+
3251+
3252+ def slaves_get(self, ppp_slaves):
3253+ '''Get a media descriptor's slave list
3254+ The list will contain slaves parsed by VLC or previously added by
3255+ L{slaves_add}(). The typical use case of this function is to save
3256+ a list of slave in a database for a later use.
3257+ @param ppp_slaves: address to store an allocated array of slaves (must be freed with L{slaves_release}()) [OUT].
3258+ @return: the number of slaves (zero on error).
3259+ @version: LibVLC 3.0.0 and later. See L{slaves_add}.
3260+ '''
3261+ return libvlc_media_slaves_get(self, ppp_slaves)
3262+
3263+
3264 def parse(self):
3265 '''Parse a media.
3266- This fetches (local) meta data and tracks information.
3267+ This fetches (local) art, meta data and tracks information.
3268 The method is synchronous.
3269- See L{parse_async}
3270+ \deprecated This function could block indefinitely.
3271+ Use L{parse_with_options}() instead
3272+ See L{parse_with_options}
3273 See L{get_meta}
3274- See libvlc_media_get_tracks_info.
3275+ See L{get_tracks_info}.
3276 '''
3277 return libvlc_media_parse(self)
3278
3279
3280 def parse_async(self):
3281 '''Parse a media.
3282- This fetches (local) meta data and tracks information.
3283+ This fetches (local) art, meta data and tracks information.
3284 The method is the asynchronous of L{parse}().
3285 To track when this is over you can listen to libvlc_MediaParsedChanged
3286 event. However if the media was already parsed you will not receive this
3287 event.
3288+ \deprecated You can't be sure to receive the libvlc_MediaParsedChanged
3289+ event (you can wait indefinitely for this event).
3290+ Use L{parse_with_options}() instead
3291 See L{parse}
3292 See libvlc_MediaParsedChanged
3293 See L{get_meta}
3294- See libvlc_media_get_tracks_info.
3295+ See L{get_tracks_info}.
3296 '''
3297 return libvlc_media_parse_async(self)
3298
3299
3300 def is_parsed(self):
3301- '''Get Parsed status for media descriptor object.
3302+ '''Return true is the media descriptor object is parsed
3303+ \deprecated This can return true in case of failure.
3304+ Use L{get_parsed_status}() instead
3305 See libvlc_MediaParsedChanged.
3306 @return: true if media object has been parsed otherwise it returns false \libvlc_return_bool.
3307 '''
3308 return libvlc_media_is_parsed(self)
3309
3310
3311- def set_user_data(self, p_new_user_data):
3312- '''Sets media descriptor's user_data. user_data is specialized data
3313- accessed by the host application, VLC.framework uses it as a pointer to
3314- an native object that references a L{Media} pointer.
3315- @param p_new_user_data: pointer to user data.
3316- '''
3317- return libvlc_media_set_user_data(self, p_new_user_data)
3318-
3319-
3320- def get_user_data(self):
3321- '''Get media descriptor's user_data. user_data is specialized data
3322- accessed by the host application, VLC.framework uses it as a pointer to
3323- an native object that references a L{Media} pointer.
3324- '''
3325- return libvlc_media_get_user_data(self)
3326+ def get_tracks_info(self):
3327+ '''Get media descriptor's elementary streams description
3328+ Note, you need to call L{parse}() or play the media at least once
3329+ before calling this function.
3330+ Not doing this will result in an empty array.
3331+ \deprecated Use L{tracks_get}() instead.
3332+ @param tracks: address to store an allocated array of Elementary Streams descriptions (must be freed by the caller) [OUT].
3333+ @return: the number of Elementary Streams.
3334+ '''
3335+ return libvlc_media_get_tracks_info(self)
3336
3337
3338 def player_new_from_media(self):
3339@@ -2155,6 +2763,25 @@
3340 '''
3341 return _Constructor(cls, ptr)
3342
3343+ def start(self):
3344+ '''Start media discovery.
3345+ To stop it, call L{stop}() or
3346+ L{list_release}() directly.
3347+ See L{stop}.
3348+ @return: -1 in case of error, 0 otherwise.
3349+ @version: LibVLC 3.0.0 or later.
3350+ '''
3351+ return libvlc_media_discoverer_start(self)
3352+
3353+
3354+ def stop(self):
3355+ '''Stop media discovery.
3356+ See L{start}.
3357+ @version: LibVLC 3.0.0 or later.
3358+ '''
3359+ return libvlc_media_discoverer_stop(self)
3360+
3361+
3362 def release(self):
3363 '''Release media discover object. If the reference count reaches 0, then
3364 the object will be released.
3365@@ -2162,26 +2789,12 @@
3366 return libvlc_media_discoverer_release(self)
3367
3368
3369- def localized_name(self):
3370- '''Get media service discover object its localized name.
3371- @return: localized name.
3372- '''
3373- return libvlc_media_discoverer_localized_name(self)
3374-
3375-
3376 def media_list(self):
3377 '''Get media service discover media list.
3378 @return: list of media items.
3379 '''
3380 return libvlc_media_discoverer_media_list(self)
3381
3382- @memoize_parameterless
3383- def event_manager(self):
3384- '''Get event manager from media service discover object.
3385- @return: event manager object.
3386- '''
3387- return libvlc_media_discoverer_event_manager(self)
3388-
3389
3390 def is_running(self):
3391 '''Query if media service discover object is running.
3392@@ -2189,6 +2802,24 @@
3393 '''
3394 return libvlc_media_discoverer_is_running(self)
3395
3396+
3397+ def localized_name(self):
3398+ '''Get media service discover object its localized name.
3399+ \deprecated Useless, use L{list_get}() to get the
3400+ longname of the service discovery.
3401+ @return: localized name or None if the media_discoverer is not started.
3402+ '''
3403+ return libvlc_media_discoverer_localized_name(self)
3404+
3405+ @memoize_parameterless
3406+ def event_manager(self):
3407+ '''Get event manager from media service discover object.
3408+ \deprecated Useless, media_discoverer events are only triggered when calling
3409+ L{start}() and L{stop}().
3410+ @return: event manager object.
3411+ '''
3412+ return libvlc_media_discoverer_event_manager(self)
3413+
3414 class MediaLibrary(_Ctype):
3415 '''N/A
3416 '''
3417@@ -2229,7 +2860,7 @@
3418
3419 class MediaList(_Ctype):
3420 '''Create a new MediaList instance.
3421-
3422+
3423 Usage: MediaList(list_of_MRLs)
3424
3425 See vlc.Instance.media_list_new documentation for details.
3426@@ -2249,10 +2880,10 @@
3427
3428 def get_instance(self):
3429 return getattr(self, '_instance', None)
3430-
3431+
3432 def add_media(self, mrl):
3433 """Add media instance to media list.
3434-
3435+
3436 The L{lock} should be held upon entering this function.
3437 @param mrl: a media instance or a MRL.
3438 @return: 0 on success, -1 if the media list is read-only.
3439@@ -2435,6 +3066,13 @@
3440 return libvlc_media_list_player_set_media_player(self, p_mi)
3441
3442
3443+ def get_media_player(self):
3444+ '''Get media player of the media_list_player instance.
3445+ @return: media player instance @note the caller is responsible for releasing the returned instance.
3446+ '''
3447+ return libvlc_media_list_player_get_media_player(self)
3448+
3449+
3450 def set_media_list(self, p_mlist):
3451 '''Set the media list associated with the player.
3452 @param p_mlist: list of media.
3453@@ -2454,6 +3092,14 @@
3454 return libvlc_media_list_player_pause(self)
3455
3456
3457+ def set_pause(self, do_pause):
3458+ '''Pause or resume media list.
3459+ @param do_pause: play/resume if zero, pause if non-zero.
3460+ @version: LibVLC 3.0.0 or later.
3461+ '''
3462+ return libvlc_media_list_player_set_pause(self, do_pause)
3463+
3464+
3465 def is_playing(self):
3466 '''Is media list playing?
3467 @return: true for playing and false for not playing \libvlc_return_bool.
3468@@ -2463,7 +3109,7 @@
3469
3470 def get_state(self):
3471 '''Get current libvlc_state of media list player.
3472- @return: libvlc_state_t for media list player.
3473+ @return: L{State} for media list player.
3474 '''
3475 return libvlc_media_list_player_get_state(self)
3476
3477@@ -2529,7 +3175,7 @@
3478 def __new__(cls, *args):
3479 if len(args) == 1 and isinstance(args[0], _Ints):
3480 return _Constructor(cls, args[0])
3481-
3482+
3483 if args and isinstance(args[0], Instance):
3484 instance = args[0]
3485 args = args[1:]
3486@@ -2595,19 +3241,31 @@
3487 '''
3488 titleDescription_pp = ctypes.POINTER(TitleDescription)()
3489 n = libvlc_media_player_get_full_title_descriptions(self, ctypes.byref(titleDescription_pp))
3490- info = ctypes.cast(ctypes.titleDescription_pp, ctypes.POINTER(ctypes.POINTER(TitleDescription) * n))
3491- return info
3492+ info = ctypes.cast(titleDescription_pp, ctypes.POINTER(ctypes.POINTER(TitleDescription) * n))
3493+ try:
3494+ contents = info.contents
3495+ except ValueError:
3496+ # Media not parsed, no info.
3497+ return None
3498+ descr = ( contents[i].contents for i in range(len(contents)) )
3499+ return descr
3500
3501 def get_full_chapter_descriptions(self, i_chapters_of_title):
3502 '''Get the full description of available chapters.
3503- @param index: of the title to query for chapters.
3504- @return: the chapter list
3505+ @param i_chapters_of_title: index of the title to query for chapters (uses current title if set to -1).
3506+ @return: the chapters list
3507 @version: LibVLC 3.0.0 and later.
3508 '''
3509 chapterDescription_pp = ctypes.POINTER(ChapterDescription)()
3510 n = libvlc_media_player_get_full_chapter_descriptions(self, ctypes.byref(chapterDescription_pp))
3511- info = ctypes.cast(ctypes.chapterDescription_pp, ctypes.POINTER(ctypes.POINTER(ChapterDescription) * n))
3512- return info
3513+ info = ctypes.cast(chapterDescription_pp, ctypes.POINTER(ctypes.POINTER(ChapterDescription) * n))
3514+ try:
3515+ contents = info.contents
3516+ except ValueError:
3517+ # Media not parsed, no info.
3518+ return None
3519+ descr = ( contents[i].contents for i in range(len(contents)) )
3520+ return descr
3521
3522 def video_get_size(self, num=0):
3523 """Get the video size in pixels as 2-tuple (width, height).
3524@@ -2626,13 +3284,13 @@
3525 Specify where the media player should render its video
3526 output. If LibVLC was built without Win32/Win64 API output
3527 support, then this has no effects.
3528-
3529+
3530 @param drawable: windows handle of the drawable.
3531 """
3532 if not isinstance(drawable, ctypes.c_void_p):
3533 drawable = ctypes.c_void_p(int(drawable))
3534 libvlc_media_player_set_hwnd(self, drawable)
3535-
3536+
3537 def video_get_width(self, num=0):
3538 """Get the width of a video in pixels.
3539
3540@@ -2673,6 +3331,45 @@
3541
3542
3543
3544+ def get_fps(self):
3545+ '''Get movie fps rate
3546+ This function is provided for backward compatibility. It cannot deal with
3547+ multiple video tracks. In LibVLC versions prior to 3.0, it would also fail
3548+ if the file format did not convey the frame rate explicitly.
3549+ \deprecated Consider using L{media_tracks_get}() instead.
3550+ @return: frames per second (fps) for this playing movie, or 0 if unspecified.
3551+ '''
3552+ return libvlc_media_player_get_fps(self)
3553+
3554+
3555+ def set_agl(self, drawable):
3556+ '''\deprecated Use L{set_nsobject}() instead.
3557+ '''
3558+ return libvlc_media_player_set_agl(self, drawable)
3559+
3560+
3561+ def get_agl(self):
3562+ '''\deprecated Use L{get_nsobject}() instead.
3563+ '''
3564+ return libvlc_media_player_get_agl(self)
3565+
3566+
3567+ def video_set_subtitle_file(self, psz_subtitle):
3568+ '''Set new video subtitle file.
3569+ \deprecated Use L{add_slave}() instead.
3570+ @param psz_subtitle: new video subtitle file.
3571+ @return: the success status (boolean).
3572+ '''
3573+ return libvlc_video_set_subtitle_file(self, str_to_bytes(psz_subtitle))
3574+
3575+
3576+ def toggle_teletext(self):
3577+ '''Toggle teletext transparent status on video output.
3578+ \deprecated use L{video_set_teletext}() instead.
3579+ '''
3580+ return libvlc_toggle_teletext(self)
3581+
3582+
3583 def release(self):
3584 '''Release a media_player after use
3585 Decrement the reference count of a media player object. If the
3586@@ -2746,11 +3443,43 @@
3587 return libvlc_media_player_stop(self)
3588
3589
3590+ def set_renderer(self, p_item):
3591+ '''Set a renderer to the media player
3592+ @note: must be called before the first call of L{play}() to
3593+ take effect.
3594+ See L{renderer_discoverer_new}.
3595+ @param p_item: an item discovered by L{renderer_discoverer_start}().
3596+ @return: 0 on success, -1 on error.
3597+ @version: LibVLC 3.0.0 or later.
3598+ '''
3599+ return libvlc_media_player_set_renderer(self, p_item)
3600+
3601+
3602 def video_set_callbacks(self, lock, unlock, display, opaque):
3603 '''Set callbacks and private data to render decoded video to a custom area
3604 in memory.
3605 Use L{video_set_format}() or L{video_set_format_callbacks}()
3606 to configure the decoded format.
3607+ @warning: Rendering video into custom memory buffers is considerably less
3608+ efficient than rendering in a custom window as normal.
3609+ For optimal perfomances, VLC media player renders into a custom window, and
3610+ does not use this function and associated callbacks. It is B{highly
3611+ recommended} that other LibVLC-based application do likewise.
3612+ To embed video in a window, use libvlc_media_player_set_xid() or equivalent
3613+ depending on the operating system.
3614+ If window embedding does not fit the application use case, then a custom
3615+ LibVLC video output display plugin is required to maintain optimal video
3616+ rendering performances.
3617+ The following limitations affect performance:
3618+ - Hardware video decoding acceleration will either be disabled completely,
3619+ or require (relatively slow) copy from video/DSP memory to main memory.
3620+ - Sub-pictures (subtitles, on-screen display, etc.) must be blent into the
3621+ main picture by the CPU instead of the GPU.
3622+ - Depending on the video format, pixel format conversion, picture scaling,
3623+ cropping and/or picture re-orientation, must be performed by the CPU
3624+ instead of the GPU.
3625+ - Memory copying is required between LibVLC reference picture buffers and
3626+ application buffers (between lock and unlock callbacks).
3627 @param lock: callback to lock video memory (must not be None).
3628 @param unlock: callback to unlock video memory (or None if not needed).
3629 @param display: callback to display video (or None if not needed).
3630@@ -2789,16 +3518,16 @@
3631 Use the vout called "macosx".
3632 The drawable is an NSObject that follow the VLCOpenGLVideoViewEmbedding
3633 protocol:
3634- @begincode
3635+ @code.m
3636 \@protocol VLCOpenGLVideoViewEmbedding <NSObject>
3637 - (void)addVoutSubview:(NSView *)view;
3638 - (void)removeVoutSubview:(NSView *)view;
3639 \@end
3640 @endcode
3641 Or it can be an NSView object.
3642- If you want to use it along with Qt4 see the QMacCocoaViewContainer. Then
3643+ If you want to use it along with Qt see the QMacCocoaViewContainer. Then
3644 the following code should work:
3645- @begincode
3646+ @code.mm
3647
3648 NSView *video = [[NSView alloc] init];
3649 QMacCocoaViewContainer *container = new QMacCocoaViewContainer(video, parent);
3650@@ -2819,30 +3548,25 @@
3651 return libvlc_media_player_get_nsobject(self)
3652
3653
3654- def set_agl(self, drawable):
3655- '''Set the agl handler where the media player should render its video output.
3656- @param drawable: the agl handler.
3657- '''
3658- return libvlc_media_player_set_agl(self, drawable)
3659-
3660-
3661- def get_agl(self):
3662- '''Get the agl handler previously set with L{set_agl}().
3663- @return: the agl handler or 0 if none where set.
3664- '''
3665- return libvlc_media_player_get_agl(self)
3666-
3667-
3668 def set_xwindow(self, drawable):
3669 '''Set an X Window System drawable where the media player should render its
3670- video output. If LibVLC was built without X11 output support, then this has
3671- no effects.
3672- The specified identifier must correspond to an existing Input/Output class
3673- X11 window. Pixmaps are B{not} supported. The caller shall ensure that
3674- the X11 server is the same as the one the VLC instance has been configured
3675- with. This function must be called before video playback is started;
3676- otherwise it will only take effect after playback stop and restart.
3677- @param drawable: the ID of the X window.
3678+ video output. The call takes effect when the playback starts. If it is
3679+ already started, it might need to be stopped before changes apply.
3680+ If LibVLC was built without X11 output support, then this function has no
3681+ effects.
3682+ By default, LibVLC will capture input events on the video rendering area.
3683+ Use L{video_set_mouse_input}() and L{video_set_key_input}() to
3684+ disable that and deliver events to the parent window / to the application
3685+ instead. By design, the X11 protocol delivers input events to only one
3686+ recipient.
3687+ @warning
3688+ The application must call the XInitThreads() function from Xlib before
3689+ L{new}(), and before any call to XOpenDisplay() directly or via any
3690+ other library. Failure to call XInitThreads() will seriously impede LibVLC
3691+ performance. Calling XOpenDisplay() before XInitThreads() will eventually
3692+ crash the process. That is a limitation of Xlib.
3693+ @param drawable: X11 window ID @note The specified identifier must correspond to an existing Input/Output class X11 window. Pixmaps are B{not} currently supported. The default X11 server is assumed, i.e. that specified in the DISPLAY environment variable. @warning LibVLC can deal with invalid X11 handle errors, however some display drivers (EGL, GLX, VA and/or VDPAU) can unfortunately not. Thus the window handle must remain valid until playback is stopped, otherwise the process may abort or crash.
3694+ @bug No more than one window handle per media player instance can be specified. If the media has multiple simultaneously active video tracks, extra tracks will be rendered into external windows beyond the control of the application.
3695 '''
3696 return libvlc_media_player_set_xwindow(self, drawable)
3697
3698@@ -2866,10 +3590,29 @@
3699 return libvlc_media_player_get_hwnd(self)
3700
3701
3702+ def set_android_context(self, p_awindow_handler):
3703+ '''Set the android context.
3704+ @param p_awindow_handler: org.videolan.libvlc.AWindow jobject owned by the org.videolan.libvlc.MediaPlayer class from the libvlc-android project.
3705+ @version: LibVLC 3.0.0 and later.
3706+ '''
3707+ return libvlc_media_player_set_android_context(self, p_awindow_handler)
3708+
3709+
3710+ def set_evas_object(self, p_evas_object):
3711+ '''Set the EFL Evas Object.
3712+ @param p_evas_object: a valid EFL Evas Object (Evas_Object).
3713+ @return: -1 if an error was detected, 0 otherwise.
3714+ @version: LibVLC 3.0.0 and later.
3715+ '''
3716+ return libvlc_media_player_set_evas_object(self, p_evas_object)
3717+
3718+
3719 def audio_set_callbacks(self, play, pause, resume, flush, drain, opaque):
3720- '''Set callbacks and private data for decoded audio.
3721+ '''Sets callbacks and private data for decoded audio.
3722 Use L{audio_set_format}() or L{audio_set_format_callbacks}()
3723 to configure the decoded audio format.
3724+ @note: The audio callbacks override any other audio output mechanism.
3725+ If the callbacks are set, LibVLC will B{not} output audio in any way.
3726 @param play: callback to play audio samples (must not be None).
3727 @param pause: callback to pause playback (or None to ignore).
3728 @param resume: callback to resume playback (or None to ignore).
3729@@ -2893,8 +3636,8 @@
3730
3731
3732 def audio_set_format_callbacks(self, setup, cleanup):
3733- '''Set decoded audio format. This only works in combination with
3734- L{audio_set_callbacks}().
3735+ '''Sets decoded audio format via callbacks.
3736+ This only works in combination with L{audio_set_callbacks}().
3737 @param setup: callback to select the audio format (cannot be None).
3738 @param cleanup: callback to release any allocated resources (or None).
3739 @version: LibVLC 2.0.0 or later.
3740@@ -2903,7 +3646,7 @@
3741
3742
3743 def audio_set_format(self, format, rate, channels):
3744- '''Set decoded audio format.
3745+ '''Sets a fixed decoded audio format.
3746 This only works in combination with L{audio_set_callbacks}(),
3747 and is mutually exclusive with L{audio_set_format_callbacks}().
3748 @param format: a four-characters string identifying the sample format (e.g. "S16N" or "FL32").
3749@@ -3040,18 +3783,11 @@
3750
3751 def get_state(self):
3752 '''Get current movie state.
3753- @return: the current state of the media player (playing, paused, ...) See libvlc_state_t.
3754+ @return: the current state of the media player (playing, paused, ...) See L{State}.
3755 '''
3756 return libvlc_media_player_get_state(self)
3757
3758
3759- def get_fps(self):
3760- '''Get movie fps rate.
3761- @return: frames per second (fps) for this playing movie, or 0 if unspecified.
3762- '''
3763- return libvlc_media_player_get_fps(self)
3764-
3765-
3766 def has_vout(self):
3767 '''How many video outputs does this media player have?
3768 @return: the number of video outputs.
3769@@ -3104,6 +3840,19 @@
3770 return libvlc_media_player_set_video_title_display(self, position, timeout)
3771
3772
3773+ def add_slave(self, i_type, psz_uri, b_select):
3774+ '''Add a slave to the current media player.
3775+ @note: If the player is playing, the slave will be added directly. This call
3776+ will also update the slave list of the attached L{Media}.
3777+ @param i_type: subtitle or audio.
3778+ @param psz_uri: Uri of the slave (should contain a valid scheme).
3779+ @param b_select: True if this slave should be selected when it's loaded.
3780+ @return: 0 on success, -1 on error.
3781+ @version: LibVLC 3.0.0 and later. See L{media_slaves_add}.
3782+ '''
3783+ return libvlc_media_player_add_slave(self, i_type, str_to_bytes(psz_uri), b_select)
3784+
3785+
3786 def toggle_fullscreen(self):
3787 '''Toggle fullscreen status on non-embedded video outputs.
3788 @warning: The same limitations applies to this function
3789@@ -3190,6 +3939,17 @@
3790 return libvlc_video_set_aspect_ratio(self, str_to_bytes(psz_aspect))
3791
3792
3793+ def video_update_viewpoint(self, p_viewpoint, b_absolute):
3794+ '''Update the video viewpoint information.
3795+ @note: It is safe to call this function before the media player is started.
3796+ @param p_viewpoint: video viewpoint allocated via L{video_new_viewpoint}().
3797+ @param b_absolute: if true replace the old viewpoint with the new one. If false, increase/decrease it.
3798+ @return: -1 in case of error, 0 otherwise @note the values are set asynchronously, it will be used by the next frame displayed.
3799+ @version: LibVLC 3.0.0 and later.
3800+ '''
3801+ return libvlc_video_update_viewpoint(self, p_viewpoint, b_absolute)
3802+
3803+
3804 def video_get_spu(self):
3805 '''Get current video subtitle.
3806 @return: the video subtitle selected, or -1 if none.
3807@@ -3212,14 +3972,6 @@
3808 return libvlc_video_set_spu(self, i_spu)
3809
3810
3811- def video_set_subtitle_file(self, psz_subtitle):
3812- '''Set new video subtitle file.
3813- @param psz_subtitle: new video subtitle file.
3814- @return: the success status (boolean).
3815- '''
3816- return libvlc_video_set_subtitle_file(self, str_to_bytes(psz_subtitle))
3817-
3818-
3819 def video_get_spu_delay(self):
3820 '''Get the current subtitle delay. Positive values means subtitles are being
3821 displayed later, negative values earlier.
3822@@ -3256,7 +4008,9 @@
3823
3824
3825 def video_get_teletext(self):
3826- '''Get current teletext page requested.
3827+ '''Get current teletext page requested or 0 if it's disabled.
3828+ Teletext is disabled by default, call L{video_set_teletext}() to enable
3829+ it.
3830 @return: the current teletext page requested.
3831 '''
3832 return libvlc_video_get_teletext(self)
3833@@ -3264,17 +4018,12 @@
3834
3835 def video_set_teletext(self, i_page):
3836 '''Set new teletext page to retrieve.
3837- @param i_page: teletex page number requested.
3838+ This function can also be used to send a teletext key.
3839+ @param i_page: teletex page number requested. This value can be 0 to disable teletext, a number in the range ]0;1000[ to show the requested page, or a \ref L{TeletextKey}. 100 is the default teletext page.
3840 '''
3841 return libvlc_video_set_teletext(self, i_page)
3842
3843
3844- def toggle_teletext(self):
3845- '''Toggle teletext transparent status on video output.
3846- '''
3847- return libvlc_toggle_teletext(self)
3848-
3849-
3850 def video_get_track_count(self):
3851 '''Get number of available video tracks.
3852 @return: the number of available video tracks (int).
3853@@ -3302,7 +4051,7 @@
3854 If i_width AND i_height is 0, original size is used.
3855 If i_width XOR i_height is 0, original aspect-ratio is preserved.
3856 @param num: number of video output (typically 0 for the first/only one).
3857- @param psz_filepath: the path where to save the screenshot to.
3858+ @param psz_filepath: the path of a file or a folder to save the screenshot into.
3859 @param i_width: the snapshot's width.
3860 @param i_height: the snapshot's height.
3861 @return: 0 on success, -1 if the video was not found.
3862@@ -3351,7 +4100,7 @@
3863
3864 def video_get_logo_int(self, option):
3865 '''Get integer logo option.
3866- @param option: logo option to get, values of libvlc_video_logo_option_t.
3867+ @param option: logo option to get, values of L{VideoLogoOption}.
3868 '''
3869 return libvlc_video_get_logo_int(self, option)
3870
3871@@ -3361,7 +4110,7 @@
3872 are ignored.
3873 Passing libvlc_logo_enable as option value has the side effect of
3874 starting (arg !0) or stopping (arg 0) the logo filter.
3875- @param option: logo option to set, values of libvlc_video_logo_option_t.
3876+ @param option: logo option to set, values of L{VideoLogoOption}.
3877 @param value: logo option value.
3878 '''
3879 return libvlc_video_set_logo_int(self, option, value)
3880@@ -3370,7 +4119,7 @@
3881 def video_set_logo_string(self, option, psz_value):
3882 '''Set logo option as string. Options that take a different type value
3883 are ignored.
3884- @param option: logo option to set, values of libvlc_video_logo_option_t.
3885+ @param option: logo option to set, values of L{VideoLogoOption}.
3886 @param psz_value: logo option value.
3887 '''
3888 return libvlc_video_set_logo_string(self, option, str_to_bytes(psz_value))
3889@@ -3378,7 +4127,7 @@
3890
3891 def video_get_adjust_int(self, option):
3892 '''Get integer adjust option.
3893- @param option: adjust option to get, values of libvlc_video_adjust_option_t.
3894+ @param option: adjust option to get, values of L{VideoAdjustOption}.
3895 @version: LibVLC 1.1.1 and later.
3896 '''
3897 return libvlc_video_get_adjust_int(self, option)
3898@@ -3389,7 +4138,7 @@
3899 are ignored.
3900 Passing libvlc_adjust_enable as option value has the side effect of
3901 starting (arg !0) or stopping (arg 0) the adjust filter.
3902- @param option: adust option to set, values of libvlc_video_adjust_option_t.
3903+ @param option: adust option to set, values of L{VideoAdjustOption}.
3904 @param value: adjust option value.
3905 @version: LibVLC 1.1.1 and later.
3906 '''
3907@@ -3398,7 +4147,7 @@
3908
3909 def video_get_adjust_float(self, option):
3910 '''Get float adjust option.
3911- @param option: adjust option to get, values of libvlc_video_adjust_option_t.
3912+ @param option: adjust option to get, values of L{VideoAdjustOption}.
3913 @version: LibVLC 1.1.1 and later.
3914 '''
3915 return libvlc_video_get_adjust_float(self, option)
3916@@ -3407,7 +4156,7 @@
3917 def video_set_adjust_float(self, option, value):
3918 '''Set adjust option as float. Options that take a different type value
3919 are ignored.
3920- @param option: adust option to set, values of libvlc_video_adjust_option_t.
3921+ @param option: adust option to set, values of L{VideoAdjustOption}.
3922 @param value: adjust option value.
3923 @version: LibVLC 1.1.1 and later.
3924 '''
3925@@ -3419,7 +4168,7 @@
3926 @note: Any change will take be effect only after playback is stopped and
3927 restarted. Audio output cannot be changed while playing.
3928 @param psz_name: name of audio output, use psz_name of See L{AudioOutput}.
3929- @return: 0 if function succeded, -1 on error.
3930+ @return: 0 if function succeeded, -1 on error.
3931 '''
3932 return libvlc_audio_output_set(self, str_to_bytes(psz_name))
3933
3934@@ -3433,7 +4182,7 @@
3935 @warning: Some audio output devices in the list might not actually work in
3936 some circumstances. By default, it is recommended to not specify any
3937 explicit audio device.
3938- @return: A None-terminated linked list of potential audio output devices. It must be freed it with L{audio_output_device_list_release}().
3939+ @return: A None-terminated linked list of potential audio output devices. It must be freed with L{audio_output_device_list_release}().
3940 @version: LibVLC 2.2.0 or later.
3941 '''
3942 return libvlc_audio_output_device_enum(self)
3943@@ -3467,6 +4216,24 @@
3944 return libvlc_audio_output_device_set(self, str_to_bytes(module), str_to_bytes(device_id))
3945
3946
3947+ def audio_output_device_get(self):
3948+ '''Get the current audio output device identifier.
3949+ This complements L{audio_output_device_set}().
3950+ @warning: The initial value for the current audio output device identifier
3951+ may not be set or may be some unknown value. A LibVLC application should
3952+ compare this value against the known device identifiers (e.g. those that
3953+ were previously retrieved by a call to L{audio_output_device_enum} or
3954+ L{audio_output_device_list_get}) to find the current audio output device.
3955+ It is possible that the selected audio output device changes (an external
3956+ change) without a call to L{audio_output_device_set}. That may make this
3957+ method unsuitable to use if a LibVLC application is attempting to track
3958+ dynamic audio device changes as they happen.
3959+ @return: the current audio output device identifier None if no device is selected or in case of error (the result must be released with free() or L{free}()).
3960+ @version: LibVLC 3.0.0 or later.
3961+ '''
3962+ return libvlc_audio_output_device_get(self)
3963+
3964+
3965 def audio_toggle_mute(self):
3966 '''Toggle mute status.
3967 '''
3968@@ -3526,14 +4293,14 @@
3969
3970 def audio_get_channel(self):
3971 '''Get current audio channel.
3972- @return: the audio channel See libvlc_audio_output_channel_t.
3973+ @return: the audio channel See L{AudioOutputChannel}.
3974 '''
3975 return libvlc_audio_get_channel(self)
3976
3977
3978 def audio_set_channel(self, channel):
3979 '''Set current audio channel.
3980- @param channel: the audio channel, See libvlc_audio_output_channel_t.
3981+ @param channel: the audio channel, See L{AudioOutputChannel}.
3982 @return: 0 on success, -1 on error.
3983 '''
3984 return libvlc_audio_set_channel(self, channel)
3985@@ -3578,21 +4345,25 @@
3986 '''
3987 return libvlc_media_player_set_equalizer(self, p_equalizer)
3988
3989+
3990+ def get_role(self):
3991+ '''Gets the media role.
3992+ @return: the media player role (\ref libvlc_media_player_role_t).
3993+ @version: LibVLC 3.0.0 and later.
3994+ '''
3995+ return libvlc_media_player_get_role(self)
3996+
3997+
3998+ def set_role(self, role):
3999+ '''Sets the media role.
4000+ @param role: the media player role (\ref libvlc_media_player_role_t).
4001+ @return: 0 on success, -1 on error.
4002+ '''
4003+ return libvlc_media_player_set_role(self, role)
4004+
4005
4006 # LibVLC __version__ functions #
4007
4008-def libvlc_errmsg():
4009- '''A human-readable error message for the last LibVLC error in the calling
4010- thread. The resulting string is valid until another error occurs (at least
4011- until the next LibVLC call).
4012- @warning
4013- This will be None if there was no error.
4014- '''
4015- f = _Cfunctions.get('libvlc_errmsg', None) or \
4016- _Cfunction('libvlc_errmsg', (), None,
4017- ctypes.c_char_p)
4018- return f()
4019-
4020 def libvlc_clearerr():
4021 '''Clears the LibVLC error status for the current thread. This is optional.
4022 By default, the error status is automatically overridden when a new error
4023@@ -3619,6 +4390,34 @@
4024 '''Create and initialize a libvlc instance.
4025 This functions accept a list of "command line" arguments similar to the
4026 main(). These arguments affect the LibVLC instance default configuration.
4027+ @note
4028+ LibVLC may create threads. Therefore, any thread-unsafe process
4029+ initialization must be performed before calling L{libvlc_new}(). In particular
4030+ and where applicable:
4031+ - setlocale() and textdomain(),
4032+ - setenv(), unsetenv() and putenv(),
4033+ - with the X11 display system, XInitThreads()
4034+ (see also L{libvlc_media_player_set_xwindow}()) and
4035+ - on Microsoft Windows, SetErrorMode().
4036+ - sigprocmask() shall never be invoked; pthread_sigmask() can be used.
4037+ On POSIX systems, the SIGCHLD signal B{must not} be ignored, i.e. the
4038+ signal handler must set to SIG_DFL or a function pointer, not SIG_IGN.
4039+ Also while LibVLC is active, the wait() function shall not be called, and
4040+ any call to waitpid() shall use a strictly positive value for the first
4041+ parameter (i.e. the PID). Failure to follow those rules may lead to a
4042+ deadlock or a busy loop.
4043+ Also on POSIX systems, it is recommended that the SIGPIPE signal be blocked,
4044+ even if it is not, in principles, necessary, e.g.:
4045+ @code
4046+ @endcode
4047+ On Microsoft Windows Vista/2008, the process error mode
4048+ SEM_FAILCRITICALERRORS flag B{must} be set before using LibVLC.
4049+ On later versions, that is optional and unnecessary.
4050+ Also on Microsoft Windows (Vista and any later version), setting the default
4051+ DLL directories to SYSTEM32 exclusively is strongly recommended for
4052+ security reasons:
4053+ @code
4054+ @endcode.
4055 @param argc: the number of arguments (should be 0).
4056 @param argv: list of arguments (should be None).
4057 @return: the libvlc instance or None in case of error.
4058@@ -3763,8 +4562,11 @@
4059 return f(event_type)
4060
4061 def libvlc_log_get_context(ctx):
4062- '''Gets debugging information about a log message: the name of the VLC module
4063- emitting the message and the message location within the source code.
4064+ '''Gets log message debug infos.
4065+ This function retrieves self-debug information about a log message:
4066+ - the name of the VLC module emitting the message,
4067+ - the name of the source code module (i.e. file) and
4068+ - the line number within the source code module.
4069 The returned module name and file name will be None if unknown.
4070 The returned line number will similarly be zero if unknown.
4071 @param ctx: message context (as passed to the @ref libvlc_log_cb callback).
4072@@ -3777,10 +4579,12 @@
4073 return f(ctx)
4074
4075 def libvlc_log_get_object(ctx, id):
4076- '''Gets VLC object information about a log message: the type name of the VLC
4077- object emitting the message, the object header if any and a temporaly-unique
4078- object identifier. This information is mainly meant for B{manual}
4079- troubleshooting.
4080+ '''Gets log message info.
4081+ This function retrieves meta-information about a log message:
4082+ - the type name of the VLC object emitting the message,
4083+ - the object header if any, and
4084+ - a temporaly-unique object identifier.
4085+ This information is mainly meant for B{manual} troubleshooting.
4086 The returned type name may be "generic" if unknown, but it cannot be None.
4087 The returned header will be None if unset; in current versions, the header
4088 is used to distinguish for VLM inputs.
4089@@ -3796,10 +4600,12 @@
4090 return f(ctx, id)
4091
4092 def libvlc_log_unset(p_instance):
4093- '''Unsets the logging callback for a LibVLC instance. This is rarely needed:
4094- the callback is implicitly unset when the instance is destroyed.
4095- This function will wait for any pending callbacks invocation to complete
4096- (causing a deadlock if called from within the callback).
4097+ '''Unsets the logging callback.
4098+ This function deregisters the logging callback for a LibVLC instance.
4099+ This is rarely needed as the callback is implicitly unset when the instance
4100+ is destroyed.
4101+ @note: This function will wait for any pending callbacks invocation to
4102+ complete (causing a deadlock if called from within the callback).
4103 @param p_instance: libvlc instance.
4104 @version: LibVLC 2.1.0 or later.
4105 '''
4106@@ -3808,7 +4614,7 @@
4107 None, Instance)
4108 return f(p_instance)
4109
4110-def libvlc_log_set(cb, data, p_instance):
4111+def libvlc_log_set(p_instance, cb, data):
4112 '''Sets the logging callback for a LibVLC instance.
4113 This function is thread-safe: it will wait for any pending callbacks
4114 invocation to complete.
4115@@ -3820,7 +4626,7 @@
4116 f = _Cfunctions.get('libvlc_log_set', None) or \
4117 _Cfunction('libvlc_log_set', ((1,), (1,), (1,),), None,
4118 None, Instance, LogCb, ctypes.c_void_p)
4119- return f(cb, data, p_instance)
4120+ return f(p_instance, cb, data)
4121
4122 def libvlc_log_set_file(p_instance, stream):
4123 '''Sets up logging to a file.
4124@@ -3875,6 +4681,522 @@
4125 ctypes.c_int64)
4126 return f()
4127
4128+def libvlc_media_discoverer_new(p_inst, psz_name):
4129+ '''Create a media discoverer object by name.
4130+ After this object is created, you should attach to media_list events in
4131+ order to be notified of new items discovered.
4132+ You need to call L{libvlc_media_discoverer_start}() in order to start the
4133+ discovery.
4134+ See L{libvlc_media_discoverer_media_list}
4135+ See L{libvlc_media_discoverer_event_manager}
4136+ See L{libvlc_media_discoverer_start}.
4137+ @param p_inst: libvlc instance.
4138+ @param psz_name: service name; use L{libvlc_media_discoverer_list_get}() to get a list of the discoverer names available in this libVLC instance.
4139+ @return: media discover object or None in case of error.
4140+ @version: LibVLC 3.0.0 or later.
4141+ '''
4142+ f = _Cfunctions.get('libvlc_media_discoverer_new', None) or \
4143+ _Cfunction('libvlc_media_discoverer_new', ((1,), (1,),), class_result(MediaDiscoverer),
4144+ ctypes.c_void_p, Instance, ctypes.c_char_p)
4145+ return f(p_inst, psz_name)
4146+
4147+def libvlc_media_discoverer_start(p_mdis):
4148+ '''Start media discovery.
4149+ To stop it, call L{libvlc_media_discoverer_stop}() or
4150+ L{libvlc_media_discoverer_list_release}() directly.
4151+ See L{libvlc_media_discoverer_stop}.
4152+ @param p_mdis: media discover object.
4153+ @return: -1 in case of error, 0 otherwise.
4154+ @version: LibVLC 3.0.0 or later.
4155+ '''
4156+ f = _Cfunctions.get('libvlc_media_discoverer_start', None) or \
4157+ _Cfunction('libvlc_media_discoverer_start', ((1,),), None,
4158+ ctypes.c_int, MediaDiscoverer)
4159+ return f(p_mdis)
4160+
4161+def libvlc_media_discoverer_stop(p_mdis):
4162+ '''Stop media discovery.
4163+ See L{libvlc_media_discoverer_start}.
4164+ @param p_mdis: media discover object.
4165+ @version: LibVLC 3.0.0 or later.
4166+ '''
4167+ f = _Cfunctions.get('libvlc_media_discoverer_stop', None) or \
4168+ _Cfunction('libvlc_media_discoverer_stop', ((1,),), None,
4169+ None, MediaDiscoverer)
4170+ return f(p_mdis)
4171+
4172+def libvlc_media_discoverer_release(p_mdis):
4173+ '''Release media discover object. If the reference count reaches 0, then
4174+ the object will be released.
4175+ @param p_mdis: media service discover object.
4176+ '''
4177+ f = _Cfunctions.get('libvlc_media_discoverer_release', None) or \
4178+ _Cfunction('libvlc_media_discoverer_release', ((1,),), None,
4179+ None, MediaDiscoverer)
4180+ return f(p_mdis)
4181+
4182+def libvlc_media_discoverer_media_list(p_mdis):
4183+ '''Get media service discover media list.
4184+ @param p_mdis: media service discover object.
4185+ @return: list of media items.
4186+ '''
4187+ f = _Cfunctions.get('libvlc_media_discoverer_media_list', None) or \
4188+ _Cfunction('libvlc_media_discoverer_media_list', ((1,),), class_result(MediaList),
4189+ ctypes.c_void_p, MediaDiscoverer)
4190+ return f(p_mdis)
4191+
4192+def libvlc_media_discoverer_is_running(p_mdis):
4193+ '''Query if media service discover object is running.
4194+ @param p_mdis: media service discover object.
4195+ @return: true if running, false if not \libvlc_return_bool.
4196+ '''
4197+ f = _Cfunctions.get('libvlc_media_discoverer_is_running', None) or \
4198+ _Cfunction('libvlc_media_discoverer_is_running', ((1,),), None,
4199+ ctypes.c_int, MediaDiscoverer)
4200+ return f(p_mdis)
4201+
4202+def libvlc_media_discoverer_list_get(p_inst, i_cat, ppp_services):
4203+ '''Get media discoverer services by category.
4204+ @param p_inst: libvlc instance.
4205+ @param i_cat: category of services to fetch.
4206+ @param ppp_services: address to store an allocated array of media discoverer services (must be freed with L{libvlc_media_discoverer_list_release}() by the caller) [OUT].
4207+ @return: the number of media discoverer services (0 on error).
4208+ @version: LibVLC 3.0.0 and later.
4209+ '''
4210+ f = _Cfunctions.get('libvlc_media_discoverer_list_get', None) or \
4211+ _Cfunction('libvlc_media_discoverer_list_get', ((1,), (1,), (1,),), None,
4212+ ctypes.c_size_t, Instance, MediaDiscovererCategory, ctypes.POINTER(ctypes.POINTER(MediaDiscovererDescription)))
4213+ return f(p_inst, i_cat, ppp_services)
4214+
4215+def libvlc_media_discoverer_list_release(pp_services, i_count):
4216+ '''Release an array of media discoverer services.
4217+ @param pp_services: array to release.
4218+ @param i_count: number of elements in the array.
4219+ @version: LibVLC 3.0.0 and later. See L{libvlc_media_discoverer_list_get}().
4220+ '''
4221+ f = _Cfunctions.get('libvlc_media_discoverer_list_release', None) or \
4222+ _Cfunction('libvlc_media_discoverer_list_release', ((1,), (1,),), None,
4223+ None, ctypes.POINTER(MediaDiscovererDescription), ctypes.c_size_t)
4224+ return f(pp_services, i_count)
4225+
4226+def libvlc_dialog_set_context(p_id, p_context):
4227+ '''Associate an opaque pointer with the dialog id.
4228+ @version: LibVLC 3.0.0 and later.
4229+ '''
4230+ f = _Cfunctions.get('libvlc_dialog_set_context', None) or \
4231+ _Cfunction('libvlc_dialog_set_context', ((1,), (1,),), None,
4232+ None, ctypes.c_void_p, ctypes.c_void_p)
4233+ return f(p_id, p_context)
4234+
4235+def libvlc_dialog_get_context(p_id):
4236+ '''Return the opaque pointer associated with the dialog id.
4237+ @version: LibVLC 3.0.0 and later.
4238+ '''
4239+ f = _Cfunctions.get('libvlc_dialog_get_context', None) or \
4240+ _Cfunction('libvlc_dialog_get_context', ((1,),), None,
4241+ ctypes.c_void_p, ctypes.c_void_p)
4242+ return f(p_id)
4243+
4244+def libvlc_dialog_post_login(p_id, psz_username, psz_password, b_store):
4245+ '''Post a login answer
4246+ After this call, p_id won't be valid anymore
4247+ See libvlc_dialog_cbs.pf_display_login.
4248+ @param p_id: id of the dialog.
4249+ @param psz_username: valid and non empty string.
4250+ @param psz_password: valid string (can be empty).
4251+ @param b_store: if true, store the credentials.
4252+ @return: 0 on success, or -1 on error.
4253+ @version: LibVLC 3.0.0 and later.
4254+ '''
4255+ f = _Cfunctions.get('libvlc_dialog_post_login', None) or \
4256+ _Cfunction('libvlc_dialog_post_login', ((1,), (1,), (1,), (1,),), None,
4257+ ctypes.c_int, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_bool)
4258+ return f(p_id, psz_username, psz_password, b_store)
4259+
4260+def libvlc_dialog_post_action(p_id, i_action):
4261+ '''Post a question answer
4262+ After this call, p_id won't be valid anymore
4263+ See libvlc_dialog_cbs.pf_display_question.
4264+ @param p_id: id of the dialog.
4265+ @param i_action: 1 for action1, 2 for action2.
4266+ @return: 0 on success, or -1 on error.
4267+ @version: LibVLC 3.0.0 and later.
4268+ '''
4269+ f = _Cfunctions.get('libvlc_dialog_post_action', None) or \
4270+ _Cfunction('libvlc_dialog_post_action', ((1,), (1,),), None,
4271+ ctypes.c_int, ctypes.c_void_p, ctypes.c_int)
4272+ return f(p_id, i_action)
4273+
4274+def libvlc_dialog_dismiss(p_id):
4275+ '''Dismiss a dialog
4276+ After this call, p_id won't be valid anymore
4277+ See libvlc_dialog_cbs.pf_cancel.
4278+ @param p_id: id of the dialog.
4279+ @return: 0 on success, or -1 on error.
4280+ @version: LibVLC 3.0.0 and later.
4281+ '''
4282+ f = _Cfunctions.get('libvlc_dialog_dismiss', None) or \
4283+ _Cfunction('libvlc_dialog_dismiss', ((1,),), None,
4284+ ctypes.c_int, ctypes.c_void_p)
4285+ return f(p_id)
4286+
4287+def libvlc_media_library_new(p_instance):
4288+ '''Create an new Media Library object.
4289+ @param p_instance: the libvlc instance.
4290+ @return: a new object or None on error.
4291+ '''
4292+ f = _Cfunctions.get('libvlc_media_library_new', None) or \
4293+ _Cfunction('libvlc_media_library_new', ((1,),), class_result(MediaLibrary),
4294+ ctypes.c_void_p, Instance)
4295+ return f(p_instance)
4296+
4297+def libvlc_media_library_release(p_mlib):
4298+ '''Release media library object. This functions decrements the
4299+ reference count of the media library object. If it reaches 0,
4300+ then the object will be released.
4301+ @param p_mlib: media library object.
4302+ '''
4303+ f = _Cfunctions.get('libvlc_media_library_release', None) or \
4304+ _Cfunction('libvlc_media_library_release', ((1,),), None,
4305+ None, MediaLibrary)
4306+ return f(p_mlib)
4307+
4308+def libvlc_media_library_retain(p_mlib):
4309+ '''Retain a reference to a media library object. This function will
4310+ increment the reference counting for this object. Use
4311+ L{libvlc_media_library_release}() to decrement the reference count.
4312+ @param p_mlib: media library object.
4313+ '''
4314+ f = _Cfunctions.get('libvlc_media_library_retain', None) or \
4315+ _Cfunction('libvlc_media_library_retain', ((1,),), None,
4316+ None, MediaLibrary)
4317+ return f(p_mlib)
4318+
4319+def libvlc_media_library_load(p_mlib):
4320+ '''Load media library.
4321+ @param p_mlib: media library object.
4322+ @return: 0 on success, -1 on error.
4323+ '''
4324+ f = _Cfunctions.get('libvlc_media_library_load', None) or \
4325+ _Cfunction('libvlc_media_library_load', ((1,),), None,
4326+ ctypes.c_int, MediaLibrary)
4327+ return f(p_mlib)
4328+
4329+def libvlc_media_library_media_list(p_mlib):
4330+ '''Get media library subitems.
4331+ @param p_mlib: media library object.
4332+ @return: media list subitems.
4333+ '''
4334+ f = _Cfunctions.get('libvlc_media_library_media_list', None) or \
4335+ _Cfunction('libvlc_media_library_media_list', ((1,),), class_result(MediaList),
4336+ ctypes.c_void_p, MediaLibrary)
4337+ return f(p_mlib)
4338+
4339+def libvlc_vlm_release(p_instance):
4340+ '''Release the vlm instance related to the given L{Instance}.
4341+ @param p_instance: the instance.
4342+ '''
4343+ f = _Cfunctions.get('libvlc_vlm_release', None) or \
4344+ _Cfunction('libvlc_vlm_release', ((1,),), None,
4345+ None, Instance)
4346+ return f(p_instance)
4347+
4348+def libvlc_vlm_add_broadcast(p_instance, psz_name, psz_input, psz_output, i_options, ppsz_options, b_enabled, b_loop):
4349+ '''Add a broadcast, with one input.
4350+ @param p_instance: the instance.
4351+ @param psz_name: the name of the new broadcast.
4352+ @param psz_input: the input MRL.
4353+ @param psz_output: the output MRL (the parameter to the "sout" variable).
4354+ @param i_options: number of additional options.
4355+ @param ppsz_options: additional options.
4356+ @param b_enabled: boolean for enabling the new broadcast.
4357+ @param b_loop: Should this broadcast be played in loop ?
4358+ @return: 0 on success, -1 on error.
4359+ '''
4360+ f = _Cfunctions.get('libvlc_vlm_add_broadcast', None) or \
4361+ _Cfunction('libvlc_vlm_add_broadcast', ((1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,),), None,
4362+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int, ListPOINTER(ctypes.c_char_p), ctypes.c_int, ctypes.c_int)
4363+ return f(p_instance, psz_name, psz_input, psz_output, i_options, ppsz_options, b_enabled, b_loop)
4364+
4365+def libvlc_vlm_add_vod(p_instance, psz_name, psz_input, i_options, ppsz_options, b_enabled, psz_mux):
4366+ '''Add a vod, with one input.
4367+ @param p_instance: the instance.
4368+ @param psz_name: the name of the new vod media.
4369+ @param psz_input: the input MRL.
4370+ @param i_options: number of additional options.
4371+ @param ppsz_options: additional options.
4372+ @param b_enabled: boolean for enabling the new vod.
4373+ @param psz_mux: the muxer of the vod media.
4374+ @return: 0 on success, -1 on error.
4375+ '''
4376+ f = _Cfunctions.get('libvlc_vlm_add_vod', None) or \
4377+ _Cfunction('libvlc_vlm_add_vod', ((1,), (1,), (1,), (1,), (1,), (1,), (1,),), None,
4378+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int, ListPOINTER(ctypes.c_char_p), ctypes.c_int, ctypes.c_char_p)
4379+ return f(p_instance, psz_name, psz_input, i_options, ppsz_options, b_enabled, psz_mux)
4380+
4381+def libvlc_vlm_del_media(p_instance, psz_name):
4382+ '''Delete a media (VOD or broadcast).
4383+ @param p_instance: the instance.
4384+ @param psz_name: the media to delete.
4385+ @return: 0 on success, -1 on error.
4386+ '''
4387+ f = _Cfunctions.get('libvlc_vlm_del_media', None) or \
4388+ _Cfunction('libvlc_vlm_del_media', ((1,), (1,),), None,
4389+ ctypes.c_int, Instance, ctypes.c_char_p)
4390+ return f(p_instance, psz_name)
4391+
4392+def libvlc_vlm_set_enabled(p_instance, psz_name, b_enabled):
4393+ '''Enable or disable a media (VOD or broadcast).
4394+ @param p_instance: the instance.
4395+ @param psz_name: the media to work on.
4396+ @param b_enabled: the new status.
4397+ @return: 0 on success, -1 on error.
4398+ '''
4399+ f = _Cfunctions.get('libvlc_vlm_set_enabled', None) or \
4400+ _Cfunction('libvlc_vlm_set_enabled', ((1,), (1,), (1,),), None,
4401+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_int)
4402+ return f(p_instance, psz_name, b_enabled)
4403+
4404+def libvlc_vlm_set_output(p_instance, psz_name, psz_output):
4405+ '''Set the output for a media.
4406+ @param p_instance: the instance.
4407+ @param psz_name: the media to work on.
4408+ @param psz_output: the output MRL (the parameter to the "sout" variable).
4409+ @return: 0 on success, -1 on error.
4410+ '''
4411+ f = _Cfunctions.get('libvlc_vlm_set_output', None) or \
4412+ _Cfunction('libvlc_vlm_set_output', ((1,), (1,), (1,),), None,
4413+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_char_p)
4414+ return f(p_instance, psz_name, psz_output)
4415+
4416+def libvlc_vlm_set_input(p_instance, psz_name, psz_input):
4417+ '''Set a media's input MRL. This will delete all existing inputs and
4418+ add the specified one.
4419+ @param p_instance: the instance.
4420+ @param psz_name: the media to work on.
4421+ @param psz_input: the input MRL.
4422+ @return: 0 on success, -1 on error.
4423+ '''
4424+ f = _Cfunctions.get('libvlc_vlm_set_input', None) or \
4425+ _Cfunction('libvlc_vlm_set_input', ((1,), (1,), (1,),), None,
4426+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_char_p)
4427+ return f(p_instance, psz_name, psz_input)
4428+
4429+def libvlc_vlm_add_input(p_instance, psz_name, psz_input):
4430+ '''Add a media's input MRL. This will add the specified one.
4431+ @param p_instance: the instance.
4432+ @param psz_name: the media to work on.
4433+ @param psz_input: the input MRL.
4434+ @return: 0 on success, -1 on error.
4435+ '''
4436+ f = _Cfunctions.get('libvlc_vlm_add_input', None) or \
4437+ _Cfunction('libvlc_vlm_add_input', ((1,), (1,), (1,),), None,
4438+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_char_p)
4439+ return f(p_instance, psz_name, psz_input)
4440+
4441+def libvlc_vlm_set_loop(p_instance, psz_name, b_loop):
4442+ '''Set a media's loop status.
4443+ @param p_instance: the instance.
4444+ @param psz_name: the media to work on.
4445+ @param b_loop: the new status.
4446+ @return: 0 on success, -1 on error.
4447+ '''
4448+ f = _Cfunctions.get('libvlc_vlm_set_loop', None) or \
4449+ _Cfunction('libvlc_vlm_set_loop', ((1,), (1,), (1,),), None,
4450+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_int)
4451+ return f(p_instance, psz_name, b_loop)
4452+
4453+def libvlc_vlm_set_mux(p_instance, psz_name, psz_mux):
4454+ '''Set a media's vod muxer.
4455+ @param p_instance: the instance.
4456+ @param psz_name: the media to work on.
4457+ @param psz_mux: the new muxer.
4458+ @return: 0 on success, -1 on error.
4459+ '''
4460+ f = _Cfunctions.get('libvlc_vlm_set_mux', None) or \
4461+ _Cfunction('libvlc_vlm_set_mux', ((1,), (1,), (1,),), None,
4462+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_char_p)
4463+ return f(p_instance, psz_name, psz_mux)
4464+
4465+def libvlc_vlm_change_media(p_instance, psz_name, psz_input, psz_output, i_options, ppsz_options, b_enabled, b_loop):
4466+ '''Edit the parameters of a media. This will delete all existing inputs and
4467+ add the specified one.
4468+ @param p_instance: the instance.
4469+ @param psz_name: the name of the new broadcast.
4470+ @param psz_input: the input MRL.
4471+ @param psz_output: the output MRL (the parameter to the "sout" variable).
4472+ @param i_options: number of additional options.
4473+ @param ppsz_options: additional options.
4474+ @param b_enabled: boolean for enabling the new broadcast.
4475+ @param b_loop: Should this broadcast be played in loop ?
4476+ @return: 0 on success, -1 on error.
4477+ '''
4478+ f = _Cfunctions.get('libvlc_vlm_change_media', None) or \
4479+ _Cfunction('libvlc_vlm_change_media', ((1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,),), None,
4480+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int, ListPOINTER(ctypes.c_char_p), ctypes.c_int, ctypes.c_int)
4481+ return f(p_instance, psz_name, psz_input, psz_output, i_options, ppsz_options, b_enabled, b_loop)
4482+
4483+def libvlc_vlm_play_media(p_instance, psz_name):
4484+ '''Play the named broadcast.
4485+ @param p_instance: the instance.
4486+ @param psz_name: the name of the broadcast.
4487+ @return: 0 on success, -1 on error.
4488+ '''
4489+ f = _Cfunctions.get('libvlc_vlm_play_media', None) or \
4490+ _Cfunction('libvlc_vlm_play_media', ((1,), (1,),), None,
4491+ ctypes.c_int, Instance, ctypes.c_char_p)
4492+ return f(p_instance, psz_name)
4493+
4494+def libvlc_vlm_stop_media(p_instance, psz_name):
4495+ '''Stop the named broadcast.
4496+ @param p_instance: the instance.
4497+ @param psz_name: the name of the broadcast.
4498+ @return: 0 on success, -1 on error.
4499+ '''
4500+ f = _Cfunctions.get('libvlc_vlm_stop_media', None) or \
4501+ _Cfunction('libvlc_vlm_stop_media', ((1,), (1,),), None,
4502+ ctypes.c_int, Instance, ctypes.c_char_p)
4503+ return f(p_instance, psz_name)
4504+
4505+def libvlc_vlm_pause_media(p_instance, psz_name):
4506+ '''Pause the named broadcast.
4507+ @param p_instance: the instance.
4508+ @param psz_name: the name of the broadcast.
4509+ @return: 0 on success, -1 on error.
4510+ '''
4511+ f = _Cfunctions.get('libvlc_vlm_pause_media', None) or \
4512+ _Cfunction('libvlc_vlm_pause_media', ((1,), (1,),), None,
4513+ ctypes.c_int, Instance, ctypes.c_char_p)
4514+ return f(p_instance, psz_name)
4515+
4516+def libvlc_vlm_seek_media(p_instance, psz_name, f_percentage):
4517+ '''Seek in the named broadcast.
4518+ @param p_instance: the instance.
4519+ @param psz_name: the name of the broadcast.
4520+ @param f_percentage: the percentage to seek to.
4521+ @return: 0 on success, -1 on error.
4522+ '''
4523+ f = _Cfunctions.get('libvlc_vlm_seek_media', None) or \
4524+ _Cfunction('libvlc_vlm_seek_media', ((1,), (1,), (1,),), None,
4525+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_float)
4526+ return f(p_instance, psz_name, f_percentage)
4527+
4528+def libvlc_vlm_show_media(p_instance, psz_name):
4529+ '''Return information about the named media as a JSON
4530+ string representation.
4531+ This function is mainly intended for debugging use,
4532+ if you want programmatic access to the state of
4533+ a vlm_media_instance_t, please use the corresponding
4534+ libvlc_vlm_get_media_instance_xxx -functions.
4535+ Currently there are no such functions available for
4536+ vlm_media_t though.
4537+ @param p_instance: the instance.
4538+ @param psz_name: the name of the media, if the name is an empty string, all media is described.
4539+ @return: string with information about named media, or None on error.
4540+ '''
4541+ f = _Cfunctions.get('libvlc_vlm_show_media', None) or \
4542+ _Cfunction('libvlc_vlm_show_media', ((1,), (1,),), string_result,
4543+ ctypes.c_void_p, Instance, ctypes.c_char_p)
4544+ return f(p_instance, psz_name)
4545+
4546+def libvlc_vlm_get_media_instance_position(p_instance, psz_name, i_instance):
4547+ '''Get vlm_media instance position by name or instance id.
4548+ @param p_instance: a libvlc instance.
4549+ @param psz_name: name of vlm media instance.
4550+ @param i_instance: instance id.
4551+ @return: position as float or -1. on error.
4552+ '''
4553+ f = _Cfunctions.get('libvlc_vlm_get_media_instance_position', None) or \
4554+ _Cfunction('libvlc_vlm_get_media_instance_position', ((1,), (1,), (1,),), None,
4555+ ctypes.c_float, Instance, ctypes.c_char_p, ctypes.c_int)
4556+ return f(p_instance, psz_name, i_instance)
4557+
4558+def libvlc_vlm_get_media_instance_time(p_instance, psz_name, i_instance):
4559+ '''Get vlm_media instance time by name or instance id.
4560+ @param p_instance: a libvlc instance.
4561+ @param psz_name: name of vlm media instance.
4562+ @param i_instance: instance id.
4563+ @return: time as integer or -1 on error.
4564+ '''
4565+ f = _Cfunctions.get('libvlc_vlm_get_media_instance_time', None) or \
4566+ _Cfunction('libvlc_vlm_get_media_instance_time', ((1,), (1,), (1,),), None,
4567+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_int)
4568+ return f(p_instance, psz_name, i_instance)
4569+
4570+def libvlc_vlm_get_media_instance_length(p_instance, psz_name, i_instance):
4571+ '''Get vlm_media instance length by name or instance id.
4572+ @param p_instance: a libvlc instance.
4573+ @param psz_name: name of vlm media instance.
4574+ @param i_instance: instance id.
4575+ @return: length of media item or -1 on error.
4576+ '''
4577+ f = _Cfunctions.get('libvlc_vlm_get_media_instance_length', None) or \
4578+ _Cfunction('libvlc_vlm_get_media_instance_length', ((1,), (1,), (1,),), None,
4579+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_int)
4580+ return f(p_instance, psz_name, i_instance)
4581+
4582+def libvlc_vlm_get_media_instance_rate(p_instance, psz_name, i_instance):
4583+ '''Get vlm_media instance playback rate by name or instance id.
4584+ @param p_instance: a libvlc instance.
4585+ @param psz_name: name of vlm media instance.
4586+ @param i_instance: instance id.
4587+ @return: playback rate or -1 on error.
4588+ '''
4589+ f = _Cfunctions.get('libvlc_vlm_get_media_instance_rate', None) or \
4590+ _Cfunction('libvlc_vlm_get_media_instance_rate', ((1,), (1,), (1,),), None,
4591+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_int)
4592+ return f(p_instance, psz_name, i_instance)
4593+
4594+def libvlc_vlm_get_media_instance_title(p_instance, psz_name, i_instance):
4595+ '''Get vlm_media instance title number by name or instance id.
4596+ @param p_instance: a libvlc instance.
4597+ @param psz_name: name of vlm media instance.
4598+ @param i_instance: instance id.
4599+ @return: title as number or -1 on error.
4600+ @bug: will always return 0.
4601+ '''
4602+ f = _Cfunctions.get('libvlc_vlm_get_media_instance_title', None) or \
4603+ _Cfunction('libvlc_vlm_get_media_instance_title', ((1,), (1,), (1,),), None,
4604+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_int)
4605+ return f(p_instance, psz_name, i_instance)
4606+
4607+def libvlc_vlm_get_media_instance_chapter(p_instance, psz_name, i_instance):
4608+ '''Get vlm_media instance chapter number by name or instance id.
4609+ @param p_instance: a libvlc instance.
4610+ @param psz_name: name of vlm media instance.
4611+ @param i_instance: instance id.
4612+ @return: chapter as number or -1 on error.
4613+ @bug: will always return 0.
4614+ '''
4615+ f = _Cfunctions.get('libvlc_vlm_get_media_instance_chapter', None) or \
4616+ _Cfunction('libvlc_vlm_get_media_instance_chapter', ((1,), (1,), (1,),), None,
4617+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_int)
4618+ return f(p_instance, psz_name, i_instance)
4619+
4620+def libvlc_vlm_get_media_instance_seekable(p_instance, psz_name, i_instance):
4621+ '''Is libvlc instance seekable ?
4622+ @param p_instance: a libvlc instance.
4623+ @param psz_name: name of vlm media instance.
4624+ @param i_instance: instance id.
4625+ @return: 1 if seekable, 0 if not, -1 if media does not exist.
4626+ @bug: will always return 0.
4627+ '''
4628+ f = _Cfunctions.get('libvlc_vlm_get_media_instance_seekable', None) or \
4629+ _Cfunction('libvlc_vlm_get_media_instance_seekable', ((1,), (1,), (1,),), None,
4630+ ctypes.c_int, Instance, ctypes.c_char_p, ctypes.c_int)
4631+ return f(p_instance, psz_name, i_instance)
4632+
4633+def libvlc_vlm_get_event_manager(p_instance):
4634+ '''Get libvlc_event_manager from a vlm media.
4635+ The p_event_manager is immutable, so you don't have to hold the lock.
4636+ @param p_instance: a libvlc instance.
4637+ @return: libvlc_event_manager.
4638+ '''
4639+ f = _Cfunctions.get('libvlc_vlm_get_event_manager', None) or \
4640+ _Cfunction('libvlc_vlm_get_event_manager', ((1,),), class_result(EventManager),
4641+ ctypes.c_void_p, Instance)
4642+ return f(p_instance)
4643+
4644 def libvlc_media_new_location(p_instance, psz_mrl):
4645 '''Create a media with a certain given media resource location,
4646 for instance a valid URL.
4647@@ -3928,6 +5250,22 @@
4648 ctypes.c_void_p, Instance, ctypes.c_int)
4649 return f(p_instance, fd)
4650
4651+def libvlc_media_new_callbacks(instance, open_cb, read_cb, seek_cb, close_cb, opaque):
4652+ '''Create a media with custom callbacks to read the data from.
4653+ @param instance: LibVLC instance.
4654+ @param open_cb: callback to open the custom bitstream input media.
4655+ @param read_cb: callback to read data (must not be None).
4656+ @param seek_cb: callback to seek, or None if seeking is not supported.
4657+ @param close_cb: callback to close the media, or None if unnecessary.
4658+ @param opaque: data pointer for the open callback.
4659+ @return: the newly created media or None on error @note If open_cb is None, the opaque pointer will be passed to read_cb, seek_cb and close_cb, and the stream size will be treated as unknown. @note The callbacks may be called asynchronously (from another thread). A single stream instance need not be reentrant. However the open_cb needs to be reentrant if the media is used by multiple player instances. @warning The callbacks may be used until all or any player instances that were supplied the media item are stopped. See L{libvlc_media_release}.
4660+ @version: LibVLC 3.0.0 and later.
4661+ '''
4662+ f = _Cfunctions.get('libvlc_media_new_callbacks', None) or \
4663+ _Cfunction('libvlc_media_new_callbacks', ((1,), (1,), (1,), (1,), (1,), (1,),), class_result(Media),
4664+ ctypes.c_void_p, Instance, MediaOpenCb, MediaReadCb, MediaSeekCb, MediaCloseCb, ctypes.c_void_p)
4665+ return f(instance, open_cb, read_cb, seek_cb, close_cb, opaque)
4666+
4667 def libvlc_media_new_as_node(p_instance, psz_name):
4668 '''Create a media as an empty node with a given name.
4669 See L{libvlc_media_release}.
4670@@ -3980,7 +5318,7 @@
4671 return f(p_md, psz_options, i_flags)
4672
4673 def libvlc_media_retain(p_md):
4674- '''Retain a reference to a media descriptor object (libvlc_media_t). Use
4675+ '''Retain a reference to a media descriptor object (L{Media}). Use
4676 L{libvlc_media_release}() to decrement the reference count of a
4677 media descriptor object.
4678 @param p_md: the media descriptor.
4679@@ -4025,11 +5363,8 @@
4680 def libvlc_media_get_meta(p_md, e_meta):
4681 '''Read the meta of the media.
4682 If the media has not yet been parsed this will return None.
4683- This methods automatically calls L{libvlc_media_parse_async}(), so after calling
4684- it you may receive a libvlc_MediaMetaChanged event. If you prefer a synchronous
4685- version ensure that you call L{libvlc_media_parse}() before get_meta().
4686 See L{libvlc_media_parse}
4687- See L{libvlc_media_parse_async}
4688+ See L{libvlc_media_parse_with_options}
4689 See libvlc_MediaMetaChanged.
4690 @param p_md: the media descriptor.
4691 @param e_meta: the meta to read.
4692@@ -4063,12 +5398,10 @@
4693 return f(p_md)
4694
4695 def libvlc_media_get_state(p_md):
4696- '''Get current state of media descriptor object. Possible media states
4697- are defined in libvlc_structures.c ( libvlc_NothingSpecial=0,
4698- libvlc_Opening, libvlc_Buffering, libvlc_Playing, libvlc_Paused,
4699- libvlc_Stopped, libvlc_Ended,
4700- libvlc_Error).
4701- See libvlc_state_t.
4702+ '''Get current state of media descriptor object. Possible media states are
4703+ libvlc_NothingSpecial=0, libvlc_Opening, libvlc_Playing, libvlc_Paused,
4704+ libvlc_Stopped, libvlc_Ended, libvlc_Error.
4705+ See L{State}.
4706 @param p_md: a media descriptor object.
4707 @return: state of media descriptor object.
4708 '''
4709@@ -4121,47 +5454,57 @@
4710 ctypes.c_longlong, Media)
4711 return f(p_md)
4712
4713-def libvlc_media_parse(p_md):
4714- '''Parse a media.
4715- This fetches (local) meta data and tracks information.
4716- The method is synchronous.
4717- See L{libvlc_media_parse_async}
4718- See L{libvlc_media_get_meta}
4719- See libvlc_media_get_tracks_info.
4720- @param p_md: media descriptor object.
4721- '''
4722- f = _Cfunctions.get('libvlc_media_parse', None) or \
4723- _Cfunction('libvlc_media_parse', ((1,),), None,
4724- None, Media)
4725- return f(p_md)
4726-
4727-def libvlc_media_parse_async(p_md):
4728- '''Parse a media.
4729- This fetches (local) meta data and tracks information.
4730- The method is the asynchronous of L{libvlc_media_parse}().
4731+def libvlc_media_parse_with_options(p_md, parse_flag, timeout):
4732+ '''Parse the media asynchronously with options.
4733+ This fetches (local or network) art, meta data and/or tracks information.
4734+ This method is the extended version of L{libvlc_media_parse_with_options}().
4735 To track when this is over you can listen to libvlc_MediaParsedChanged
4736- event. However if the media was already parsed you will not receive this
4737- event.
4738- See L{libvlc_media_parse}
4739+ event. However if this functions returns an error, you will not receive any
4740+ events.
4741+ It uses a flag to specify parse options (see L{MediaParseFlag}). All
4742+ these flags can be combined. By default, media is parsed if it's a local
4743+ file.
4744+ @note: Parsing can be aborted with L{libvlc_media_parse_stop}().
4745 See libvlc_MediaParsedChanged
4746 See L{libvlc_media_get_meta}
4747- See libvlc_media_get_tracks_info.
4748- @param p_md: media descriptor object.
4749- '''
4750- f = _Cfunctions.get('libvlc_media_parse_async', None) or \
4751- _Cfunction('libvlc_media_parse_async', ((1,),), None,
4752+ See L{libvlc_media_tracks_get}
4753+ See L{libvlc_media_get_parsed_status}
4754+ See L{MediaParseFlag}.
4755+ @param p_md: media descriptor object.
4756+ @param parse_flag: parse options:
4757+ @param timeout: maximum time allowed to preparse the media. If -1, the default "preparse-timeout" option will be used as a timeout. If 0, it will wait indefinitely. If > 0, the timeout will be used (in milliseconds).
4758+ @return: -1 in case of error, 0 otherwise.
4759+ @version: LibVLC 3.0.0 or later.
4760+ '''
4761+ f = _Cfunctions.get('libvlc_media_parse_with_options', None) or \
4762+ _Cfunction('libvlc_media_parse_with_options', ((1,), (1,), (1,),), None,
4763+ ctypes.c_int, Media, MediaParseFlag, ctypes.c_int)
4764+ return f(p_md, parse_flag, timeout)
4765+
4766+def libvlc_media_parse_stop(p_md):
4767+ '''Stop the parsing of the media
4768+ When the media parsing is stopped, the libvlc_MediaParsedChanged event will
4769+ be sent with the libvlc_media_parsed_status_timeout status.
4770+ See L{libvlc_media_parse_with_options}.
4771+ @param p_md: media descriptor object.
4772+ @version: LibVLC 3.0.0 or later.
4773+ '''
4774+ f = _Cfunctions.get('libvlc_media_parse_stop', None) or \
4775+ _Cfunction('libvlc_media_parse_stop', ((1,),), None,
4776 None, Media)
4777 return f(p_md)
4778
4779-def libvlc_media_is_parsed(p_md):
4780+def libvlc_media_get_parsed_status(p_md):
4781 '''Get Parsed status for media descriptor object.
4782- See libvlc_MediaParsedChanged.
4783+ See libvlc_MediaParsedChanged
4784+ See L{MediaParsedStatus}.
4785 @param p_md: media descriptor object.
4786- @return: true if media object has been parsed otherwise it returns false \libvlc_return_bool.
4787+ @return: a value of the L{MediaParsedStatus} enum.
4788+ @version: LibVLC 3.0.0 or later.
4789 '''
4790- f = _Cfunctions.get('libvlc_media_is_parsed', None) or \
4791- _Cfunction('libvlc_media_is_parsed', ((1,),), None,
4792- ctypes.c_int, Media)
4793+ f = _Cfunctions.get('libvlc_media_get_parsed_status', None) or \
4794+ _Cfunction('libvlc_media_get_parsed_status', ((1,),), None,
4795+ MediaParsedStatus, Media)
4796 return f(p_md)
4797
4798 def libvlc_media_set_user_data(p_md, p_new_user_data):
4799@@ -4202,6 +5545,18 @@
4800 ctypes.c_uint, Media, ctypes.POINTER(ctypes.POINTER(MediaTrack)))
4801 return f(p_md, tracks)
4802
4803+def libvlc_media_get_codec_description(i_type, i_codec):
4804+ '''Get codec description from media elementary stream.
4805+ @param i_type: i_type from L{MediaTrack}.
4806+ @param i_codec: i_codec or i_original_fourcc from L{MediaTrack}.
4807+ @return: codec description.
4808+ @version: LibVLC 3.0.0 and later. See L{MediaTrack}.
4809+ '''
4810+ f = _Cfunctions.get('libvlc_media_get_codec_description', None) or \
4811+ _Cfunction('libvlc_media_get_codec_description', ((1,), (1,),), None,
4812+ ctypes.c_char_p, TrackType, ctypes.c_uint32)
4813+ return f(i_type, i_codec)
4814+
4815 def libvlc_media_tracks_release(p_tracks, i_count):
4816 '''Release media descriptor's elementary streams description array.
4817 @param p_tracks: tracks info array to release.
4818@@ -4213,118 +5568,232 @@
4819 None, ctypes.POINTER(MediaTrack), ctypes.c_uint)
4820 return f(p_tracks, i_count)
4821
4822-def libvlc_media_discoverer_new_from_name(p_inst, psz_name):
4823- '''Discover media service by name.
4824+def libvlc_media_get_type(p_md):
4825+ '''Get the media type of the media descriptor object.
4826+ @param p_md: media descriptor object.
4827+ @return: media type.
4828+ @version: LibVLC 3.0.0 and later. See L{MediaType}.
4829+ '''
4830+ f = _Cfunctions.get('libvlc_media_get_type', None) or \
4831+ _Cfunction('libvlc_media_get_type', ((1,),), None,
4832+ MediaType, Media)
4833+ return f(p_md)
4834+
4835+def libvlc_media_slaves_add(p_md, i_type, i_priority, psz_uri):
4836+ '''Add a slave to the current media.
4837+ A slave is an external input source that may contains an additional subtitle
4838+ track (like a .srt) or an additional audio track (like a .ac3).
4839+ @note: This function must be called before the media is parsed (via
4840+ L{libvlc_media_parse_with_options}()) or before the media is played (via
4841+ L{libvlc_media_player_play}()).
4842+ @param p_md: media descriptor object.
4843+ @param i_type: subtitle or audio.
4844+ @param i_priority: from 0 (low priority) to 4 (high priority).
4845+ @param psz_uri: Uri of the slave (should contain a valid scheme).
4846+ @return: 0 on success, -1 on error.
4847+ @version: LibVLC 3.0.0 and later.
4848+ '''
4849+ f = _Cfunctions.get('libvlc_media_slaves_add', None) or \
4850+ _Cfunction('libvlc_media_slaves_add', ((1,), (1,), (1,), (1,),), None,
4851+ ctypes.c_int, Media, MediaSlaveType, ctypes.c_int, ctypes.c_char_p)
4852+ return f(p_md, i_type, i_priority, psz_uri)
4853+
4854+def libvlc_media_slaves_clear(p_md):
4855+ '''Clear all slaves previously added by L{libvlc_media_slaves_add}() or
4856+ internally.
4857+ @param p_md: media descriptor object.
4858+ @version: LibVLC 3.0.0 and later.
4859+ '''
4860+ f = _Cfunctions.get('libvlc_media_slaves_clear', None) or \
4861+ _Cfunction('libvlc_media_slaves_clear', ((1,),), None,
4862+ None, Media)
4863+ return f(p_md)
4864+
4865+def libvlc_media_slaves_get(p_md, ppp_slaves):
4866+ '''Get a media descriptor's slave list
4867+ The list will contain slaves parsed by VLC or previously added by
4868+ L{libvlc_media_slaves_add}(). The typical use case of this function is to save
4869+ a list of slave in a database for a later use.
4870+ @param p_md: media descriptor object.
4871+ @param ppp_slaves: address to store an allocated array of slaves (must be freed with L{libvlc_media_slaves_release}()) [OUT].
4872+ @return: the number of slaves (zero on error).
4873+ @version: LibVLC 3.0.0 and later. See L{libvlc_media_slaves_add}.
4874+ '''
4875+ f = _Cfunctions.get('libvlc_media_slaves_get', None) or \
4876+ _Cfunction('libvlc_media_slaves_get', ((1,), (1,),), None,
4877+ ctypes.c_int, Media, ctypes.POINTER(ctypes.POINTER(MediaSlave)))
4878+ return f(p_md, ppp_slaves)
4879+
4880+def libvlc_media_slaves_release(pp_slaves, i_count):
4881+ '''Release a media descriptor's slave list.
4882+ @param pp_slaves: slave array to release.
4883+ @param i_count: number of elements in the array.
4884+ @version: LibVLC 3.0.0 and later.
4885+ '''
4886+ f = _Cfunctions.get('libvlc_media_slaves_release', None) or \
4887+ _Cfunction('libvlc_media_slaves_release', ((1,), (1,),), None,
4888+ None, ctypes.POINTER(MediaSlave), ctypes.c_int)
4889+ return f(pp_slaves, i_count)
4890+
4891+def libvlc_renderer_item_hold(p_item):
4892+ '''Hold a renderer item, i.e. creates a new reference
4893+ This functions need to called from the libvlc_RendererDiscovererItemAdded
4894+ callback if the libvlc user wants to use this item after. (for display or
4895+ for passing it to the mediaplayer for example).
4896+ @return: the current item.
4897+ @version: LibVLC 3.0.0 or later.
4898+ '''
4899+ f = _Cfunctions.get('libvlc_renderer_item_hold', None) or \
4900+ _Cfunction('libvlc_renderer_item_hold', ((1,),), None,
4901+ ctypes.c_void_p, ctypes.c_void_p)
4902+ return f(p_item)
4903+
4904+def libvlc_renderer_item_release(p_item):
4905+ '''Releases a renderer item, i.e. decrements its reference counter.
4906+ @version: LibVLC 3.0.0 or later.
4907+ '''
4908+ f = _Cfunctions.get('libvlc_renderer_item_release', None) or \
4909+ _Cfunction('libvlc_renderer_item_release', ((1,),), None,
4910+ None, ctypes.c_void_p)
4911+ return f(p_item)
4912+
4913+def libvlc_renderer_item_name(p_item):
4914+ '''Get the human readable name of a renderer item.
4915+ @return: the name of the item (can't be None, must *not* be freed).
4916+ @version: LibVLC 3.0.0 or later.
4917+ '''
4918+ f = _Cfunctions.get('libvlc_renderer_item_name', None) or \
4919+ _Cfunction('libvlc_renderer_item_name', ((1,),), None,
4920+ ctypes.c_char_p, ctypes.c_void_p)
4921+ return f(p_item)
4922+
4923+def libvlc_renderer_item_type(p_item):
4924+ '''Get the type (not translated) of a renderer item. For now, the type can only
4925+ be "chromecast" ("upnp", "airplay" may come later).
4926+ @return: the type of the item (can't be None, must *not* be freed).
4927+ @version: LibVLC 3.0.0 or later.
4928+ '''
4929+ f = _Cfunctions.get('libvlc_renderer_item_type', None) or \
4930+ _Cfunction('libvlc_renderer_item_type', ((1,),), None,
4931+ ctypes.c_char_p, ctypes.c_void_p)
4932+ return f(p_item)
4933+
4934+def libvlc_renderer_item_icon_uri(p_item):
4935+ '''Get the icon uri of a renderer item.
4936+ @return: the uri of the item's icon (can be None, must *not* be freed).
4937+ @version: LibVLC 3.0.0 or later.
4938+ '''
4939+ f = _Cfunctions.get('libvlc_renderer_item_icon_uri', None) or \
4940+ _Cfunction('libvlc_renderer_item_icon_uri', ((1,),), None,
4941+ ctypes.c_char_p, ctypes.c_void_p)
4942+ return f(p_item)
4943+
4944+def libvlc_renderer_item_flags(p_item):
4945+ '''Get the flags of a renderer item
4946+ See LIBVLC_RENDERER_CAN_AUDIO
4947+ See LIBVLC_RENDERER_CAN_VIDEO.
4948+ @return: bitwise flag: capabilities of the renderer, see.
4949+ @version: LibVLC 3.0.0 or later.
4950+ '''
4951+ f = _Cfunctions.get('libvlc_renderer_item_flags', None) or \
4952+ _Cfunction('libvlc_renderer_item_flags', ((1,),), None,
4953+ ctypes.c_int, ctypes.c_void_p)
4954+ return f(p_item)
4955+
4956+def libvlc_renderer_discoverer_new(p_inst, psz_name):
4957+ '''Create a renderer discoverer object by name
4958+ After this object is created, you should attach to events in order to be
4959+ notified of the discoverer events.
4960+ You need to call L{libvlc_renderer_discoverer_start}() in order to start the
4961+ discovery.
4962+ See L{libvlc_renderer_discoverer_event_manager}()
4963+ See L{libvlc_renderer_discoverer_start}().
4964 @param p_inst: libvlc instance.
4965- @param psz_name: service name.
4966+ @param psz_name: service name; use L{libvlc_renderer_discoverer_list_get}() to get a list of the discoverer names available in this libVLC instance.
4967 @return: media discover object or None in case of error.
4968+ @version: LibVLC 3.0.0 or later.
4969 '''
4970- f = _Cfunctions.get('libvlc_media_discoverer_new_from_name', None) or \
4971- _Cfunction('libvlc_media_discoverer_new_from_name', ((1,), (1,),), class_result(MediaDiscoverer),
4972+ f = _Cfunctions.get('libvlc_renderer_discoverer_new', None) or \
4973+ _Cfunction('libvlc_renderer_discoverer_new', ((1,), (1,),), None,
4974 ctypes.c_void_p, Instance, ctypes.c_char_p)
4975 return f(p_inst, psz_name)
4976
4977-def libvlc_media_discoverer_release(p_mdis):
4978- '''Release media discover object. If the reference count reaches 0, then
4979- the object will be released.
4980- @param p_mdis: media service discover object.
4981- '''
4982- f = _Cfunctions.get('libvlc_media_discoverer_release', None) or \
4983- _Cfunction('libvlc_media_discoverer_release', ((1,),), None,
4984- None, MediaDiscoverer)
4985- return f(p_mdis)
4986-
4987-def libvlc_media_discoverer_localized_name(p_mdis):
4988- '''Get media service discover object its localized name.
4989- @param p_mdis: media discover object.
4990- @return: localized name.
4991- '''
4992- f = _Cfunctions.get('libvlc_media_discoverer_localized_name', None) or \
4993- _Cfunction('libvlc_media_discoverer_localized_name', ((1,),), string_result,
4994- ctypes.c_void_p, MediaDiscoverer)
4995- return f(p_mdis)
4996-
4997-def libvlc_media_discoverer_media_list(p_mdis):
4998- '''Get media service discover media list.
4999- @param p_mdis: media service discover object.
5000- @return: list of media items.
The diff has been truncated for viewing.