[f4m] Tolerate missed fragments on live streams

This commit is contained in:
Antti Ajanki 2015-02-23 21:56:35 +02:00
parent c4f8c453ae
commit 5eaaeb7c31
1 changed files with 30 additions and 13 deletions

View File

@ -11,6 +11,7 @@ from .common import FileDownloader
from .http import HttpFD from .http import HttpFD
from ..compat import ( from ..compat import (
compat_urlparse, compat_urlparse,
compat_urllib_error,
) )
from ..utils import ( from ..utils import (
struct_pack, struct_pack,
@ -389,22 +390,38 @@ class F4mFD(FileDownloader):
if akamai_pv: if akamai_pv:
url += '?' + akamai_pv.strip(';') url += '?' + akamai_pv.strip(';')
frag_filename = '%s-%s' % (tmpfilename, name) frag_filename = '%s-%s' % (tmpfilename, name)
success = http_dl.download(frag_filename, {'url': url}) try:
if not success: success = http_dl.download(frag_filename, {'url': url})
return False if not success:
with open(frag_filename, 'rb') as down: return False
down_data = down.read() with open(frag_filename, 'rb') as down:
reader = FlvReader(down_data) down_data = down.read()
while True: reader = FlvReader(down_data)
_, box_type, box_data = reader.read_box_info() while True:
if box_type == b'mdat': _, box_type, box_data = reader.read_box_info()
dest_stream.write(box_data) if box_type == b'mdat':
break dest_stream.write(box_data)
frags_filenames.append(frag_filename) break
if live:
os.remove(frag_filename)
else:
frags_filenames.append(frag_filename)
except (compat_urllib_error.HTTPError, ) as err:
if live and (err.code == 404 or err.code == 410):
# We didn't keep up with the live window. Continue
# with the next available fragment.
msg = 'Fragment %d unavailable' % frag_i
self.report_warning(msg)
fragments_list = []
else:
raise
if not fragments_list and live and bootstrap_url: if not fragments_list and live and bootstrap_url:
fragments_list = self._update_live_fragments(bootstrap_url, frag_i) fragments_list = self._update_live_fragments(bootstrap_url, frag_i)
self.to_screen('Updated available fragments: %d' % len(fragments_list)) total_frags += len(fragments_list)
if fragments_list and (fragments_list[0][1] > frag_i + 1):
msg = 'Missed %d fragments' % (fragments_list[0][1] - (frag_i + 1))
self.report_warning(msg)
dest_stream.close() dest_stream.close()