示例#1
0
 def test_stco(self):
     with TemporaryFile() as f:
         f.write(b'\x00\x00\x00\xf8\x73\x74\x63\x6f\x00\x00\x00\x00\x00\x00\x00'
                 b'\x3a\x00\x00\x23\xfb\x00\x04\xc3\x1e\x00\x05\x7b\x55\x00\x07'
                 b'\x84\x5c\x00\x0a\xb0\xcd\x00\x0d\x4b\xf3\x00\x0e\x84\xa6\x00'
                 b'\x0f\xf5\x77\x00\x15\x34\x84\x00\x17\x28\xb4\x00\x19\xd8\x75'
                 b'\x00\x1a\xd8\x1f\x00\x1d\x4e\xdd\x00\x20\x54\xd7\x00\x22\xa4'
                 b'\x7a\x00\x25\x96\x16\x00\x28\x33\x6c\x00\x29\x40\x03\x00\x2a'
                 b'\xaa\x83\x00\x2b\xf2\x0f\x00\x2e\xae\xfd\x00\x30\x9f\x80\x00'
                 b'\x32\xb1\xf9\x00\x34\x72\x12\x00\x37\x52\x66\x00\x39\x45\xf8'
                 b'\x00\x3a\xd0\x8a\x00\x3c\xf1\x95\x00\x40\x2b\xec\x00\x42\x13'
                 b'\xba\x00\x44\x1e\xbe\x00\x46\x06\x7d\x00\x49\x4a\xbd\x00\x4b'
                 b'\x14\x65\x00\x4c\xf8\xd1\x00\x4f\x06\x25\x00\x52\x4c\x9a\x00'
                 b'\x54\x2c\xc5\x00\x56\x6b\x81\x00\x58\xb9\xa9\x00\x5c\x23\xdb'
                 b'\x00\x5d\xeb\x67\x00\x5f\x7d\x79\x00\x61\x14\x59\x00\x64\x13'
                 b'\xb2\x00\x66\x20\xb7\x00\x68\x05\x1e\x00\x69\xc7\x05\x00\x6d'
                 b'\x98\x41\x00\x70\x9a\xaa\x00\x72\x8c\xcd\x00\x74\xa7\x2e\x00'
                 b'\x78\x88\xb8\x00\x7b\x56\x2d\x00\x7d\x6a\xc0\x00\x7f\xd0\x96'
                 b'\x00\x83\x41\xdc\x00\x84\xd6\xf4')
         f.seek(0)
         reader = StreamReader(f)
         size = reader.read32()
         _ = reader.read32()
         stco = parse_stco(reader, size)
         self.assertNotEqual(stco, None)
         self.assertEqual(stco.entry_count, 58)
示例#2
0
 def test_stts(self):
     with TemporaryFile() as f:
        f.write(b'\x00\x00\x00\x18\x73\x74\x74\x73\x00'
                b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x02\xb0\x00\x00\x03\xe8')
        f.seek(0)
        reader = StreamReader(f)
        size = reader.read32()
        _ = reader.read32()
        stts = parse_stts(reader, size)
        self.assertNotEqual(stts, None)
        self.assertEqual(stts.entry_count, 1)
示例#3
0
 def test_stss(self):
     with TemporaryFile() as f:
         f.write(b'\x00\x00\x00\x4c\x73\x74\x73\x73\x00\x00\x00\x00\x00'
                 b'\x00\x00\x0f\x00\x00\x00\x01\x00\x00\x00\x31\x00\x00'
                 b'\x00\x61\x00\x00\x00\x91\x00\x00\x00\xc1\x00\x00\x00'
                 b'\xf1\x00\x00\x01\x21\x00\x00\x01\x51\x00\x00\x01\x81'
                 b'\x00\x00\x01\xb1\x00\x00\x01\xe1\x00\x00\x02\x11\x00\x00\x02\x41'
                 b'\x00\x00\x02\x71\x00\x00\x02\xa1')
         f.seek(0)
         reader = StreamReader(f)
         size = reader.read32()
         _ = reader.read32()
         stss = parse_stss(reader, size)
         self.assertNotEqual(stss, None)
示例#4
0
 def test_ftyp(self):
      with  TemporaryFile() as f:
             f.write(b"\x00\x00\x00\x18\x66\x74\x79\x70\x69\x73\x6f\x36\x00\x00\x00\x01\x69\x73\x6f\x36\x64\x61\x73\x68")
             f.seek(0)
             reader = StreamReader(f)
             size = reader.read32()
             _ = reader.read32()
             ftyp = parse_ftyp(reader, size)
             self.assertNotEqual(ftyp, None)
             self.assertEqual(ftyp.size, 24)
             self.assertEqual(ftyp.major_brand, 'iso6')
             self.assertEqual(len(ftyp.compatible_brands), 2)
             self.assertEqual(ftyp.compatible_brands[0], 'iso6')
             self.assertEqual(ftyp.compatible_brands[1], 'dash')
示例#5
0
    def test_stsc(self):
        with TemporaryFile() as f:

            f.write(b'\x00\x00\x00\x34\x73\x74\x73\x63\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00'
                    b'\x00\x01\x00\x00\x00\x0d\x00\x00\x00\x01\x00\x00\x00'
                    b'\x02\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x3a'
                    b'\x00\x00\x00\x03\x00\x00\x00\x01')
            f.seek(0)
            reader = StreamReader(f)
            size = reader.read32()
            _ = reader.read32()
            stsc = parse_stsc(reader, size)
            self.assertNotEqual(stsc, None)
            self.assertEqual(stsc.entry_count, 3)
            self.assertEqual(stsc.first_chunk[0], 1)
            self.assertEqual(stsc.samples_per_chunk[0], 13)
            self.assertEqual(stsc.sample_description_index[0], 1)
示例#6
0
class BoxParser:
    def __init__(self, file):
        self.reader = StreamReader(file)
        self.root = None
        self.frame_gen = None

    def parse(self):
        if not self.root:
            self.root = RootBox()
            size = self.reader.read32()
            type = self.reader.read32_as_str()
            while not self.reader.reached_eof():
                if type == "ftyp":
                    self.root.ftyp = parse_typ(self.reader, size, FileTypeBox)
                elif type == "styp":
                    self.root.styp = parse_typ(self.reader, size, SegmentTypeBox)
                elif type == "moov":
                    self.root.moov = parse_moov(self.reader, size)
                elif type == "free":
                    self.root.free = parse_free(self.reader, size)
                elif type == "mdat":
                    self.root.mdats.append(parse_mdat(self.reader, size))
                elif type == "PLEP":
                    self.root.plep = parse_plep(self.reader, size)
                else:
                    raise InvalidBoxError("type %s unknown" % type, None)
                if self.reader.reached_eof():
                    break
                # At the end of current box parsing, the file pointer will be
                # ready to read the size and type of the next box
                size = self.reader.read32()
                type = self.reader.read32_as_str()

            # Either box parsing was successful or it has errors

    def get_tree(self):
        return self.root

    def get_all_info(self):
        # TODO abhi: not sure if the metadata should be structured as a dict
        # or something else. For now, just return a dict.
        out = {}
        if self.root is None:
            self.parse()

        out["duration"] = self.root.get_duration()
        out["timescale"] = self.root.get_timescale()
        out["brands"] = self.root.get_compatible_brands()
        out["created"] = self.root.get_creation_time()
        out["modified"] = self.root.get_modification_time()
        out["tracks"] = self.root.get_all_tracks()
        out["is_fragmented"] = self.root.has_fragments()
        # out["is_progressive"] = not sure what this means
        out["has_iod"] = self.root.has_iods()

        return out

    def get_frames(self, media_type):
        # media_type can be either audio, video or both
        if not self.root:
            self.parse()

        # TODO abhi: Implement a FrameGenerator
        # self.frame_gen = FrameGenerator(media_type, self.root.get_all_tracks(), self.root.mdats)
        # return self.frame_gen

        return None

    def get_nalu_gen(self, trak):
        # TODO abhi: we can't just be using any mdat box
        # However, for now, assume we are dealing with non fMP4 files
        return NALUGenerator(self.reader, trak, self.root.mdats[0])