diff options
Diffstat (limited to 'youtube_dl/downloader/hls.py')
| -rw-r--r-- | youtube_dl/downloader/hls.py | 59 | 
1 files changed, 59 insertions, 0 deletions
diff --git a/youtube_dl/downloader/hls.py b/youtube_dl/downloader/hls.py index 32852f333..56cce2811 100644 --- a/youtube_dl/downloader/hls.py +++ b/youtube_dl/downloader/hls.py @@ -1,8 +1,13 @@ +from __future__ import unicode_literals +  import os +import re  import subprocess  from .common import FileDownloader  from ..utils import ( +    compat_urlparse, +    compat_urllib_request,      check_executable,      encodeFilename,  ) @@ -43,3 +48,57 @@ class HlsFD(FileDownloader):              self.to_stderr(u"\n")              self.report_error(u'%s exited with code %d' % (program, retval))              return False + + +class NativeHlsFD(FileDownloader): +    """ A more limited implementation that does not require ffmpeg """ + +    def real_download(self, filename, info_dict): +        url = info_dict['url'] +        self.report_destination(filename) +        tmpfilename = self.temp_name(filename) + +        self.to_screen( +            '[hlsnative] %s: Downloading m3u8 manifest' % info_dict['id']) +        data = self.ydl.urlopen(url).read() +        s = data.decode('utf-8', 'ignore') +        segment_urls = [] +        for line in s.splitlines(): +            line = line.strip() +            if line and not line.startswith('#'): +                segment_url = ( +                    line +                    if re.match(r'^https?://', line) +                    else compat_urlparse.urljoin(url, line)) +                segment_urls.append(segment_url) + +        is_test = self.params.get('test', False) +        remaining_bytes = self._TEST_FILE_SIZE if is_test else None +        byte_counter = 0 +        with open(tmpfilename, 'wb') as outf: +            for i, segurl in enumerate(segment_urls): +                self.to_screen( +                    '[hlsnative] %s: Downloading segment %d / %d' % +                    (info_dict['id'], i + 1, len(segment_urls))) +                seg_req = compat_urllib_request.Request(segurl) +                if remaining_bytes: +                    seg_req.add_header('Range', 'bytes=0-%d' % (remaining_bytes - 1)) + +                segment = self.ydl.urlopen(seg_req).read() +                if remaining_bytes: +                    segment = segment[:remaining_bytes] +                    remaining_bytes -= len(segment) +                outf.write(segment) +                byte_counter += len(segment) +                if remaining_bytes <= 0: +                    break + +        self._hook_progress({ +            'downloaded_bytes': byte_counter, +            'total_bytes': byte_counter, +            'filename': filename, +            'status': 'finished', +        }) +        self.try_rename(tmpfilename, filename) +        return True +  | 
