1import bento4.core as bt4 2import os.path as path 3import unittest 4from struct import pack 5 6BENTO4_TEST_DATA_DIR = path.join(path.dirname(__file__), '..', 'Data') 7 8class CoreTester(unittest.TestCase): 9 10 def setUp(self): 11 self.file = bt4.File(path.join(BENTO4_TEST_DATA_DIR, 'test-001.mp4')) 12 13 def test_moov_position(self): 14 self.assertTrue(self.file.moov_is_before_mdat) 15 16 def test_atom_type_name(self): 17 self.assertEquals('caca', bt4.atom_name(bt4.atom_type('caca'))) 18 self.assertNotEquals('zobi', bt4.atom_name(bt4.atom_type('fouf'))) 19 20 def test_filetype(self): 21 major_brand, minor_version, compat_brands = self.file.type 22 self.assertEquals(major_brand, bt4.File.FILE_BRAND_MP42) 23 self.assertEquals(minor_version, 1) 24 self.assertEquals(len(compat_brands), 2) 25 self.assertEquals(compat_brands[0], bt4.File.FILE_BRAND_MP42) 26 self.assertEquals(bt4.atom_name(compat_brands[1]), 'avc1') 27 28 def test_movie(self): 29 self.failIfEqual(self.file.movie, None, "no movie in file") 30 31 def test_tracks(self): 32 tracks = self.file.movie.tracks 33 known_values = { 34 1: {'type': bt4.Track.TYPE_AUDIO, 35 'handler_type': bt4.Track.HANDLER_TYPE_SOUN, 36 'sample_count': 78, 37 'durationms': 3600, 38 'media_timescale': 22050, 39 'sample_descriptions': [ 40 {'type': bt4.SampleDescription.TYPE_MPEG}, 41 ]}, 42 2: {'type': bt4.Track.TYPE_VIDEO, 43 'handler_type': bt4.Track.HANDLER_TYPE_VIDE, 44 'sample_count': 54, 45 'durationms': 3600, 46 'media_timescale': 30000, 47 'sample_descriptions': [ 48 {'type': bt4.SampleDescription.TYPE_AVC} 49 ]}, 50 3: {'type': bt4.Track.TYPE_HINT, 51 'handler_type': bt4.Track.HANDLER_TYPE_HINT, 52 'sample_count': 54, 53 'durationms': 3600, 54 'media_timescale': 90000}, 55 4: {'type': bt4.Track.TYPE_HINT, 56 'handler_type': bt4.Track.HANDLER_TYPE_HINT, 57 'sample_count': 39, 58 'durationms': 3600, 59 'media_timescale': 22050} 60 } 61 for id in known_values: 62 self.assertEquals(tracks[id].id, id) 63 self.assertEquals(tracks[id].type, known_values[id]['type']) 64 self.assertEquals(tracks[id].handler_type, 65 known_values[id]['handler_type']) 66 self.assertEquals(tracks[id].media_duration[1], 67 known_values[id]['media_timescale']) 68 self.assertEquals(tracks[id].sample_count, 69 known_values[id]['sample_count']) 70 duration, timescale = tracks[id].duration 71 self.assertEquals(duration*1000/timescale, 72 known_values[id]['durationms']) 73 if 'sample_descriptions' in known_values: 74 known_sample_descs = known_values['sample_descriptions'] 75 for i in xrange(len(sample_descs)): 76 self.assertEquals(sample_descs['type'], 77 tracks[id].sample_description(i).type) 78 79 def test_avc_track(self): 80 tracks = self.file.movie.tracks 81 avc_track = tracks[2] 82 test_filename = path.join(BENTO4_TEST_DATA_DIR, 'test-001.mp4.2') 83 try: 84 test_file = open(test_filename, 'rb') 85 avc_data = '' 86 for s in avc_track.sample_iterator(): 87 self.assertEquals(len(s.data), s.size) 88 self.assertEquals(s.description_index, 0) 89 avc_data += pack('>I', s.size) 90 avc_data += s.data 91 92 # test the sample data 93 test_data = test_file.read() 94 self.assertEquals(len(avc_data), len(test_data)) 95 self.assertEquals(avc_data, test_data, 96 'avc data mismatch') 97 98 # test the sample description 99 avc_desc = avc_track.sample_description(0) 100 self.assertEquals(avc_desc.type, bt4.SampleDescription.TYPE_AVC) 101 self.assertEquals(bt4.avc_profile_name(avc_desc.profile), "Main") 102 self.assertEquals(avc_desc.profile_compatibility, 0x40) 103 self.assertEquals(avc_desc.nalu_length_size, 4) 104 self.assertEquals(avc_desc.width, 160) 105 self.assertEquals(avc_desc.height, 120) 106 self.assertEquals(avc_desc.depth, 24) 107 108 finally: 109 test_file.close() 110 111 112if __name__ == '__main__': 113 unittest.main() 114 115