[downloader/f4m] Transform timestamps to start from zero-based
This commit is contained in:
parent
05aa9c82d9
commit
889568d128
@ -21,6 +21,31 @@ from ..utils import (
|
|||||||
xpath_text,
|
xpath_text,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class FlvPacket(object):
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.packet_type = stream.read_unsigned_char()
|
||||||
|
payload_len = stream.read_unsigned_int_24()
|
||||||
|
timestamp_low = stream.read_unsigned_int_24()
|
||||||
|
timestamp_high = stream.read_unsigned_char()
|
||||||
|
self.timestamp = (timestamp_high << 24) + timestamp_low
|
||||||
|
if self.timestamp & 0x80000000 != 0:
|
||||||
|
self.timestamp &= 0x7FFFFFFF
|
||||||
|
|
||||||
|
self.stream_id = stream.read_unsigned_int_24()
|
||||||
|
self.payload = stream.read(payload_len)
|
||||||
|
self.total_packet_len = stream.read_unsigned_int()
|
||||||
|
|
||||||
|
def write(self, stream):
|
||||||
|
write_unsigned_char(stream, self.packet_type)
|
||||||
|
write_unsigned_int_24(stream, len(self.payload))
|
||||||
|
timestamp_low = self.timestamp & 0x00FFFFFF;
|
||||||
|
timestamp_high = (self.timestamp & 0xFF000000) >> 24;
|
||||||
|
write_unsigned_int_24(stream, timestamp_low)
|
||||||
|
write_unsigned_char(stream, timestamp_high)
|
||||||
|
write_unsigned_int_24(stream, self.stream_id)
|
||||||
|
stream.write(self.payload)
|
||||||
|
write_unsigned_int(stream, self.total_packet_len)
|
||||||
|
|
||||||
|
|
||||||
class FlvReader(io.BytesIO):
|
class FlvReader(io.BytesIO):
|
||||||
"""
|
"""
|
||||||
@ -35,6 +60,10 @@ class FlvReader(io.BytesIO):
|
|||||||
def read_unsigned_int(self):
|
def read_unsigned_int(self):
|
||||||
return struct_unpack('!I', self.read(4))[0]
|
return struct_unpack('!I', self.read(4))[0]
|
||||||
|
|
||||||
|
def read_unsigned_int_24(self):
|
||||||
|
v = b'\x00' + bytearray(self.read(3))
|
||||||
|
return struct_unpack('!I', v)[0]
|
||||||
|
|
||||||
def read_unsigned_char(self):
|
def read_unsigned_char(self):
|
||||||
return struct_unpack('!B', self.read(1))[0]
|
return struct_unpack('!B', self.read(1))[0]
|
||||||
|
|
||||||
@ -170,6 +199,11 @@ class FlvReader(io.BytesIO):
|
|||||||
assert box_type == b'abst'
|
assert box_type == b'abst'
|
||||||
return FlvReader(box_data).read_abst()
|
return FlvReader(box_data).read_abst()
|
||||||
|
|
||||||
|
def read_packets(self, endoffset):
|
||||||
|
packets = []
|
||||||
|
while self.tell() < endoffset:
|
||||||
|
packets.append(FlvPacket(self))
|
||||||
|
return packets
|
||||||
|
|
||||||
def read_bootstrap_info(bootstrap_bytes):
|
def read_bootstrap_info(bootstrap_bytes):
|
||||||
return FlvReader(bootstrap_bytes).read_bootstrap_info()
|
return FlvReader(bootstrap_bytes).read_bootstrap_info()
|
||||||
@ -192,6 +226,9 @@ def build_fragments_list(boot_info):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def write_unsigned_char(stream, val):
|
||||||
|
stream.write(struct_pack('!B', val))
|
||||||
|
|
||||||
def write_unsigned_int(stream, val):
|
def write_unsigned_int(stream, val):
|
||||||
stream.write(struct_pack('!I', val))
|
stream.write(struct_pack('!I', val))
|
||||||
|
|
||||||
@ -285,6 +322,18 @@ class F4mFD(FileDownloader):
|
|||||||
boot_info = read_bootstrap_info(bootstrap)
|
boot_info = read_bootstrap_info(bootstrap)
|
||||||
return (boot_info, bootstrap_url)
|
return (boot_info, bootstrap_url)
|
||||||
|
|
||||||
|
def adjust_timestamps(self, packets, timebase):
|
||||||
|
for p in packets:
|
||||||
|
if timebase is None:
|
||||||
|
timebase = p.timestamp
|
||||||
|
if p.timestamp >= timebase and timebase > 1000:
|
||||||
|
p.timestamp = p.timestamp - timebase
|
||||||
|
return (packets, timebase)
|
||||||
|
|
||||||
|
def write_packets(self, dest_stream, packets):
|
||||||
|
for p in packets:
|
||||||
|
p.write(dest_stream)
|
||||||
|
|
||||||
def real_download(self, filename, info_dict):
|
def real_download(self, filename, info_dict):
|
||||||
man_url = info_dict['url']
|
man_url = info_dict['url']
|
||||||
requested_bitrate = info_dict.get('tbr')
|
requested_bitrate = info_dict.get('tbr')
|
||||||
@ -382,6 +431,7 @@ class F4mFD(FileDownloader):
|
|||||||
|
|
||||||
http_dl.add_progress_hook(frag_progress_hook)
|
http_dl.add_progress_hook(frag_progress_hook)
|
||||||
|
|
||||||
|
timebase = None
|
||||||
frags_filenames = []
|
frags_filenames = []
|
||||||
while fragments_list:
|
while fragments_list:
|
||||||
seg_i, frag_i = fragments_list.pop(0)
|
seg_i, frag_i = fragments_list.pop(0)
|
||||||
@ -402,7 +452,9 @@ class F4mFD(FileDownloader):
|
|||||||
while True:
|
while True:
|
||||||
_, box_type, box_data = reader.read_box_info()
|
_, box_type, box_data = reader.read_box_info()
|
||||||
if box_type == b'mdat':
|
if box_type == b'mdat':
|
||||||
dest_stream.write(box_data)
|
packets = FlvReader(box_data).read_packets(len(box_data))
|
||||||
|
packets, timebase = self.adjust_timestamps(packets, timebase)
|
||||||
|
self.write_packets(dest_stream, packets)
|
||||||
break
|
break
|
||||||
if live:
|
if live:
|
||||||
os.remove(frag_filename)
|
os.remove(frag_filename)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user