[downloader/fragment] Use temp file for current fragment
This commit is contained in:
parent
a4d6cf970c
commit
d3f0687cf7
@ -2,7 +2,6 @@ from __future__ import division, unicode_literals
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import io
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from .common import FileDownloader
|
from .common import FileDownloader
|
||||||
@ -48,28 +47,42 @@ class FragmentFD(FileDownloader):
|
|||||||
self._prepare_frag_download(ctx)
|
self._prepare_frag_download(ctx)
|
||||||
self._start_frag_download(ctx)
|
self._start_frag_download(ctx)
|
||||||
|
|
||||||
|
def _read_ytdl_file(self, ctx):
|
||||||
|
stream, _ = sanitize_open(self.ytdl_filename(ctx['filename']), 'r')
|
||||||
|
ctx['fragment_index'] = json.loads(stream.read())['download']['current_fragment_index']
|
||||||
|
stream.close()
|
||||||
|
|
||||||
|
def _write_ytdl_file(self, ctx):
|
||||||
|
frag_index_stream, _ = sanitize_open(self.ytdl_filename(ctx['filename']), 'w')
|
||||||
|
frag_index_stream.write(json.dumps({
|
||||||
|
'download': {
|
||||||
|
'current_fragment_index': ctx['fragment_index']
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
frag_index_stream.close()
|
||||||
|
|
||||||
def _download_fragment(self, ctx, frag_url, info_dict, headers=None):
|
def _download_fragment(self, ctx, frag_url, info_dict, headers=None):
|
||||||
down = io.BytesIO()
|
fragment_filename = '%s-Frag%d' % (ctx['tmpfilename'], ctx['fragment_index'])
|
||||||
success = ctx['dl'].download(down, {
|
success = ctx['dl'].download(fragment_filename, {
|
||||||
'url': frag_url,
|
'url': frag_url,
|
||||||
'http_headers': headers or info_dict.get('http_headers'),
|
'http_headers': headers or info_dict.get('http_headers'),
|
||||||
})
|
})
|
||||||
if not success:
|
if not success:
|
||||||
return False, None
|
return False, None
|
||||||
frag_content = down.getvalue()
|
down, frag_sanitized = sanitize_open(fragment_filename, 'rb')
|
||||||
|
ctx['fragment_filename_sanitized'] = frag_sanitized
|
||||||
|
frag_content = down.read()
|
||||||
down.close()
|
down.close()
|
||||||
return True, frag_content
|
return True, frag_content
|
||||||
|
|
||||||
def _append_fragment(self, ctx, frag_content):
|
def _append_fragment(self, ctx, frag_content):
|
||||||
ctx['dest_stream'].write(frag_content)
|
try:
|
||||||
if not (ctx.get('live') or ctx['tmpfilename'] == '-'):
|
ctx['dest_stream'].write(frag_content)
|
||||||
frag_index_stream, _ = sanitize_open(self.ytdl_filename(ctx['filename']), 'w')
|
finally:
|
||||||
frag_index_stream.write(json.dumps({
|
if not (ctx.get('live') or ctx['tmpfilename'] == '-'):
|
||||||
'download': {
|
self._write_ytdl_file(ctx)
|
||||||
'last_fragment_index': ctx['fragment_index']
|
os.remove(ctx['fragment_filename_sanitized'])
|
||||||
},
|
del ctx['fragment_filename_sanitized']
|
||||||
}))
|
|
||||||
frag_index_stream.close()
|
|
||||||
|
|
||||||
def _prepare_frag_download(self, ctx):
|
def _prepare_frag_download(self, ctx):
|
||||||
if 'live' not in ctx:
|
if 'live' not in ctx:
|
||||||
@ -93,23 +106,29 @@ class FragmentFD(FileDownloader):
|
|||||||
tmpfilename = self.temp_name(ctx['filename'])
|
tmpfilename = self.temp_name(ctx['filename'])
|
||||||
open_mode = 'wb'
|
open_mode = 'wb'
|
||||||
resume_len = 0
|
resume_len = 0
|
||||||
frag_index = 0
|
|
||||||
# Establish possible resume length
|
# Establish possible resume length
|
||||||
if os.path.isfile(encodeFilename(tmpfilename)):
|
if os.path.isfile(encodeFilename(tmpfilename)):
|
||||||
open_mode = 'ab'
|
open_mode = 'ab'
|
||||||
resume_len = os.path.getsize(encodeFilename(tmpfilename))
|
resume_len = os.path.getsize(encodeFilename(tmpfilename))
|
||||||
ytdl_filename = encodeFilename(self.ytdl_filename(ctx['filename']))
|
|
||||||
if os.path.isfile(ytdl_filename):
|
ctx['fragment_index'] = 0
|
||||||
frag_index_stream, _ = sanitize_open(ytdl_filename, 'r')
|
if os.path.isfile(encodeFilename(self.ytdl_filename(ctx['filename']))):
|
||||||
frag_index = json.loads(frag_index_stream.read())['download']['last_fragment_index']
|
self._read_ytdl_file(ctx)
|
||||||
frag_index_stream.close()
|
else:
|
||||||
|
self._write_ytdl_file(ctx)
|
||||||
|
|
||||||
|
if ctx['fragment_index'] > 0:
|
||||||
|
assert resume_len > 0
|
||||||
|
else:
|
||||||
|
assert resume_len == 0
|
||||||
|
|
||||||
dest_stream, tmpfilename = sanitize_open(tmpfilename, open_mode)
|
dest_stream, tmpfilename = sanitize_open(tmpfilename, open_mode)
|
||||||
|
|
||||||
ctx.update({
|
ctx.update({
|
||||||
'dl': dl,
|
'dl': dl,
|
||||||
'dest_stream': dest_stream,
|
'dest_stream': dest_stream,
|
||||||
'tmpfilename': tmpfilename,
|
'tmpfilename': tmpfilename,
|
||||||
'fragment_index': frag_index,
|
|
||||||
# Total complete fragments downloaded so far in bytes
|
# Total complete fragments downloaded so far in bytes
|
||||||
'complete_frags_downloaded_bytes': resume_len,
|
'complete_frags_downloaded_bytes': resume_len,
|
||||||
})
|
})
|
||||||
|
@ -20,14 +20,10 @@ from ..utils import (
|
|||||||
|
|
||||||
|
|
||||||
class HttpFD(FileDownloader):
|
class HttpFD(FileDownloader):
|
||||||
def real_download(self, filename_or_stream, info_dict):
|
def real_download(self, filename, info_dict):
|
||||||
url = info_dict['url']
|
url = info_dict['url']
|
||||||
filename = filename_or_stream
|
|
||||||
stream = None
|
|
||||||
if hasattr(filename_or_stream, 'write'):
|
|
||||||
stream = filename_or_stream
|
|
||||||
filename = '-'
|
|
||||||
tmpfilename = self.temp_name(filename)
|
tmpfilename = self.temp_name(filename)
|
||||||
|
stream = None
|
||||||
|
|
||||||
# Do not include the Accept-Encoding header
|
# Do not include the Accept-Encoding header
|
||||||
headers = {'Youtubedl-no-compression': 'True'}
|
headers = {'Youtubedl-no-compression': 'True'}
|
||||||
|
Loading…
Reference in New Issue
Block a user