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: 9468 lines (+3897/-2446)
60 files modified
openlp/.version (+1/-1)
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 (+11/-5)
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 Pending
Review via email: mp+361641@code.launchpad.net

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

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

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 : Posted in a previous version of this proposal

Linux tests passed!

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

Linting passed!

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

macOS tests passed!

Revision history for this message
Phill (phill-ridout) wrote : Posted in a previous version of this proposal

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

Revision history for this message
Phill (phill-ridout) wrote : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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!

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

Linux tests passed!

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

Linting failed, please see https://ci.openlp.io/job/MP-03-Linting/26/ 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!

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