logo

youtube-dl

[mirror] Download/Watch videos from video hostersgit clone https://hacktivis.me/git/mirror/youtube-dl.git

s4c.py (4496B)


  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. from functools import partial as partial_f
  4. from .common import InfoExtractor
  5. from ..utils import (
  6. float_or_none,
  7. merge_dicts,
  8. T,
  9. traverse_obj,
  10. txt_or_none,
  11. url_or_none,
  12. )
  13. class S4CIE(InfoExtractor):
  14. _VALID_URL = r'https?://(?:www\.)?s4c\.cymru/clic/programme/(?P<id>\d+)'
  15. _TESTS = [{
  16. 'url': 'https://www.s4c.cymru/clic/programme/861362209',
  17. 'info_dict': {
  18. 'id': '861362209',
  19. 'ext': 'mp4',
  20. 'title': 'Y Swn',
  21. 'description': 'md5:f7681a30e4955b250b3224aa9fe70cf0',
  22. 'duration': 5340,
  23. 'thumbnail': 'https://www.s4c.cymru/amg/1920x1080/Y_Swn_2023S4C_099_ii.jpg',
  24. },
  25. }, {
  26. 'url': 'https://www.s4c.cymru/clic/programme/856636948',
  27. 'info_dict': {
  28. 'id': '856636948',
  29. 'ext': 'mp4',
  30. 'title': 'Am Dro',
  31. 'duration': 2880,
  32. 'description': 'md5:100d8686fc9a632a0cb2db52a3433ffe',
  33. 'thumbnail': 'https://www.s4c.cymru/amg/1920x1080/Am_Dro_2022-23S4C_P6_4005.jpg',
  34. },
  35. }]
  36. def _real_extract(self, url):
  37. video_id = self._match_id(url)
  38. details = self._download_json(
  39. 'https://www.s4c.cymru/df/full_prog_details',
  40. video_id, query={
  41. 'lang': 'e',
  42. 'programme_id': video_id,
  43. }, fatal=False)
  44. player_config = self._download_json(
  45. 'https://player-api.s4c-cdn.co.uk/player-configuration/prod', video_id, query={
  46. 'programme_id': video_id,
  47. 'signed': '0',
  48. 'lang': 'en',
  49. 'mode': 'od',
  50. 'appId': 'clic',
  51. 'streamName': '',
  52. }, note='Downloading player config JSON')
  53. m3u8_url = self._download_json(
  54. 'https://player-api.s4c-cdn.co.uk/streaming-urls/prod', video_id, query={
  55. 'mode': 'od',
  56. 'application': 'clic',
  57. 'region': 'WW',
  58. 'extra': 'false',
  59. 'thirdParty': 'false',
  60. 'filename': player_config['filename'],
  61. }, note='Downloading streaming urls JSON')['hls']
  62. formats = self._extract_m3u8_formats(m3u8_url, video_id, 'mp4', m3u8_id='hls', entry_protocol='m3u8_native')
  63. self._sort_formats(formats)
  64. subtitles = {}
  65. for sub in traverse_obj(player_config, ('subtitles', lambda _, v: url_or_none(v['0']))):
  66. subtitles.setdefault(sub.get('3', 'en'), []).append({
  67. 'url': sub['0'],
  68. 'name': sub.get('1'),
  69. })
  70. return merge_dicts({
  71. 'id': video_id,
  72. 'formats': formats,
  73. 'subtitles': subtitles,
  74. 'thumbnail': url_or_none(player_config.get('poster')),
  75. }, traverse_obj(details, ('full_prog_details', 0, {
  76. 'title': (('programme_title', 'series_title'), T(txt_or_none)),
  77. 'description': ('full_billing', T(txt_or_none)),
  78. 'duration': ('duration', T(partial_f(float_or_none, invscale=60))),
  79. }), get_all=False),
  80. rev=True)
  81. class S4CSeriesIE(InfoExtractor):
  82. _VALID_URL = r'https?://(?:www\.)?s4c\.cymru/clic/series/(?P<id>\d+)'
  83. _TESTS = [{
  84. 'url': 'https://www.s4c.cymru/clic/series/864982911',
  85. 'playlist_mincount': 6,
  86. 'info_dict': {
  87. 'id': '864982911',
  88. 'title': 'Iaith ar Daith',
  89. },
  90. }, {
  91. 'url': 'https://www.s4c.cymru/clic/series/866852587',
  92. 'playlist_mincount': 8,
  93. 'info_dict': {
  94. 'id': '866852587',
  95. 'title': 'FFIT Cymru',
  96. },
  97. }]
  98. def _real_extract(self, url):
  99. series_id = self._match_id(url)
  100. series_details = self._download_json(
  101. 'https://www.s4c.cymru/df/series_details', series_id, query={
  102. 'lang': 'e',
  103. 'series_id': series_id,
  104. 'show_prog_in_series': 'Y'
  105. }, note='Downloading series details JSON')
  106. return self.playlist_result(
  107. (self.url_result('https://www.s4c.cymru/clic/programme/' + episode_id, S4CIE, episode_id)
  108. for episode_id in traverse_obj(series_details, ('other_progs_in_series', Ellipsis, 'id'))),
  109. playlist_id=series_id, playlist_title=traverse_obj(
  110. series_details, ('full_prog_details', 0, 'series_title', T(txt_or_none))))