def process_tfdt(self, data): """Generate new timestamps for tfdt and change size of boxes above if needed. Try to keep in 32 bits if possible.""" version = data[8] if self.track_timescale is not None: tfdt_offset = self.offset * self.track_timescale else: tfdt_offset = 0 if version == 0: # 32-bit baseMediaDecodeTime base_media_decode_time = str_to_uint32(data[12:16]) new_base_media_decode_time = base_media_decode_time + tfdt_offset if new_base_media_decode_time < 4294967296: output = data[:12] output += uint32_to_str(new_base_media_decode_time) else: # print "Forced to change to 64-bit tfdt." self.size_change = 4 output = uint32_to_str( str_to_uint32(data[:4]) + self.size_change) output += data[4:8] output += b'\x01' output += data[9:12] output += uint64_to_str(new_base_media_decode_time) else: # 64-bit # print "Staying at 64-bit tfdt." output = data[:12] base_media_decode_time = str_to_uint64(data[12:20]) new_base_media_decode_time = base_media_decode_time + tfdt_offset output += uint64_to_str(new_base_media_decode_time) self.tfdt_value = new_base_media_decode_time return output
def process_sidx(self, data): "Process sidx data and add to output." if not KEEP_SIDX: return b"" output = b"" version = data[8] timescale = str_to_uint32(data[16:20]) if version == 0: # print("Changing sidx version to 1") size = str_to_uint32(data[0:4]) sidx_size_expansion = 8 output += uint32_to_str(size + sidx_size_expansion) output += data[4:8] output += b'\x01' output += data[9:20] earliest_presentation_time = str_to_uint32(data[20:24]) first_offset = str_to_uint32(data[24:28]) else: output += data[0:20] earliest_presentation_time = str_to_uint64(data[20:28]) first_offset = str_to_uint64(data[28:36]) new_presentation_time = earliest_presentation_time + timescale * self.offset output += uint64_to_str(new_presentation_time) output += uint64_to_str(first_offset) if version == 0: output += data[28:] else: output += data[36:] return output
def process_tkhd(self, data): "Set trackID and time." version = data[8] output = data[:12] if version == 1: if self.creation_modfication_time: output += uint64_to_str(self.creation_modfication_time) output += uint64_to_str(self.creation_modfication_time) else: output += data[12:28] output += uint32_to_str(self.track_id) output += uint32_to_str(0) output += uint64_to_str(0) # duration pos = 44 else: if self.creation_modfication_time: output += uint32_to_str(self.creation_modfication_time) output += uint32_to_str(self.creation_modfication_time) else: output += data[12:20] output += uint32_to_str(self.track_id) output += uint32_to_str(0) output += uint32_to_str(0) # duration pos = 32 output += data[pos:] return output
def create_sidx(self, seg_size): """Return a sidx box which can be inserted right before the moof. This is optional, but some clients require it to present.""" output = uint32_to_str(52) # Size of box output += b'sidx\x01\x00\x00\x00' # type, version and flags output += b'\x00\x00\x00\x01' # refID output += uint32_to_str(self.track_timescale) output += uint64_to_str(self.tfdt_value) # decode_time for now output += uint64_to_str(0) # first_offset = 0 output += b'\x00\x00\x00\x01' # reserved and reference_count # Next 1 bit reference type + 31 bit size of segment output += uint32_to_str(seg_size) output += uint32_to_str(self.duration) output += b'\x90\x00\x00\x00' return output
def process_saio(self, data): "Process saio and possibly change offset by size_change if needed." version_flags = str_to_uint32(data[8:12]) version = version_flags >> 24 flags = version_flags & 0xffffff pos = 12 if flags & 0x1: pos += 8 entry_count = str_to_uint32(data[pos:pos + 4]) pos += 4 output = data[:pos] delta_offset = self.size_change if version == 0: for i in range(entry_count): offset = str_to_uint32(data[pos:pos + 4]) pos += 4 output += uint32_to_str(offset + delta_offset) if i == 0: self.new_saio_value = offset + delta_offset else: for i in range(entry_count): offset = str_to_uint64(data[pos:pos + 8]) pos += 8 output += uint64_to_str(offset + delta_offset) if i == 0: self.new_saio_value = offset + delta_offset return output
def process_tfdt(self, data): "Process a tfdt box and set the baseMediaDecodeTime." version = ord(data[8]) assert version == 1, "Can only handle tfdt version 1 (64-bit tfdt)." output = data[:12] output += uint64_to_str(self.tfdt_time) return output
def _insert_timing_data(self, data): "Help function to insert timestamps and timescale in similar boxes." version = data[8] output = data[:12] if version == 1: if self.creation_modfication_time: output += uint64_to_str(self.creation_modfication_time) output += uint64_to_str(self.creation_modfication_time) else: output += data[12:28] output += uint32_to_str(self.timescale) output += uint64_to_str(0) # duration else: if self.creation_modfication_time: output += uint32_to_str(self.creation_modfication_time) output += uint32_to_str(self.creation_modfication_time) else: output += data[12:20] output += uint32_to_str(self.timescale) output += uint32_to_str(0) return output
def process_tfdt_to_64bit(self, data, output): """Generate new timestamps for tfdt and change size of boxes above if needed. Note that the input output will be returned and can have another size.""" version = data[8] tfdt_offset = self.offset * self.track_timescale if version == 0: # 32-bit baseMediaDecodeTime self.size_change = 4 output = uint32_to_str(str_to_uint32(data[:4]) + self.size_change) output += data[4:8] output += b'\x01' output += data[9:12] base_media_decode_time = str_to_uint32(data[12:16]) else: # 64-bit output = data[:12] base_media_decode_time = str_to_uint64(data[12:20]) new_base_media_decode_time = base_media_decode_time + tfdt_offset output += uint64_to_str(new_base_media_decode_time) self.tfdt_value = new_base_media_decode_time return output