]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/downloader/fragment.py
   1 from __future__ 
import division
, unicode_literals
 
   6 from .common 
import FileDownloader
 
   7 from .http 
import HttpFD
 
  14 class HttpQuietDownloader(HttpFD
): 
  15     def to_screen(self
, *args
, **kargs
): 
  19 class FragmentFD(FileDownloader
): 
  21     A base file downloader class for fragmented media (e.g. f4m/m3u8 manifests). 
  25     fragment_retries:   Number of times to retry a fragment for HTTP error (DASH only) 
  28     def report_retry_fragment(self
, fragment_name
, count
, retries
): 
  30             '[download] Got server HTTP error. Retrying fragment %s (attempt %d of %s)...' 
  31             % (fragment_name
, count
, self
.format_retries(retries
))) 
  33     def _prepare_and_start_frag_download(self
, ctx
): 
  34         self
._prepare
_frag
_download
(ctx
) 
  35         self
._start
_frag
_download
(ctx
) 
  37     def _prepare_frag_download(self
, ctx
): 
  41             '[%s] Total fragments: %s' 
  42             % (self
.FD_NAME
, ctx
['total_frags'] if not ctx
['live'] else 'unknown (live)')) 
  43         self
.report_destination(ctx
['filename']) 
  44         dl 
= HttpQuietDownloader( 
  50                 'ratelimit': self
.params
.get('ratelimit'), 
  51                 'retries': self
.params
.get('retries', 0), 
  52                 'test': self
.params
.get('test', False), 
  55         tmpfilename 
= self
.temp_name(ctx
['filename']) 
  56         dest_stream
, tmpfilename 
= sanitize_open(tmpfilename
, 'wb') 
  59             'dest_stream': dest_stream
, 
  60             'tmpfilename': tmpfilename
, 
  63     def _start_frag_download(self
, ctx
): 
  64         total_frags 
= ctx
['total_frags'] 
  65         # This dict stores the download progress, it's updated by the progress 
  68             'status': 'downloading', 
  69             'downloaded_bytes': 0, 
  71             'frag_count': total_frags
, 
  72             'filename': ctx
['filename'], 
  73             'tmpfilename': ctx
['tmpfilename'], 
  79             # Total complete fragments downloaded so far in bytes 
  80             'complete_frags_downloaded_bytes': 0, 
  81             # Amount of fragment's bytes downloaded by the time of the previous 
  82             # frag progress hook invocation 
  83             'prev_frag_downloaded_bytes': 0, 
  86         def frag_progress_hook(s
): 
  87             if s
['status'] not in ('downloading', 'finished'): 
  90             time_now 
= time
.time() 
  91             state
['elapsed'] = time_now 
- start
 
  92             frag_total_bytes 
= s
.get('total_bytes') or 0 
  95                     (ctx
['complete_frags_downloaded_bytes'] + frag_total_bytes
) / 
  96                     (state
['frag_index'] + 1) * total_frags
) 
  97                 state
['total_bytes_estimate'] = estimated_size
 
  99             if s
['status'] == 'finished': 
 100                 state
['frag_index'] += 1 
 101                 state
['downloaded_bytes'] += frag_total_bytes 
- ctx
['prev_frag_downloaded_bytes'] 
 102                 ctx
['complete_frags_downloaded_bytes'] = state
['downloaded_bytes'] 
 103                 ctx
['prev_frag_downloaded_bytes'] = 0 
 105                 frag_downloaded_bytes 
= s
['downloaded_bytes'] 
 106                 state
['downloaded_bytes'] += frag_downloaded_bytes 
- ctx
['prev_frag_downloaded_bytes'] 
 108                     state
['eta'] = self
.calc_eta( 
 109                         start
, time_now
, estimated_size
, 
 110                         state
['downloaded_bytes']) 
 111                 state
['speed'] = s
.get('speed') or ctx
.get('speed') 
 112                 ctx
['speed'] = state
['speed'] 
 113                 ctx
['prev_frag_downloaded_bytes'] = frag_downloaded_bytes
 
 114             self
._hook
_progress
(state
) 
 116         ctx
['dl'].add_progress_hook(frag_progress_hook
) 
 120     def _finish_frag_download(self
, ctx
): 
 121         ctx
['dest_stream'].close() 
 122         elapsed 
= time
.time() - ctx
['started'] 
 123         self
.try_rename(ctx
['tmpfilename'], ctx
['filename']) 
 124         fsize 
= os
.path
.getsize(encodeFilename(ctx
['filename'])) 
 126         self
._hook
_progress
({ 
 127             'downloaded_bytes': fsize
, 
 128             'total_bytes': fsize
, 
 129             'filename': ctx
['filename'], 
 130             'status': 'finished',