To work around the problem, I made a very quick hack:

on line 340 of libmpdemux/stream.c I replaced 'return 0' with
'exit(0)'

I don't know how this will affect other streamed media, so be careful,
but the result is perfect seeking in music files.



On Sun, Jan 18, 2004 at 11:25:19AM -0800, [EMAIL PROTECTED] wrote:
> Update of /cvsroot/freevo/freevo/WIP/Aubin
> In directory sc8-pr-cvs1:/tmp/cvs-serv3578
> 
> Added Files:
>       mplayer.py 
> Log Message:
> A version of the mp3 audio plugin which gives perfect seeking on VBR
> and other mp3 files...
> 
> One major problem:
> 
> o If you seek right to the end of a file, mplayer will go crazy and print
> "Seek Failed" and never quit. 
> 
> But it works very nicely if you ever skip through files.
> 
> It does two things.
> 
> 1) Pass '-hr-mp3-seek' for mp3 files
> 2) Send a 'seek -1' which worksaround a bug in mplayers time display when using 
> hr-mp3-seek.
> 
> 
> 
> 
> --- NEW FILE: mplayer.py ---
> #if 0 /*
> # -----------------------------------------------------------------------
> # mplayer.py - the Freevo MPlayer plugin for audio
> # -----------------------------------------------------------------------
> # $Id: mplayer.py,v 1.1 2004/01/18 19:25:16 outlyer Exp $
> #
> # Notes:
> # Todo:        
> #
> # -----------------------------------------------------------------------
> # $Log: mplayer.py,v $
> # Revision 1.1  2004/01/18 19:25:16  outlyer
> # A version of the mp3 audio plugin which gives perfect seeking on VBR
> # and other mp3 files...
> #
> # One major problem:
> #
> # o If you seek right to the end of a file, mplayer will go crazy and print
> # "Seek Failed" and never quit.
> #
> # But it works very nicely if you ever skip through files.
> #
> # It does two things.
> #
> # 1) Pass '-hr-mp3-seek' for mp3 files
> # 2) Send a 'seek -1' which worksaround a bug in mplayers time display when using 
> hr-mp3-seek.
> #
> # Revision 1.33  2004/01/14 20:36:16  mikeruelle
> # they guys do not play radio
> #
> # Revision 1.32  2003/12/29 22:33:30  dischi
> # Oops
> #
> # Revision 1.31  2003/12/29 22:09:19  dischi
> # move to new Item attributes
> #
> # Revision 1.30  2003/12/13 14:27:19  outlyer
> # Since ChildApp2 defaults to stopping the OSD, stop_osd=0 needs to be defined
> # here or the audio player will try to stop the display and then try to write
> # to the screen (and crash)
> #
> # Revision 1.29  2003/12/10 19:10:35  dischi
> # AUDIO_PLAY_END is not needed anymore
> #
> # Revision 1.28  2003/12/10 19:02:38  dischi
> # move to new ChildApp2 and remove the internal thread
> #
> # Revision 1.27  2003/12/06 13:43:35  dischi
> # expand the <audio> parsing in fxd files
> #
> # Revision 1.26  2003/11/22 15:30:55  dischi
> # support more than one player
> #
> # Revision 1.25  2003/11/11 18:01:44  dischi
> # fix playback problems with fxd files (and transform to list app style)
> #
> # Revision 1.24  2003/11/08 13:21:18  dischi
> # network m3u support, added AUDIOCD plugin register
> #
> # Revision 1.23  2003/10/21 21:17:41  gsbarbieri
> # Some more i18n improvements.
> #
> # Revision 1.22  2003/10/20 13:36:07  outlyer
> # Remove the double-quit
> #
> # -----------------------------------------------------------------------
> # Freevo - A Home Theater PC framework
> # Copyright (C) 2002 Krister Lagerstrom, et al. 
> # Please see the file freevo/Docs/CREDITS for a complete list of authors.
> #
> # This program is free software; you can redistribute it and/or modify
> # it under the terms of the GNU General Public License as published by
> # the Free Software Foundation; either version 2 of the License, or
> # (at your option) any later version.
> #
> # This program is distributed in the hope that it will be useful, but
> # WITHOUT ANY WARRANTY; without even the implied warranty of MER-
> # CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
> # Public License for more details.
> #
> # You should have received a copy of the GNU General Public License along
> # with this program; if not, write to the Free Software Foundation, Inc.,
> # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> #
> # ----------------------------------------------------------------------- */
> #endif
> 
> import os
> import re
> 
> import config     # Configuration handler. reads config file.
> import childapp   # Handle child applications
> 
> import rc
> import plugin
> 
> from event import *
> 
> 
> class PluginInterface(plugin.Plugin):
>     """
>     Mplayer plugin for the audio player. Use mplayer to play all audio
>     files.
>     """
>     def __init__(self):
>         # create the mplayer object
>         plugin.Plugin.__init__(self)
> 
>         # register mplayer as the object to play audio
>         plugin.register(MPlayer(), plugin.AUDIO_PLAYER, True)
> 
> 
> class MPlayer:
>     """
>     the main class to control mplayer
>     """
>     
>     def __init__(self):
>         self.name     = 'mplayer'
>         self.app_mode = 'audio'
>         self.app      = None
> 
> 
>     def rate(self, item):
>         """
>         How good can this player play the file:
>         2 = good
>         1 = possible, but not good
>         0 = unplayable
>         """
>         if item.url.startswith('radio://'):
>             return 0
>         if item.url.startswith('cdda://'):
>             return 1
>         return 2
> 
>     def get_demuxer(self, filename):
>         DEMUXER_MP3 = 17
>         DEMUXER_OGG = 18
>         rest, extension     = os.path.splitext(filename)
>         if extension.lower() == '.mp3':
>             return "-hr-mp3-seek -demuxer " + str(DEMUXER_MP3)
>         if extension.lower() == '.ogg':
>             return "-demuxer " + str(DEMUXER_OGG)
>         else:
>             return ''
> 
> 
>     def play(self, item, playerGUI):
>         """
>         play a audioitem with mplayer
>         """
>         self.playerGUI = playerGUI
>         filename       = item.filename
> 
>         if filename and not os.path.isfile(filename):
>             return _('%s\nnot found!') % item.url
>             
>         if not filename:
>             filename = item.url
>             
>         # Build the MPlayer command
>         mpl = '--prio=%s %s -slave %s' % (config.MPLAYER_NICE,
>                                           config.MPLAYER_CMD,
>                                           config.MPLAYER_ARGS_DEF)
> 
>         if not item.network_play:
>             demux = ' %s ' % self.get_demuxer(filename)
>         else:
>             # Don't include demuxer for network files
>             demux = ''
> 
>         extra_opts = item.mplayer_options
> 
>         is_playlist = False
>         if hasattr(item, 'is_playlist') and item.is_playlist:
>             is_playlist = True
>             
>         if item.network_play and filename.endswith('m3u'):
>             is_playlist = True
> 
>         if item.network_play:
>             extra_opts += ' -cache 100'
> 
>         if hasattr(item, 'reconnect') and item.reconnect:
>             extra_opts += ' -loop 0'
>             
>         command = '%s -vo null -ao %s %s %s' % (mpl, config.MPLAYER_AO_DEV, demux,
>                                                 extra_opts)
> 
>         if command.find('-playlist') > 0:
>             command = command.replace('-playlist', '')
>             
>         command = command.replace('\n', '').split(' ')
> 
>         if is_playlist:
>             command.append('-playlist')
>             
>         command.append(filename)
>         
>         if plugin.getbyname('MIXER'):
>             plugin.getbyname('MIXER').reset()
> 
>         self.item = item
> 
>         if not self.item.valid:
>             # Invalid file, show an error and survive.
>             return _('Invalid audio file')
> 
>         _debug_('MPlayer.play(): Starting cmd=%s' % command)
>             
>         self.app = MPlayerApp(command, self)
>         self.app.write('seek -1\n');
>         return None
>     
> 
>     def stop(self):
>         """
>         Stop mplayer
>         """
>         self.app.stop('quit\n')
> 
> 
>     def is_playing(self):
>         return self.app.isAlive()
> 
> 
>     def refresh(self):
>         self.playerGUI.refresh()
>         
> 
>     def eventhandler(self, event, menuw=None):
>         """
>         eventhandler for mplayer control. If an event is not bound in this
>         function it will be passed over to the items eventhandler
>         """
> 
>         if event == PLAY_END and event.arg:
>             self.stop()
>             if self.playerGUI.try_next_player():
>                 return True
>             
>         if event == AUDIO_SEND_MPLAYER_CMD:
>             self.app.write('%s\n' % event.arg)
>             return True
> 
>         if event in ( STOP, PLAY_END, USER_END ):
>             self.playerGUI.stop()
>             return self.item.eventhandler(event)
> 
>         elif event == PAUSE or event == PLAY:
>             self.app.write('pause\n')
>             return True
> 
>         elif event == SEEK:
>             self.app.write('seek %s\n' % event.arg)
>             return True
> 
>         else:
>             # everything else: give event to the items eventhandler
>             return self.item.eventhandler(event)
>             
>             
> # ======================================================================
> 
> class MPlayerApp(childapp.ChildApp2):
>     """
>     class controlling the in and output from the mplayer process
>     """
>     def __init__(self, app, player):
>         self.item        = player.item
>         self.player      = player
>         self.elapsed     = 0
>         self.stop_reason = 0 # 0 = ok, 1 = error
>         self.RE_TIME     = re.compile("^A: *([0-9]+)").match
>       self.RE_TIME_NEW = re.compile("^A: *([0-9]+):([0-9]+)").match
>         childapp.ChildApp2.__init__(self, app, stop_osd=0)
> 
> 
>     def stop_event(self):
>         return Event(PLAY_END, self.stop_reason, handler=self.player.eventhandler)
> 
>         
>     def stdout_cb(self, line):
>         if line.startswith("A:"):         # get current time
>             m = self.RE_TIME_NEW(line)
>             if m:
>                 self.stop_reason = 0
>               timestrs = m.group().split(":")
>               if len(timestrs) == 5:
>                   # playing for days!
>                     self.item.elapsed = 86400*int(timestrs[1]) + \
>                                       3600*int(timestrs[2]) + \
>                                       60*int(timestrs[3]) + \
>                                       int(timestrs[4])
>                 elif len(timestrs) == 4:
>                   # playing for hours
>                     self.item.elapsed = 3600*int(timestrs[1]) + \
>                                       60*int(timestrs[2]) + \
>                                       int(timestrs[3])
>                 elif len(timestrs) == 3:
>                   # playing for minutes
>                     self.item.elapsed = 60*int(timestrs[1]) + int(timestrs[2])
>                 elif len(timestrs) == 2:
>                   # playing for only seconds
>                     self.item.elapsed = int(timestrs[1])
>             else:
>                 m = self.RE_TIME(line) # Convert decimal 
>                 if m:
>                     self.item.elapsed = int(m.group(1))
> 
>             if self.item.elapsed != self.elapsed:
>                 self.player.refresh()
>             self.elapsed = self.item.elapsed
> 
> 
> 
>     def stderr_cb(self, line):
>         if line.startswith('Failed to open'):
>             self.stop_reason = 1
> 
> 
> 
> 
> -------------------------------------------------------
> The SF.Net email is sponsored by EclipseCon 2004
> Premiere Conference on Open Tools Development and Integration
> See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
> http://www.eclipsecon.org/osdn
> _______________________________________________
> Freevo-cvslog mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/freevo-cvslog


-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
Freevo-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freevo-devel

Reply via email to