def test_alac_2(self): # an example where the samplerate is only correct in the cookie, # also contains a bitrate atom_data = ( b'\x00\x00\x00Halac\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x02\x00\x18\x00\x00\x00\x00X\x88\x00' b'\x00\x00\x00\x00$alac\x00\x00\x00\x00\x00\x00\x10\x00\x00\x18' b'(\n\x0e\x02\x00\xff\x00\x00F/\x00%2\xd5\x00\x01X\x88') fileobj = BytesIO(atom_data) atom = Atom(fileobj) entry = AudioSampleEntry(atom, fileobj) self.assertEqual(entry.bitrate, 2437845) self.assertEqual(entry.channels, 2) self.assertEqual(entry.codec, "alac") self.assertEqual(entry.codec_description, "ALAC") self.assertEqual(entry.sample_rate, 88200)
def test_alac(self): # an exampe where the channel count in the alac cookie is right # but the SampleEntry is wrong atom_data = ( b'\x00\x00\x00Halac\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x02\x00\x10\x00\x00\x00\x00\x1f@\x00' b'\x00\x00\x00\x00$alac\x00\x00\x00\x00\x00\x00\x10\x00\x00\x10' b'(\n\x0e\x01\x00\xff\x00\x00P\x01\x00\x00\x00\x00\x00\x00\x1f@') fileobj = BytesIO(atom_data) atom = Atom(fileobj) entry = AudioSampleEntry(atom, fileobj) self.assertEqual(entry.bitrate, 0) self.assertEqual(entry.channels, 1) self.assertEqual(entry.codec, "alac") self.assertEqual(entry.codec_description, "ALAC") self.assertEqual(entry.sample_rate, 8000)
def _parse_stsd(self, atom, fileobj): """Sets channels, bits_per_sample, sample_rate and optionally bitrate. Can raise MP4StreamInfoError. """ assert atom.name == b"stsd" ok, data = atom.read(fileobj) if not ok: raise MP4StreamInfoError("Invalid stsd") try: version, flags, data = parse_full_atom(data) except ValueError as e: raise MP4StreamInfoError(e) if version != 0: raise MP4StreamInfoError("Unsupported stsd version") try: num_entries, offset = cdata.uint32_be_from(data, 0) except cdata.error as e: raise MP4StreamInfoError(e) if num_entries == 0: return # look at the first entry if there is one entry_fileobj = cBytesIO(data[offset:]) try: entry_atom = Atom(entry_fileobj) except AtomError as e: raise MP4StreamInfoError(e) try: entry = AudioSampleEntry(entry_atom, entry_fileobj) except ASEntryError as e: raise MP4StreamInfoError(e) else: self.channels = entry.channels self.bits_per_sample = entry.sample_size self.sample_rate = entry.sample_rate self.bitrate = entry.bitrate self.codec = entry.codec self.codec_description = entry.codec_description
def test_ac3(self): atom_data = ( b'\x00\x00\x00/ac-3\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x02\x00\x10\x00\x00\x00\x00V"\x00\x00' b'\x00\x00\x00\x0bdac3R\t\x00') fileobj = BytesIO(atom_data) atom = Atom(fileobj) entry = AudioSampleEntry(atom, fileobj) self.assertEqual(entry.bitrate, 128000) self.assertEqual(entry.channels, 1) self.assertEqual(entry.codec_description, "AC-3") self.assertEqual(entry.codec, "ac-3") self.assertEqual(entry.sample_rate, 22050) self.assertEqual(entry.sample_size, 16) self.assertTrue(isinstance(entry.codec, str)) self.assertTrue(isinstance(entry.codec_description, str))
def test_pce(self): atom_data = ( b'\x00\x00\x00dmp4a\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x02\x00\x10\x00\x00\x00\x00\xbb\x80' b'\x00\x00\x00\x00\x00@esds\x00\x00\x00\x00\x03\x80\x80\x80/\x00' b'\x00\x00\x04\x80\x80\x80!@\x15\x00\x15\x00\x00\x03\xed\xaa\x00' b'\x03k\x00\x05\x80\x80\x80\x0f+\x01\x88\x02\xc4\x04\x90,\x10\x8c' b'\x80\x00\x00\xed@\x06\x80\x80\x80\x01\x02') fileobj = BytesIO(atom_data) atom = Atom(fileobj) entry = AudioSampleEntry(atom, fileobj) self.assertEqual(entry.bitrate, 224000) self.assertEqual(entry.channels, 8) self.assertEqual(entry.codec_description, "AAC LC+SBR") self.assertEqual(entry.codec, "mp4a.40.2") self.assertEqual(entry.sample_rate, 48000) self.assertEqual(entry.sample_size, 16)
def test_samr(self): # parsing not implemented, values are wrong but at least it loads. # should be Mono 7.95kbps 8KHz atom_data = ( b'\x00\x00\x005samr\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x02\x00\x10\x00\x00\x00\x00\x1f@\x00' b'\x00\x00\x00\x00\x11damrFFMP\x00\x81\xff\x00\x01') fileobj = BytesIO(atom_data) atom = Atom(fileobj) entry = AudioSampleEntry(atom, fileobj) self.assertEqual(entry.bitrate, 0) self.assertEqual(entry.channels, 2) self.assertEqual(entry.codec_description, "SAMR") self.assertEqual(entry.codec, "samr") self.assertEqual(entry.sample_rate, 8000) self.assertEqual(entry.sample_size, 16) self.assertTrue(isinstance(entry.codec, str)) self.assertTrue(isinstance(entry.codec_description, str))
def test_als(self): atom_data = ( b'\x00\x00\x00\x9dmp4a\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00' b'\x00\x00\x00\x00\x00\x00\x02\x00\x00\x10\x00\x00\x00\x00\x07' b'\xd0\x00\x00\x00\x00\x00yesds\x00\x00\x00\x00\x03k\x00\x00\x00' b'\x04c@\x15\x10\xe7\xe6\x00W\xcbJ\x00W\xcbJ\x05T\xf8\x9e\x00\x0f' b'\xa0\x00ALS\x00\x00\x00\x07\xd0\x00\x00\x0c\t\x01\xff$O\xff\x00' b'g\xff\xfc\x80\x00\x00\x00,\x00\x00\x00\x00RIFF$$0\x00WAVEfmt ' b'\x10\x00\x00\x00\x01\x00\x00\x02\xd0\x07\x00\x00\x00@\x1f\x00' b'\x00\x04\x10\x00data\x00$0\x00\xf6\xceF+\x06\x01\x02') fileobj = BytesIO(atom_data) atom = Atom(fileobj) entry = AudioSampleEntry(atom, fileobj) self.assertEqual(entry.bitrate, 5753674) self.assertEqual(entry.channels, 512) self.assertEqual(entry.codec_description, "ALS") self.assertEqual(entry.codec, "mp4a.40.36") self.assertEqual(entry.sample_rate, 2000) self.assertEqual(entry.sample_size, 16)
def test_sbr_ps_sig_1(self): atom_data = ( b"\x00\x00\x00\\mp4a\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x02\x00\x10\x00\x00\x00\x00\xbb\x80\x00" b"\x00\x00\x00\x008esds\x00\x00\x00\x00\x03\x80\x80\x80'\x00\x00" b"\x00\x04\x80\x80\x80\x19@\x15\x00\x03\x00\x00\x00\xe9j\x00\x00" b"\xda\xc0\x05\x80\x80\x80\x07\x13\x08V\xe5\x9dH\x80\x06\x80\x80" b"\x80\x01\x02") fileobj = BytesIO(atom_data) atom = Atom(fileobj) entry = AudioSampleEntry(atom, fileobj) self.assertEqual(entry.bitrate, 56000) self.assertEqual(entry.channels, 2) self.assertEqual(entry.codec_description, "AAC LC+SBR+PS") self.assertEqual(entry.codec, "mp4a.40.2") self.assertEqual(entry.sample_rate, 48000) self.assertEqual(entry.sample_size, 16) self.assertTrue(isinstance(entry.codec, str)) self.assertTrue(isinstance(entry.codec_description, str))