Merge lp:~trb143/openlp/more_media into lp:openlp
- more_media
- Merge into trunk
Proposed by
Tim Bentley
Status: | Superseded |
---|---|
Proposed branch: | lp:~trb143/openlp/more_media |
Merge into: | lp:openlp |
Diff against target: |
455 lines (+138/-54) 11 files modified
openlp/core/common/settings.py (+2/-0) openlp/core/lib/__init__.py (+1/-0) openlp/core/ui/media/__init__.py (+13/-0) openlp/core/ui/media/mediacontroller.py (+23/-6) openlp/core/ui/media/mediatab.py (+29/-16) openlp/core/ui/media/vlcplayer.py (+7/-20) openlp/core/ui/servicemanager.py (+1/-1) openlp/core/ui/themeform.py (+1/-1) openlp/core/widgets/widgets.py (+2/-2) openlp/plugins/media/lib/mediaitem.py (+16/-6) tests/functional/openlp_core/ui/media/test_mediacontroller.py (+43/-2) |
To merge this branch: | bzr merge lp:~trb143/openlp/more_media |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Phill | Approve | ||
Review via email: mp+368841@code.launchpad.net |
This proposal has been superseded by a proposal from 2019-06-14.
Commit message
Adds basic streaming service item
UI to set up streaming
Fix issues with suffix refactor
Description of the change
To post a comment you must log in.
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : | # |
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : | # |
Linting failed, please see https:/
lp:~trb143/openlp/more_media
updated
- 2883. By Tim Bentley
-
Fix streaming part1
Revision history for this message
Phill (phill-ridout) wrote : | # |
Just one inconsistency with text labels (see inline) and the failed linting, but other than that looks ok!
review:
Needs Fixing
lp:~trb143/openlp/more_media
updated
- 2884. By Tim Bentley
-
colon
Revision history for this message
Phill (phill-ridout) : | # |
review:
Approve
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'openlp/core/common/settings.py' |
2 | --- openlp/core/common/settings.py 2019-06-10 20:22:22 +0000 |
3 | +++ openlp/core/common/settings.py 2019-06-14 18:00:17 +0000 |
4 | @@ -210,6 +210,8 @@ |
5 | 'media/media auto start': QtCore.Qt.Unchecked, |
6 | 'media/stream command': '', |
7 | 'media/vlc arguments': '', |
8 | + 'media/video': '', |
9 | + 'media/audio': '', |
10 | 'remotes/download version': '0.0', |
11 | 'players/background color': '#000000', |
12 | 'servicemanager/last directory': None, |
13 | |
14 | === modified file 'openlp/core/lib/__init__.py' |
15 | --- openlp/core/lib/__init__.py 2019-05-22 06:47:00 +0000 |
16 | +++ openlp/core/lib/__init__.py 2019-06-14 18:00:17 +0000 |
17 | @@ -173,6 +173,7 @@ |
18 | HasNotes = 20 |
19 | HasThumbnails = 21 |
20 | HasMetaData = 22 |
21 | + CanStream = 23 |
22 | |
23 | |
24 | def get_text_file_string(text_file_path): |
25 | |
26 | === modified file 'openlp/core/ui/media/__init__.py' |
27 | --- openlp/core/ui/media/__init__.py 2019-04-13 13:00:22 +0000 |
28 | +++ openlp/core/ui/media/__init__.py 2019-06-14 18:00:17 +0000 |
29 | @@ -26,6 +26,19 @@ |
30 | |
31 | log = logging.getLogger(__name__ + '.__init__') |
32 | |
33 | +# Audio and video extensions copied from 'include/vlc_interface.h' from vlc 2.2.0 source |
34 | +AUDIO_EXT = ['*.3ga', '*.669', '*.a52', '*.aac', '*.ac3', '*.adt', '*.adts', '*.aif', '*.aifc', '*.aiff', '*.amr', |
35 | + '*.aob', '*.ape', '*.awb', '*.caf', '*.dts', '*.flac', '*.it', '*.kar', '*.m4a', '*.m4b', '*.m4p', '*.m5p', |
36 | + '*.mid', '*.mka', '*.mlp', '*.mod', '*.mpa', '*.mp1', '*.mp2', '*.mp3', '*.mpc', '*.mpga', '*.mus', |
37 | + '*.oga', '*.ogg', '*.oma', '*.opus', '*.qcp', '*.ra', '*.rmi', '*.s3m', '*.sid', '*.spx', '*.thd', '*.tta', |
38 | + '*.voc', '*.vqf', '*.w64', '*.wav', '*.wma', '*.wv', '*.xa', '*.xm'] |
39 | +VIDEO_EXT = ['*.3g2', '*.3gp', '*.3gp2', '*.3gpp', '*.amv', '*.asf', '*.avi', '*.bik', '*.divx', '*.drc', '*.dv', |
40 | + '*.f4v', '*.flv', '*.gvi', '*.gxf', '*.iso', '*.m1v', '*.m2v', '*.m2t', '*.m2ts', '*.m4v', '*.mkv', |
41 | + '*.mov', '*.mp2', '*.mp2v', '*.mp4', '*.mp4v', '*.mpe', '*.mpeg', '*.mpeg1', '*.mpeg2', '*.mpeg4', '*.mpg', |
42 | + '*.mpv2', '*.mts', '*.mtv', '*.mxf', '*.mxg', '*.nsv', '*.nuv', '*.ogg', '*.ogm', '*.ogv', '*.ogx', '*.ps', |
43 | + '*.rec', '*.rm', '*.rmvb', '*.rpl', '*.thp', '*.tod', '*.ts', '*.tts', '*.txd', '*.vob', '*.vro', '*.webm', |
44 | + '*.wm', '*.wmv', '*.wtv', '*.xesc', '*.nut', '*.rv', '*.xvid'] |
45 | + |
46 | |
47 | class MediaState(object): |
48 | """ |
49 | |
50 | === modified file 'openlp/core/ui/media/mediacontroller.py' |
51 | --- openlp/core/ui/media/mediacontroller.py 2019-06-05 04:53:18 +0000 |
52 | +++ openlp/core/ui/media/mediacontroller.py 2019-06-14 18:00:17 +0000 |
53 | @@ -42,9 +42,9 @@ |
54 | from openlp.core.lib.serviceitem import ItemCapabilities |
55 | from openlp.core.lib.ui import critical_error_message_box |
56 | from openlp.core.ui import DisplayControllerType |
57 | -from openlp.core.ui.media import MediaState, ItemMediaInfo, MediaType, parse_optical_path |
58 | +from openlp.core.ui.media import MediaState, ItemMediaInfo, MediaType, parse_optical_path, VIDEO_EXT, AUDIO_EXT |
59 | from openlp.core.ui.media.endpoint import media_endpoint |
60 | -from openlp.core.ui.media.vlcplayer import AUDIO_EXT, VIDEO_EXT, VlcPlayer, get_vlc |
61 | +from openlp.core.ui.media.vlcplayer import VlcPlayer, get_vlc |
62 | |
63 | |
64 | log = logging.getLogger(__name__) |
65 | @@ -184,7 +184,8 @@ |
66 | display.has_audio = False |
67 | self.vlc_player.setup(display, preview) |
68 | |
69 | - def set_controls_visible(self, controller, value): |
70 | + @staticmethod |
71 | + def set_controls_visible(controller, value): |
72 | """ |
73 | After a new display is configured, all media related widget will be created too |
74 | |
75 | @@ -229,7 +230,10 @@ |
76 | display = self._define_display(controller) |
77 | if controller.is_live: |
78 | # if this is an optical device use special handling |
79 | - if service_item.is_capable(ItemCapabilities.IsOptical): |
80 | + if service_item.is_capable(ItemCapabilities.CanStream): |
81 | + is_valid = self._check_file_type(controller, display, True) |
82 | + controller.media_info.media_type = MediaType.Stream |
83 | + elif service_item.is_capable(ItemCapabilities.IsOptical): |
84 | log.debug('video is optical and live') |
85 | path = service_item.get_frame_path() |
86 | (name, title, audio_track, subtitle_track, start, end, clip_name) = parse_optical_path(path) |
87 | @@ -249,7 +253,10 @@ |
88 | controller.media_info.start_time = service_item.start_time |
89 | controller.media_info.end_time = service_item.end_time |
90 | elif controller.preview_display: |
91 | - if service_item.is_capable(ItemCapabilities.IsOptical): |
92 | + if service_item.is_capable(ItemCapabilities.CanStream): |
93 | + controller.media_info.media_type = MediaType.Stream |
94 | + is_valid = self._check_file_type(controller, display, True) |
95 | + elif service_item.is_capable(ItemCapabilities.IsOptical): |
96 | log.debug('video is optical and preview') |
97 | path = service_item.get_frame_path() |
98 | (name, title, audio_track, subtitle_track, start, end, clip_name) = parse_optical_path(path) |
99 | @@ -270,6 +277,8 @@ |
100 | # display.frame.runJavaScript('show_video("setBackBoard", null, null,"visible");') |
101 | # now start playing - Preview is autoplay! |
102 | autoplay = False |
103 | + if service_item.is_capable(ItemCapabilities.CanStream): |
104 | + autoplay = True |
105 | # Preview requested |
106 | if not controller.is_live: |
107 | autoplay = True |
108 | @@ -346,13 +355,21 @@ |
109 | controller.media_info.media_type = MediaType.DVD |
110 | return True |
111 | |
112 | - def _check_file_type(self, controller, display): |
113 | + def _check_file_type(self, controller, display, stream=False): |
114 | """ |
115 | Select the correct media Player type from the prioritized Player list |
116 | |
117 | :param controller: First element is the controller which should be used |
118 | :param display: Which display to use |
119 | + :param stream: Are we streaming or not |
120 | """ |
121 | + if stream: |
122 | + self.resize(display, self.vlc_player) |
123 | + display.media_info.media_type = MediaType.Stream |
124 | + if self.vlc_player.load(display, None): |
125 | + self.current_media_players[controller.controller_type] = self.vlc_player |
126 | + return True |
127 | + return True |
128 | for file in controller.media_info.file_info: |
129 | if file.is_file: |
130 | suffix = '*%s' % file.suffix.lower() |
131 | |
132 | === modified file 'openlp/core/ui/media/mediatab.py' |
133 | --- openlp/core/ui/media/mediatab.py 2019-05-04 19:47:06 +0000 |
134 | +++ openlp/core/ui/media/mediatab.py 2019-06-14 18:00:17 +0000 |
135 | @@ -32,10 +32,10 @@ |
136 | from openlp.core.common.settings import Settings |
137 | from openlp.core.lib.settingstab import SettingsTab |
138 | from openlp.core.ui.icons import UiIcons |
139 | - |
140 | -LINUX_STREAM = 'v4l2://{video} :v4l2-standard= :input-slave={audio} :live-caching=300' |
141 | +#vlc v4l2:///dev/video0:v4l2-standard= :input-slave=alsa://hw:0,0 :live-caching=300 |
142 | +LINUX_STREAM = 'v4l2://{video}:v4l2-standard= :input-slave=alsa://{audio} :live-caching=300' |
143 | WIN_STREAM = 'dshow://:dshow-vdev={video} :dshow-adev={audio} :live-caching=300' |
144 | -OSX_STREAM = 'avcapture://{video} :qtsound://{audio} :live-caching=300' |
145 | +OSX_STREAM = 'avcapture://{video}:qtsound://{audio}:live-caching=300' |
146 | |
147 | log = logging.getLogger(__name__) |
148 | |
149 | @@ -68,11 +68,15 @@ |
150 | self.left_layout.addWidget(self.live_media_group_box) |
151 | self.stream_media_group_box = QtWidgets.QGroupBox(self.left_column) |
152 | self.stream_media_group_box.setObjectName('stream_media_group_box') |
153 | - self.stream_media_layout = QtWidgets.QHBoxLayout(self.stream_media_group_box) |
154 | + self.stream_media_layout = QtWidgets.QFormLayout(self.stream_media_group_box) |
155 | self.stream_media_layout.setObjectName('stream_media_layout') |
156 | self.stream_media_layout.setContentsMargins(0, 0, 0, 0) |
157 | - self.stream_edit = QtWidgets.QLabel(self) |
158 | - self.stream_media_layout.addWidget(self.stream_edit) |
159 | + self.video_edit = QtWidgets.QLineEdit(self) |
160 | + self.stream_media_layout.addRow(translate('MediaPlugin.MediaTab', 'Video:'), self.video_edit) |
161 | + self.audio_edit = QtWidgets.QLineEdit(self) |
162 | + self.stream_media_layout.addRow(translate('MediaPlugin.MediaTab', 'Audio'), self.audio_edit) |
163 | + self.stream_cmd = QtWidgets.QLabel(self) |
164 | + self.stream_media_layout.addWidget(self.stream_cmd) |
165 | self.left_layout.addWidget(self.stream_media_group_box) |
166 | self.vlc_arguments_group_box = QtWidgets.QGroupBox(self.left_column) |
167 | self.vlc_arguments_group_box.setObjectName('vlc_arguments_group_box') |
168 | @@ -84,7 +88,6 @@ |
169 | self.left_layout.addWidget(self.vlc_arguments_group_box) |
170 | self.left_layout.addStretch() |
171 | self.right_layout.addStretch() |
172 | - # # Signals and slots |
173 | |
174 | def retranslate_ui(self): |
175 | """ |
176 | @@ -100,22 +103,28 @@ |
177 | Load the settings |
178 | """ |
179 | self.auto_start_check_box.setChecked(Settings().value(self.settings_section + '/media auto start')) |
180 | - self.stream_edit.setText(Settings().value(self.settings_section + '/stream command')) |
181 | - if not self.stream_edit.text(): |
182 | - if is_linux: |
183 | - self.stream_edit.setText(LINUX_STREAM) |
184 | - elif is_win: |
185 | - self.stream_edit.setText(WIN_STREAM) |
186 | - else: |
187 | - self.stream_edit.setText(OSX_STREAM) |
188 | + self.stream_cmd.setText(Settings().value(self.settings_section + '/stream command')) |
189 | + self.audio_edit.setText(Settings().value(self.settings_section + '/audio')) |
190 | + self.video_edit.setText(Settings().value(self.settings_section + '/video')) |
191 | + if not self.stream_cmd.text(): |
192 | + self.set_base_stream() |
193 | self.vlc_arguments_edit.setPlainText(Settings().value(self.settings_section + '/vlc arguments')) |
194 | if Settings().value('advanced/experimental'): |
195 | + # vlc.MediaPlayer().audio_output_device_enum() |
196 | for cam in QCameraInfo.availableCameras(): |
197 | log.debug(cam.deviceName()) |
198 | log.debug(cam.description()) |
199 | for au in QAudioDeviceInfo.availableDevices(QAudio.AudioInput): |
200 | log.debug(au.deviceName()) |
201 | |
202 | + def set_base_stream(self): |
203 | + if is_linux: |
204 | + self.stream_cmd.setText(LINUX_STREAM) |
205 | + elif is_win: |
206 | + self.stream_cmd.setText(WIN_STREAM) |
207 | + else: |
208 | + self.stream_cmd.setText(OSX_STREAM) |
209 | + |
210 | def save(self): |
211 | """ |
212 | Save the settings |
213 | @@ -123,8 +132,12 @@ |
214 | setting_key = self.settings_section + '/media auto start' |
215 | if Settings().value(setting_key) != self.auto_start_check_box.checkState(): |
216 | Settings().setValue(setting_key, self.auto_start_check_box.checkState()) |
217 | - Settings().setValue(self.settings_section + '/stream command', self.stream_edit.text()) |
218 | + Settings().setValue(self.settings_section + '/stream command', self.stream_cmd.text()) |
219 | Settings().setValue(self.settings_section + '/vlc arguments', self.vlc_arguments_edit.toPlainText()) |
220 | + Settings().setValue(self.settings_section + '/video', self.video_edit.text()) |
221 | + Settings().setValue(self.settings_section + '/audio', self.audio_edit.text()) |
222 | + self.stream_cmd.setText(self.stream_cmd.text().format(video=self.video_edit.text(), |
223 | + audio=self.audio_edit.text())) |
224 | |
225 | def post_set_up(self, post_update=False): |
226 | """ |
227 | |
228 | === modified file 'openlp/core/ui/media/vlcplayer.py' |
229 | --- openlp/core/ui/media/vlcplayer.py 2019-06-11 19:13:35 +0000 |
230 | +++ openlp/core/ui/media/vlcplayer.py 2019-06-14 18:00:17 +0000 |
231 | @@ -40,18 +40,6 @@ |
232 | log = logging.getLogger(__name__) |
233 | |
234 | # Audio and video extensions copied from 'include/vlc_interface.h' from vlc 2.2.0 source |
235 | -AUDIO_EXT = ('3ga', '669', 'a52', 'aac', 'ac3', 'adt', 'adts', 'aif', 'aifc', 'aiff', 'amr', 'aob', 'ape', 'awb', 'caf', |
236 | - 'dts', 'flac', 'it', 'kar', 'm4a', 'm4b', 'm4p', 'm5p', 'mid', 'mka', 'mlp', 'mod', 'mpa', 'mp1', 'mp2', |
237 | - 'mp3', 'mpc', 'mpga', 'mus', 'oga', 'ogg', 'oma', 'opus', 'qcp', 'ra', 'rmi', 's3m', 'sid', 'spx', 'thd', |
238 | - 'tta', 'voc', 'vqf', 'w64', 'wav', 'wma', 'wv', 'xa', 'xm') |
239 | - |
240 | -VIDEO_EXT = ('3g2', '3gp', '3gp2', '3gpp', 'amv', 'asf', 'avi', 'bik', 'divx', 'drc', 'dv', 'f4v', 'flv', 'gvi', 'gxf', |
241 | - 'iso', 'm1v', 'm2v', 'm2t', 'm2ts', 'm4v', 'mkv', 'mov', 'mp2', 'mp2v', 'mp4', 'mp4v', 'mpe', 'mpeg', |
242 | - 'mpeg1', 'mpeg2', 'mpeg4', 'mpg', 'mpv2', 'mts', 'mtv', 'mxf', 'mxg', 'nsv', 'nuv', 'ogg', 'ogm', 'ogv', |
243 | - 'ogx', 'ps', 'rec', 'rm', 'rmvb', 'rpl', 'thp', 'tod', 'ts', 'tts', 'txd', 'vob', 'vro', 'webm', 'wm', |
244 | - 'wmv', 'wtv', 'xesc', |
245 | - # These extensions was not in the official list, added manually. |
246 | - 'nut', 'rv', 'xvid') |
247 | |
248 | |
249 | def get_vlc(): |
250 | @@ -159,16 +147,15 @@ |
251 | Load a video into VLC |
252 | |
253 | :param output_display: The display where the media is |
254 | - :param file: file to be played |
255 | + :param file: file to be played or None for live streaming |
256 | :return: |
257 | """ |
258 | vlc = get_vlc() |
259 | log.debug('load vid in Vlc Controller') |
260 | - controller = output_display |
261 | - volume = controller.media_info.volume |
262 | - path = os.path.normcase(file) |
263 | + if file: |
264 | + path = os.path.normcase(file) |
265 | # create the media |
266 | - if controller.media_info.media_type == MediaType.CD: |
267 | + if output_display.media_info.media_type == MediaType.CD: |
268 | if is_win(): |
269 | path = '/' + path |
270 | output_display.vlc_media = output_display.vlc_instance.media_new_location('cdda://' + path) |
271 | @@ -180,8 +167,8 @@ |
272 | audio_cd_tracks = output_display.vlc_media.subitems() |
273 | if not audio_cd_tracks or audio_cd_tracks.count() < 1: |
274 | return False |
275 | - output_display.vlc_media = audio_cd_tracks.item_at_index(controller.media_info.title_track) |
276 | - elif controller.media_info.media_type == MediaType.Stream: |
277 | + output_display.vlc_media = audio_cd_tracks.item_at_index(output_display.media_info.title_track) |
278 | + elif output_display.media_info.media_type == MediaType.Stream: |
279 | stream_cmd = Settings().value('media/stream command') |
280 | output_display.vlc_media = output_display.vlc_instance.media_new_location(stream_cmd) |
281 | else: |
282 | @@ -190,7 +177,7 @@ |
283 | output_display.vlc_media_player.set_media(output_display.vlc_media) |
284 | # parse the metadata of the file |
285 | output_display.vlc_media.parse() |
286 | - self.volume(output_display, volume) |
287 | + self.volume(output_display, output_display.media_info.volume) |
288 | return True |
289 | |
290 | def media_state_wait(self, output_display, media_state): |
291 | |
292 | === modified file 'openlp/core/ui/servicemanager.py' |
293 | --- openlp/core/ui/servicemanager.py 2019-06-04 20:03:54 +0000 |
294 | +++ openlp/core/ui/servicemanager.py 2019-06-14 18:00:17 +0000 |
295 | @@ -48,7 +48,7 @@ |
296 | from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem |
297 | from openlp.core.lib.ui import create_widget_action, critical_error_message_box, find_and_set_in_combo_box |
298 | from openlp.core.ui.icons import UiIcons |
299 | -from openlp.core.ui.media.vlcplayer import AUDIO_EXT, VIDEO_EXT |
300 | +from openlp.core.ui.media import AUDIO_EXT, VIDEO_EXT |
301 | from openlp.core.ui.serviceitemeditform import ServiceItemEditForm |
302 | from openlp.core.ui.servicenoteform import ServiceNoteForm |
303 | from openlp.core.ui.starttimeform import StartTimeForm |
304 | |
305 | === modified file 'openlp/core/ui/themeform.py' |
306 | --- openlp/core/ui/themeform.py 2019-06-07 20:25:30 +0000 |
307 | +++ openlp/core/ui/themeform.py 2019-06-14 18:00:17 +0000 |
308 | @@ -32,7 +32,7 @@ |
309 | from openlp.core.common.registry import Registry |
310 | from openlp.core.lib.theme import BackgroundGradientType, BackgroundType |
311 | from openlp.core.lib.ui import critical_error_message_box |
312 | -from openlp.core.ui.media.vlcplayer import VIDEO_EXT |
313 | +from openlp.core.ui.media import VIDEO_EXT |
314 | from openlp.core.ui.themelayoutform import ThemeLayoutForm |
315 | from openlp.core.ui.themewizard import Ui_ThemeWizard |
316 | |
317 | |
318 | === modified file 'openlp/core/widgets/widgets.py' |
319 | --- openlp/core/widgets/widgets.py 2019-04-13 13:00:22 +0000 |
320 | +++ openlp/core/widgets/widgets.py 2019-06-14 18:00:17 +0000 |
321 | @@ -103,8 +103,8 @@ |
322 | :param QtWidgets.QRadioButton button: The button that has toggled |
323 | :param bool checked: The buttons new state |
324 | """ |
325 | - id = self.radio_group.id(button) # The work around (see above comment) |
326 | - enable_manual_edits = id == ProxyMode.MANUAL_PROXY and checked |
327 | + group_id = self.radio_group.id(button) # The work around (see above comment) |
328 | + enable_manual_edits = group_id == ProxyMode.MANUAL_PROXY and checked |
329 | self.http_edit.setEnabled(enable_manual_edits) |
330 | self.https_edit.setEnabled(enable_manual_edits) |
331 | self.username_edit.setEnabled(enable_manual_edits) |
332 | |
333 | === modified file 'openlp/plugins/media/lib/mediaitem.py' |
334 | --- openlp/plugins/media/lib/mediaitem.py 2019-06-11 05:01:02 +0000 |
335 | +++ openlp/plugins/media/lib/mediaitem.py 2019-06-14 18:00:17 +0000 |
336 | @@ -37,8 +37,8 @@ |
337 | from openlp.core.lib.serviceitem import ItemCapabilities |
338 | from openlp.core.lib.ui import critical_error_message_box |
339 | from openlp.core.ui.icons import UiIcons |
340 | -from openlp.core.ui.media import parse_optical_path, format_milliseconds |
341 | -from openlp.core.ui.media.vlcplayer import AUDIO_EXT, VIDEO_EXT, get_vlc |
342 | +from openlp.core.ui.media import parse_optical_path, format_milliseconds, AUDIO_EXT, VIDEO_EXT |
343 | +from openlp.core.ui.media.vlcplayer import get_vlc |
344 | |
345 | |
346 | if get_vlc() is not None: |
347 | @@ -175,7 +175,11 @@ |
348 | return False |
349 | filename = str(item.data(QtCore.Qt.UserRole)) |
350 | # Special handling if the filename is a optical clip |
351 | - if filename.startswith('optical:'): |
352 | + if filename == 'live': |
353 | + service_item.processor = 'vlc' |
354 | + service_item.title = filename |
355 | + service_item.add_capability(ItemCapabilities.CanStream) |
356 | + elif filename.startswith('optical:'): |
357 | (name, title, audio_track, subtitle_track, start, end, clip_name) = parse_optical_path(filename) |
358 | if not os.path.exists(name): |
359 | if not remote: |
360 | @@ -232,9 +236,9 @@ |
361 | """ |
362 | # self.populate_display_types() |
363 | self.on_new_file_masks = translate('MediaPlugin.MediaItem', |
364 | - 'Videos (*.{video});;Audio (*.{audio});;{files} ' |
365 | - '(*)').format(video=' *.'.join(VIDEO_EXT), |
366 | - audio=' *.'.join(AUDIO_EXT), |
367 | + 'Videos ({video});;Audio ({audio});;{files} ' |
368 | + '(*)').format(video=' '.join(VIDEO_EXT), |
369 | + audio=' '.join(AUDIO_EXT), |
370 | files=UiStrings().AllFiles) |
371 | |
372 | def on_delete_click(self): |
373 | @@ -258,6 +262,12 @@ |
374 | """ |
375 | # TODO needs to be fixed as no idea why this fails |
376 | # media.sort(key=lambda file_path: get_natural_key(file_path.name)) |
377 | + file_name = translate('MediaPlugin.MediaItem', 'Live Stream') |
378 | + item_name = QtWidgets.QListWidgetItem(file_name) |
379 | + item_name.setIcon(UiIcons().video) |
380 | + item_name.setData(QtCore.Qt.UserRole, 'live') |
381 | + item_name.setToolTip(translate('MediaPlugin.MediaItem', 'Show Live Stream')) |
382 | + self.list_view.addItem(item_name) |
383 | for track in media: |
384 | track_str = str(track) |
385 | track_info = QtCore.QFileInfo(track_str) |
386 | |
387 | === modified file 'tests/functional/openlp_core/ui/media/test_mediacontroller.py' |
388 | --- tests/functional/openlp_core/ui/media/test_mediacontroller.py 2019-05-31 20:19:15 +0000 |
389 | +++ tests/functional/openlp_core/ui/media/test_mediacontroller.py 2019-06-14 18:00:17 +0000 |
390 | @@ -27,6 +27,7 @@ |
391 | |
392 | from openlp.core.common.registry import Registry |
393 | from openlp.core.ui.media.mediacontroller import MediaController |
394 | +from openlp.core.ui.media import ItemMediaInfo |
395 | from tests.helpers.testmixin import TestMixin |
396 | |
397 | from tests.utils.constants import RESOURCE_PATH |
398 | @@ -57,7 +58,7 @@ |
399 | # THEN: The player's resize method should be called correctly |
400 | mocked_player.resize.assert_called_with(mocked_display) |
401 | |
402 | - def test_check_file_type(self): |
403 | + def test_check_file_type_null(self): |
404 | """ |
405 | Test that we don't try to play media when no players available |
406 | """ |
407 | @@ -71,7 +72,47 @@ |
408 | ret = media_controller._check_file_type(mocked_controller, mocked_display) |
409 | |
410 | # THEN: it should return False |
411 | - assert ret is False, '_check_file_type should return False when no mediaplayers are available.' |
412 | + assert ret is False, '_check_file_type should return False when no media file matches.' |
413 | + |
414 | + def test_check_file_video(self): |
415 | + """ |
416 | + Test that we process a file that is valid |
417 | + """ |
418 | + # GIVEN: A mocked UiStrings, get_used_players, controller, display and service_item |
419 | + media_controller = MediaController() |
420 | + mocked_controller = MagicMock() |
421 | + mocked_display = MagicMock() |
422 | + media_controller.media_players = MagicMock() |
423 | + mocked_controller.media_info = ItemMediaInfo() |
424 | + mocked_controller.media_info.file_info = [TEST_PATH / 'mp3_file.mp3'] |
425 | + media_controller.current_media_players = {} |
426 | + media_controller.vlc_player = MagicMock() |
427 | + |
428 | + # WHEN: calling _check_file_type when no players exists |
429 | + ret = media_controller._check_file_type(mocked_controller, mocked_display) |
430 | + |
431 | + # THEN: it should return False |
432 | + assert ret is True, '_check_file_type should return True when audio file is present and matches.' |
433 | + |
434 | + def test_check_file_audio(self): |
435 | + """ |
436 | + Test that we process a file that is valid |
437 | + """ |
438 | + # GIVEN: A mocked UiStrings, get_used_players, controller, display and service_item |
439 | + media_controller = MediaController() |
440 | + mocked_controller = MagicMock() |
441 | + mocked_display = MagicMock() |
442 | + media_controller.media_players = MagicMock() |
443 | + mocked_controller.media_info = ItemMediaInfo() |
444 | + mocked_controller.media_info.file_info = [TEST_PATH / 'mp4_file.mp4'] |
445 | + media_controller.current_media_players = {} |
446 | + media_controller.vlc_player = MagicMock() |
447 | + |
448 | + # WHEN: calling _check_file_type when no players exists |
449 | + ret = media_controller._check_file_type(mocked_controller, mocked_display) |
450 | + |
451 | + # THEN: it should return False |
452 | + assert ret is True, '_check_file_type should return True when media file is present and matches.' |
453 | |
454 | def test_media_play_msg(self): |
455 | """ |
Linux tests passed!