Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _determine_duration(self, fh):
# see: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
# and: https://en.wikipedia.org/wiki/WAV
riff, size, fformat = struct.unpack('4sI4s', fh.read(12))
if riff != b'RIFF' or fformat != b'WAVE':
raise TinyTagException('not a wave file!')
bitdepth = 16 # assume 16bit depth (CD quality)
chunk_header = fh.read(8)
while len(chunk_header) == 8:
subchunkid, subchunksize = struct.unpack('4sI', chunk_header)
if subchunkid == b'fmt ':
_, self.channels, self.samplerate = struct.unpack('HHI', fh.read(8))
_, _, bitdepth = struct.unpack('
return self._unpad(codecs.decode(b[1:], 'ISO-8859-1'))
elif first_byte == b'\x01': # UTF-16 with BOM
# read byte order mark to determine endianess
encoding = 'UTF-16be' if b[1:3] == b'\xfe\xff' else 'UTF-16le'
# strip the bom and optional null bytes
bytestr = b[3:-1] if len(b) % 2 == 0 else b[3:]
return self._unpad(codecs.decode(bytestr, encoding))
elif first_byte == b'\x02': # UTF-16LE
# strip optional null byte, if byte count uneven
bytestr = b[1:-1] if len(b) % 2 == 0 else b[1:]
return self._unpad(codecs.decode(bytestr, 'UTF-16le'))
elif first_byte == b'\x03': # UTF-8
return codecs.decode(b[1:], 'UTF-8')
return self._unpad(codecs.decode(b, 'ISO-8859-1')) # wild guess
except UnicodeDecodeError:
raise TinyTagException('Error decoding ID3 Tag!')
def _read(fh, nbytes): # helper function to check if we haven't reached EOF
b = fh.read(nbytes)
if len(b) < nbytes:
raise TinyTagException('Unexpected end of file')
return b
def load(self, tags, duration, image=False):
header = self._filehandler.peek(4)
if header[:3] == b'ID3': # parse ID3 header if it exists
id3 = ID3(self._filehandler, 0)
id3._parse_id3v2(self._filehandler)
self.update(id3)
header = self._filehandler.peek(4) # after ID3 should be fLaC
if header[:4] != b'fLaC':
raise TinyTagException('Invalid flac header')
self._filehandler.seek(4, os.SEEK_CUR)
self._determine_duration(self._filehandler, skip_tags=not tags)
def _parse_pages(self, fh):
# for the spec, see: https://wiki.xiph.org/Ogg
previous_page = b'' # contains data from previous (continuing) pages
header_data = fh.read(27) # read ogg page header
while len(header_data) != 0:
header = struct.unpack('<4sBBqIIiB', header_data)
oggs, version, flags, pos, serial, pageseq, crc, segments = header
self._max_samplenum = max(self._max_samplenum, pos)
if oggs != b'OggS' or version != 0:
raise TinyTagException('Not a valid ogg file!')
segsizes = struct.unpack('B'*segments, fh.read(segments))
total = 0
for segsize in segsizes: # read all segments
total += segsize
if total < 255: # less than 255 bytes means end of page
yield previous_page + fh.read(total)
previous_page = b''
total = 0
if total != 0:
if total % 255 == 0:
previous_page += fh.read(total)
else:
yield previous_page + fh.read(total)
previous_page = b''
header_data = fh.read(27)
def _get_parser_for_filename(cls, filename, exception=False):
mapping = {
('.mp3',): ID3,
('.oga', '.ogg', '.opus'): Ogg,
('.wav',): Wave,
('.flac',): Flac,
('.wma',): Wma,
('.m4b', '.m4a', '.mp4'): MP4,
}
for fileextension, tagclass in mapping.items():
if filename.lower().endswith(fileextension):
return tagclass
if exception:
raise TinyTagException('No tag reader found to support filetype! ')