]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/downloader/hls.py
9a83a73dd6b16db50cc4e72a343b1669c146a386
   1 from __future__ 
import unicode_literals
 
   7 from .common 
import FileDownloader
 
   8 from .fragment 
import FragmentFD
 
  10 from ..compat 
import compat_urlparse
 
  11 from ..postprocessor
.ffmpeg 
import FFmpegPostProcessor
 
  19 class HlsFD(FileDownloader
): 
  20     def real_download(self
, filename
, info_dict
): 
  21         url 
= info_dict
['url'] 
  22         self
.report_destination(filename
) 
  23         tmpfilename 
= self
.temp_name(filename
) 
  25         ffpp 
= FFmpegPostProcessor(downloader
=self
) 
  26         if not ffpp
.available
: 
  27             self
.report_error('m3u8 download detected but ffmpeg or avconv could not be found. Please install one.') 
  31         args 
= [ffpp
.executable
, '-y'] 
  33         if info_dict
['http_headers'] and re
.match(r
'^https?://', url
): 
  34             # Trailing \r\n after each HTTP header is important to prevent warning from ffmpeg/avconv: 
  35             # [http @ 00000000003d2fa0] No trailing CRLF found in HTTP header. 
  38                 ''.join('%s: %s\r\n' % (key
, val
) for key
, val 
in info_dict
['http_headers'].items())] 
  40         args 
+= ['-i', url
, '-f', 'mp4', '-c', 'copy', '-bsf:a', 'aac_adtstoasc'] 
  42         args 
= [encodeArgument(opt
) for opt 
in args
] 
  43         args
.append(encodeFilename(ffpp
._ffmpeg
_filename
_argument
(tmpfilename
), True)) 
  47         retval 
= subprocess
.call(args
) 
  49             fsize 
= os
.path
.getsize(encodeFilename(tmpfilename
)) 
  50             self
.to_screen('\r[%s] %s bytes' % (args
[0], fsize
)) 
  51             self
.try_rename(tmpfilename
, filename
) 
  53                 'downloaded_bytes': fsize
, 
  61             self
.report_error('%s exited with code %d' % (ffpp
.basename
, retval
)) 
  65 class NativeHlsFD(FragmentFD
): 
  66     """ A more limited implementation that does not require ffmpeg """ 
  70     def real_download(self
, filename
, info_dict
): 
  71         man_url 
= info_dict
['url'] 
  72         self
.to_screen('[%s] Downloading m3u8 manifest' % self
.FD_NAME
) 
  73         manifest 
= self
.ydl
.urlopen(man_url
).read() 
  75         s 
= manifest
.decode('utf-8', 'ignore') 
  77         for line 
in s
.splitlines(): 
  79             if line 
and not line
.startswith('#'): 
  82                     if re
.match(r
'^https?://', line
) 
  83                     else compat_urlparse
.urljoin(man_url
, line
)) 
  84                 fragment_urls
.append(segment_url
) 
  85                 # We only download the first fragment during the test 
  86                 if self
.params
.get('test', False): 
  91             'total_frags': len(fragment_urls
), 
  94         self
._prepare
_and
_start
_frag
_download
(ctx
) 
  97         for i
, frag_url 
in enumerate(fragment_urls
): 
  98             frag_filename 
= '%s-Frag%d' % (ctx
['tmpfilename'], i
) 
  99             success 
= ctx
['dl'].download(frag_filename
, {'url': frag_url
}) 
 102             down
, frag_sanitized 
= sanitize_open(frag_filename
, 'rb') 
 103             ctx
['dest_stream'].write(down
.read()) 
 105             frags_filenames
.append(frag_sanitized
) 
 107         self
._finish
_frag
_download
(ctx
) 
 109         for frag_file 
in frags_filenames
: 
 110             os
.remove(encodeFilename(frag_file
))