[xiph-cvs] cvs commit: positron/positron MP3Info.py

Stan Seibert volsung at xiph.org
Tue Jun 3 20:39:06 PDT 2003



volsung     03/06/03 23:39:06

  Modified:    positron MP3Info.py
  Log:
  VBR header handling more robust and should deal with more cases where
  the header isn't where you expect it to be.  Closes bug 360.

Revision  Changes    Path
1.6       +30 -16    positron/positron/MP3Info.py

Index: MP3Info.py
===================================================================
RCS file: /usr/local/cvsroot/positron/positron/MP3Info.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- MP3Info.py	4 Jun 2003 02:42:37 -0000	1.5
+++ MP3Info.py	4 Jun 2003 03:39:06 -0000	1.6
@@ -302,7 +302,7 @@
         if not self.valid:
             raise Error("MPEG header not valid")
 
-        self._parse_xing(file)
+        self._parse_xing(file, seeklimit, seekstart)
         
 
     def _find_header(self, file, seeklimit=_MP3_HEADER_SEEK_LIMIT,
@@ -394,28 +394,42 @@
         
         self.valid = 1
 
-    def _parse_xing(self, file):
+    def _parse_xing(self, file, seekstart=0, seeklimit=_MP3_HEADER_SEEK_LIMIT):
         """Parse the Xing-specific header.
 
         For variable-bitrate (VBR) MPEG files, Xing includes a header which
         can be used to approximate the (average) bitrate and the duration
         of the file.
         """
-        file.seek(0, 0)
-        header = file.read(128)
-
-        i = string.find(header, 'Xing')
-        if i > 0:
-            (flags,) = struct.unpack('>i', header[i+4:i+8])
-            if flags & 3:
-                # flags says "frames" and "bytes" are present. use them.
-                (frames,) = struct.unpack('>i', header[i+8:i+12])
-                (bytes,) = struct.unpack('>i', header[i+12:i+16])
-
-                if self.samplerate:
-                    self.length = int(round(frames * self.samplesperframe / self.samplerate))
-                    self.bitrate = ((bytes * 8.0 / self.length) / 1000)
+        file.seek(seekstart, 0)
+        header = file.read(seeklimit)
 
+        try:
+            i = string.find(header, 'Xing')
+            if i > 0:
+                header += file.read(128)
+                (flags,) = struct.unpack('>i', header[i+4:i+8])
+                if flags & 3:
+                    # flags says "frames" and "bytes" are present. use them.
+                    (frames,) = struct.unpack('>i', header[i+8:i+12])
+                    (bytes,) = struct.unpack('>i', header[i+12:i+16])
+
+                    if self.samplerate:
+                        length = int(round(frames * self.samplesperframe / self.samplerate))
+                        bitrate = ((bytes * 8.0 / length) / 1000)
+                        self.length = length
+                        self.bitrate = bitrate
+                        return
+        except ZeroDivisionError:
+            pass # This header is bad
+        except struct.error:
+            pass # This header is bad
+
+        # If we made it here, the header wasn't any good.  Try at the beginning
+        # now just in case
+        if seekstart != 0:
+            self._parse_xing(file, 0, seeklimit)
+        
 class MP3Info:
     def __init__(self, file):
         self.valid = 0

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list