You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.8 KiB

  1. from __future__ import unicode_literals
  2. import os.path
  3. import re
  4. from .fragment import FragmentFD
  5. from ..compat import compat_urlparse
  6. from ..utils import (
  7. encodeFilename,
  8. sanitize_open,
  9. )
  10. class HlsFD(FragmentFD):
  11. """ A limited implementation that does not require ffmpeg """
  12. FD_NAME = 'hlsnative'
  13. def real_download(self, filename, info_dict):
  14. man_url = info_dict['url']
  15. self.to_screen('[%s] Downloading m3u8 manifest' % self.FD_NAME)
  16. manifest = self.ydl.urlopen(man_url).read()
  17. s = manifest.decode('utf-8', 'ignore')
  18. fragment_urls = []
  19. for line in s.splitlines():
  20. line = line.strip()
  21. if line and not line.startswith('#'):
  22. segment_url = (
  23. line
  24. if re.match(r'^https?://', line)
  25. else compat_urlparse.urljoin(man_url, line))
  26. fragment_urls.append(segment_url)
  27. # We only download the first fragment during the test
  28. if self.params.get('test', False):
  29. break
  30. ctx = {
  31. 'filename': filename,
  32. 'total_frags': len(fragment_urls),
  33. }
  34. self._prepare_and_start_frag_download(ctx)
  35. frags_filenames = []
  36. for i, frag_url in enumerate(fragment_urls):
  37. frag_filename = '%s-Frag%d' % (ctx['tmpfilename'], i)
  38. success = ctx['dl'].download(frag_filename, {'url': frag_url})
  39. if not success:
  40. return False
  41. down, frag_sanitized = sanitize_open(frag_filename, 'rb')
  42. ctx['dest_stream'].write(down.read())
  43. down.close()
  44. frags_filenames.append(frag_sanitized)
  45. self._finish_frag_download(ctx)
  46. for frag_file in frags_filenames:
  47. os.remove(encodeFilename(frag_file))
  48. return True