Here is a patch which makes the playing of FXD movies more friendly:
when the movie is composed of several different media or files, it wont
display an error if at least one of the media/files is available. That
allows to easily play movies that are split into 2 CDs, and you have
only one CD drive. However, if no media at all was found for the given
movie, then it tells so. Same thing happens with the files: if no file
at all is available, it complains, but if at least one file is
available, it plays it and does not complain about the other ones.
The mplayer patch fixes a bug with the detection of the MPLAYER_VERSION
(if no version number can be detected, it sets the attribute to None)
and uses a list rather than a string for passing the arguments to the
program (this is not very useful, since Disch moved the really dangerous
stuff elsewhere, so it could be left out).
Matthieu
--
(~._.~) Matthieu Weber - Universit� de Jyv�skyl� (~._.~)
( ? ) email : [EMAIL PROTECTED] ( ? )
()- -() public key id : 452AE0AD ()- -()
(_)-(_) "Humor ist, wenn man trotzdem lacht (Germain Muller)" (_)-(_)
Index: fxdhandler.py
===================================================================
RCS file: /cvsroot/freevo/freevo/src/video/fxdhandler.py,v
retrieving revision 1.6
diff -u -r1.6 fxdhandler.py
--- fxdhandler.py 9 Dec 2003 19:43:01 -0000 1.6
+++ fxdhandler.py 18 Dec 2003 09:05:03 -0000
@@ -61,12 +61,13 @@
<dvd|vcd|file id name media_id mplayer_options>file</>+
<variants>
<variant>
- <part ref mplayer_options/>
- <subtitle media_id>file</subtitle>
- <audio media_id>file</audio>
- </variant>
+ <part ref mplayer_options>
+ <subtitle media_id>file</subtitle>
+ <audio media_id>file</audio>
+ </part>+
+ </variant>+
</variants>
- <info>
+ <info/>
</movie>
"""
@@ -76,8 +77,6 @@
"""
filename = fxd.gettext(node)
media_id = fxd.getattr(node, 'media-id')
- if media_id == '':
- filename = vfs.join(dirname, filename)
mode = node.name
id = fxd.getattr(node, 'id')
options = fxd.getattr(node, 'mplayer-options')
@@ -90,7 +89,8 @@
duplicates = fxd.getattr(None, 'duplicate_check', [])
if mode == 'file':
- filename = vfs.join(dirname, filename)
+ if not media_id:
+ filename = vfs.join(dirname, filename)
# mark the files we include in the fxd in _fxd_covered_
if not hasattr(item, '_fxd_covered_'):
@@ -152,7 +152,7 @@
if audio:
audio = { 'media_id': fxd.getattr(audio[0], 'media-id'),
'file' : fxd.gettext(audio[0]) }
- if audio['media_id'] == '':
+ if not audio['media_id']:
audio['file'] = vfs.join(dirname, audio['file'])
else:
audio = {}
@@ -162,7 +162,7 @@
if subtitle:
subtitle = { 'media_id': fxd.getattr(subtitle[0], 'media-id'),
'file' : fxd.gettext(subtitle[0]) }
- if subtitle['media_id'] == '':
+ if not subtitle['media_id']:
subtitle['file'] = vfs.join(dirname, subtitle['file'])
else:
subtitle = {}
@@ -182,7 +182,7 @@
if audio:
audio = { 'media_id': fxd.getattr(audio[0], 'media-id'),
'file' : fxd.gettext(audio[0]) }
- if audio['media_id'] == '':
+ if not audio['media_id']:
audio['file'] = vfs.join(dirname, audio['file'])
else:
audio = {}
@@ -190,7 +190,7 @@
if subtitle:
subtitle = { 'media_id': fxd.getattr(subtitle[0], 'media-id'),
'file' : fxd.gettext(subtitle[0]) }
- if subtitle['media_id'] == '':
+ if not subtitle['media_id']:
subtitle['file'] = vfs.join(dirname, subtitle['file'])
else:
subtitle = {}
Index: videoitem.py
===================================================================
RCS file: /cvsroot/freevo/freevo/src/video/videoitem.py,v
retrieving revision 1.101
diff -u -r1.101 videoitem.py
--- videoitem.py 9 Dec 2003 19:43:01 -0000 1.101
+++ videoitem.py 18 Dec 2003 09:05:03 -0000
@@ -391,13 +391,59 @@
def play_max_cache(self, arg=None, menuw=None):
self.play(menuw=menuw, arg='-cache 65536')
-
+
+ def set_next_available_subitem(self):
+ """
+ select the next available subitem. Loops on each subitem and checks if
+ the needed media is really there.
+ If the media is there, sets self.current_subitem to the given subitem
+ and returns 1.
+ If no media has been found, we set self.current_subitem to None.
+ If the search for the next available subitem did start from the
+ beginning of the list, then we consider that no media at all was
+ available for any subitem: we return 0.
+ If the search for the next available subitem did not start from the
+ beginning of the list, then we consider that at least one media
+ had been found in the past: we return 1.
+ """
+ cont = 1
+ from_start = 0
+ si = self.current_subitem
+ while cont:
+ if not si:
+ # No subitem selected yet: take the first one
+ si = self.subitems[0]
+ from_start = 1
+ else:
+ pos = self.subitems.index(si)
+ # Else take the next one
+ if pos < len(self.subitems)-1:
+ # Let's get the next subitem
+ si = self.subitems[pos+1]
+ else:
+ # No next subitem
+ si = None
+ cont = 0
+ if si:
+ if (si.media_id or si.media):
+ # If the file is on a removeable media
+ if util.check_media(si.media_id):
+ self.current_subitem = si
+ return 1
+ else:
+ # if not, it is always available
+ self.current_subitem = si
+ return 1
+ self.current_subitem = None
+ return not from_start
+
+
def play(self, arg=None, menuw=None):
"""
play the item.
"""
self.scan()
-
+
self.player_rating, self.player = self.possible_player[0]
self.parent.current_item = self
@@ -410,35 +456,49 @@
return
# if we have subitems (a movie with more than one file),
- # we start playing the first
+ # we start playing the first that is physically available
if self.subitems:
- self.current_subitem = self.subitems[0]
- # Pass along the options, without loosing the subitem's own
- # options
- if self.current_subitem.mplayer_options:
- if self.mplayer_options:
- self.current_subitem.mplayer_options += ' ' + self.mplayer_options
- else:
- self.current_subitem.mplayer_options = self.mplayer_options
- # When playing a subitem, the menu must be hidden. If it is not,
- # the playing will stop after the first subitem, since the
- # PLAY_END/USER_END event is not forwarded to the parent
- # videoitem.
- # And besides, we don't need the menu between two subitems.
- self.menuw.hide()
- self.current_subitem.play(arg, self.menuw)
+ self.error_in_subitem = 0
+ self.last_error_msg = ''
+ result = self.set_next_available_subitem()
+ if self.current_subitem: # 'result' is always 1 in this case
+ # The media is available now for playing
+ # Pass along the options, without loosing the subitem's own
+ # options
+ if self.current_subitem.mplayer_options:
+ if self.mplayer_options:
+ self.current_subitem.mplayer_options += ' ' +
self.mplayer_options
+ else:
+ self.current_subitem.mplayer_options = self.mplayer_options
+ # When playing a subitem, the menu must be hidden. If it is not,
+ # the playing will stop after the first subitem, since the
+ # PLAY_END/USER_END event is not forwarded to the parent
+ # videoitem.
+ # And besides, we don't need the menu between two subitems.
+ self.menuw.hide()
+ self.last_error_msg = self.current_subitem.play(arg, self.menuw)
+ if self.last_error_msg:
+ self.error_in_subitem = 1
+ # Go to the next playable subitem, using the loop in
+ # eventhandler()
+ self.eventhandler(PLAY_END)
+
+ elif not result:
+ # No media at all was found: error
+ ConfirmBox(text=(_('No media found for "%s".\n')+
+ _('Please insert the media.')) %
+ self.name, handler=self.play ).show()
return
-
# normal plackback of one file
if self.mode == "file":
file = self.filename
-
if self.media_id:
mountdir, file = util.resolve_media_mountdir(self.media_id,file)
if mountdir:
util.mount(mountdir)
else:
+ self.menuw.show()
ConfirmBox(text=(_('Media not found for file "%s".\n')+
_('Please insert the media.')) % file,
handler=self.play ).show()
@@ -453,6 +513,7 @@
if media:
self.media = media
else:
+ self.menuw.show()
ConfirmBox(text=(_('Media not not found for "%s".\n')+
_('Please insert the media.')) % self.url,
handler=self.play).show()
@@ -462,23 +523,28 @@
AlertBox(text=_('No player for this item found')).show()
return
- mplayer_options = self.mplayer_options
+ mplayer_options = self.mplayer_options.split(' ')
if not mplayer_options:
- mplayer_options = ""
+ mplayer_options = []
if arg:
- mplayer_options += ' %s' % arg
+ mplayer_options += arg.split[' ']
if self.menuw.visible:
self.menuw.hide()
self.plugin_eventhandler(PLAY, menuw)
-
+
error = self.player.play(mplayer_options, self)
if error:
- AlertBox(text=error).show()
- rc.post_event(PLAY_END)
+ # If we are a subitem we don't show any error message before
+ # having tried all the subitems
+ if self.parent.subitems:
+ return error
+ else:
+ AlertBox(text=error).show()
+ rc.post_event(PLAY_END)
def stop(self, arg=None, menuw=None):
@@ -540,18 +606,25 @@
if self.plugin_eventhandler(event, menuw):
return True
- # PLAY_END: do have have to play another file?
+ # PLAY_END: do we have to play another file?
if self.subitems:
if event == PLAY_END:
- try:
- pos = self.subitems.index(self.current_subitem)
- if pos < len(self.subitems)-1:
- self.current_subitem = self.subitems[pos+1]
- _debug_('playing next item')
- self.current_subitem.play(menuw=menuw)
+ self.set_next_available_subitem()
+ # Loop untli we find a subitem which plays without error
+ while self.current_subitem:
+ _debug_('playing next item')
+ error = self.current_subitem.play(menuw=menuw)
+ if error:
+ self.last_error_msg = error
+ self.error_in_subitem = 1
+ self.set_next_available_subitem()
+ else:
return True
- except:
- pass
+ if self.error_in_subitem:
+ # No more subitems to play, and an error occured
+ self.menuw.show()
+ AlertBox(text=self.last_error_msg).show()
+
elif event == USER_END:
pass
? patch
Index: mplayer.py
===================================================================
RCS file: /cvsroot/freevo/freevo/src/video/plugins/mplayer.py,v
retrieving revision 1.51
diff -u -r1.51 mplayer.py
--- mplayer.py 15 Dec 2003 03:45:29 -0000 1.51
+++ mplayer.py 18 Dec 2003 09:04:18 -0000
@@ -119,7 +119,9 @@
config.MPLAYER_VERSION = 0.9
elif data[ 0 : 7 ] == "dev-CVS":
config.MPLAYER_VERSION = 9999
- _debug_("MPlayer version set to: %s" % config.MPLAYER_VERSION)
+ else:
+ config.MPLAYER_VERSION = None
+ _debug_("MPlayer version set to: %s" % config.MPLAYER_VERSION)
child.wait()
# register mplayer as the object to play video
@@ -184,7 +186,10 @@
c_len = item.info.tracks[i].length
url = item.url + str(i+1)
- _debug_('MPlayer.play(): mode=%s, url=%s' % (mode, url))
+ try:
+ _debug_('MPlayer.play(): mode=%s, url=%s' % (mode, url))
+ except UnicodeError:
+ _debug_('MPlayer.play(): [non-ASCII data]')
if mode == 'file' and not os.path.isfile(url) and not network_play:
# This event allows the videoitem which contains subitems to
@@ -193,12 +198,11 @@
# Build the MPlayer command
- mpl = '--prio=%s %s %s -slave -ao %s' % (config.MPLAYER_NICE,
- config.MPLAYER_CMD,
- config.MPLAYER_ARGS_DEF,
- config.MPLAYER_AO_DEV)
+ mpl = [ '--prio=%s' % config.MPLAYER_NICE, config.MPLAYER_CMD ]
+ mpl += config.MPLAYER_ARGS_DEF.split(' ')
+ mpl += [ '-slave', '-ao', config.MPLAYER_AO_DEV ]
- additional_args = ''
+ additional_args = []
if mode == 'dvd':
if config.DVD_LANG_PREF:
@@ -209,43 +213,44 @@
if hasattr(item, 'mplayer_audio_broken') and
item.mplayer_audio_broken:
print '*** dvd audio broken, try without alang ***'
else:
- additional_args = '-alang %s' % config.DVD_LANG_PREF
+ additional_args += [ '-alang', config.DVD_LANG_PREF ]
if config.DVD_SUBTITLE_PREF:
# Only use if defined since it will always turn on subtitles
# if defined
- additional_args += ' -slang %s' % config.DVD_SUBTITLE_PREF
+ additional_args += [ '-slang', config.DVD_SUBTITLE_PREF ]
- additional_args += ' -dvd-device %s' % item.media.devicename
+ additional_args += [ '-dvd-device', item.media.devicename ]
if item.media:
- additional_args += ' -cdrom-device %s ' % item.media.devicename
+ additional_args += [ '-cdrom-device', item.media.devicename ]
if item.selected_subtitle == -1:
- additional_args += ' -noautosub'
+ additional_args += [ '-noautosub' ]
elif item.selected_subtitle and item.mode == 'file':
- additional_args += ' -vobsubid %s' % item.selected_subtitle
+ additional_args += [ '-vobsubid', item.selected_subtitle ]
elif item.selected_subtitle:
- additional_args += ' -sid %s' % item.selected_subtitle
+ additional_args += [ '-sid', item.selected_subtitle ]
if item.selected_audio:
- additional_args += ' -aid %s' % item.selected_audio
+ additional_args += [ '-aid', item.selected_audio ]
if item.deinterlace:
- additional_args += ' -vop pp=fd'
+ additional_args += [ '-vop', 'pp=fd' ]
mode = item.mime_type
if not config.MPLAYER_ARGS.has_key(mode):
mode = 'default'
# Mplayer command and standard arguments
- mpl += (' -v -vo ' + config.MPLAYER_VO_DEV + config.MPLAYER_VO_DEV_OPTS + \
- ' ' + config.MPLAYER_ARGS[mode])
+ mpl += [ '-v', '-vo', config.MPLAYER_VO_DEV +
+ config.MPLAYER_VO_DEV_OPTS ]
+ mpl += config.MPLAYER_ARGS[mode].split(' ')
# make the options a list
- mpl = mpl.split(' ') + additional_args.split(' ')
+ mpl += additional_args
if hasattr(item, 'is_playlist') and item.is_playlist:
mpl.append('-playlist')
@@ -254,7 +259,7 @@
mpl.append(url)
if options:
- mpl += options.split(' ')
+ mpl += options
# use software scaler?
if '-nosws' in mpl:
@@ -266,8 +271,8 @@
# correct avi delay based on mmpython settings
if config.MPLAYER_SET_AUDIO_DELAY and item.info.has_key('delay') and \
item.info['delay'] > 0:
- mpl += ('-mc', str(int(item.info['delay'])+1), '-delay',
- '-' + str(item.info['delay']))
+ mpl += [ '-mc', str(int(item.info['delay'])+1), '-delay',
+ '-' + str(item.info['delay']) ]
command = mpl