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.

254 lines
9.0 KiB

  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. import re
  4. from .common import InfoExtractor
  5. from ..compat import compat_str
  6. from ..utils import (
  7. parse_iso8601,
  8. qualities,
  9. determine_ext,
  10. update_url_query,
  11. int_or_none,
  12. )
  13. class TVPlayIE(InfoExtractor):
  14. IE_DESC = 'TV3Play and related services'
  15. _VALID_URL = r'''(?x)https?://(?:www\.)?
  16. (?:tvplay(?:\.skaties)?\.lv/parraides|
  17. (?:tv3play|play\.tv3)\.lt/programos|
  18. tv3play(?:\.tv3)?\.ee/sisu|
  19. tv(?:3|6|8|10)play\.se/program|
  20. (?:(?:tv3play|viasat4play|tv6play)\.no|tv3play\.dk)/programmer|
  21. play\.novatv\.bg/programi
  22. )/[^/]+/(?P<id>\d+)
  23. '''
  24. _TESTS = [
  25. {
  26. 'url': 'http://www.tvplay.lv/parraides/vinas-melo-labak/418113?autostart=true',
  27. 'md5': 'a1612fe0849455423ad8718fe049be21',
  28. 'info_dict': {
  29. 'id': '418113',
  30. 'ext': 'mp4',
  31. 'title': 'Kādi ir īri? - Viņas melo labāk',
  32. 'description': 'Baiba apsmej īrus, kādi tie ir un ko viņi dara.',
  33. 'duration': 25,
  34. 'timestamp': 1406097056,
  35. 'upload_date': '20140723',
  36. },
  37. },
  38. {
  39. 'url': 'http://play.tv3.lt/programos/moterys-meluoja-geriau/409229?autostart=true',
  40. 'info_dict': {
  41. 'id': '409229',
  42. 'ext': 'flv',
  43. 'title': 'Moterys meluoja geriau',
  44. 'description': 'md5:9aec0fc68e2cbc992d2a140bd41fa89e',
  45. 'duration': 1330,
  46. 'timestamp': 1403769181,
  47. 'upload_date': '20140626',
  48. },
  49. 'params': {
  50. # rtmp download
  51. 'skip_download': True,
  52. },
  53. },
  54. {
  55. 'url': 'http://www.tv3play.ee/sisu/kodu-keset-linna/238551?autostart=true',
  56. 'info_dict': {
  57. 'id': '238551',
  58. 'ext': 'flv',
  59. 'title': 'Kodu keset linna 398537',
  60. 'description': 'md5:7df175e3c94db9e47c0d81ffa5d68701',
  61. 'duration': 1257,
  62. 'timestamp': 1292449761,
  63. 'upload_date': '20101215',
  64. },
  65. 'params': {
  66. # rtmp download
  67. 'skip_download': True,
  68. },
  69. },
  70. {
  71. 'url': 'http://www.tv3play.se/program/husraddarna/395385?autostart=true',
  72. 'info_dict': {
  73. 'id': '395385',
  74. 'ext': 'mp4',
  75. 'title': 'Husräddarna S02E07',
  76. 'description': 'md5:f210c6c89f42d4fc39faa551be813777',
  77. 'duration': 2574,
  78. 'timestamp': 1400596321,
  79. 'upload_date': '20140520',
  80. },
  81. 'params': {
  82. 'skip_download': True,
  83. },
  84. },
  85. {
  86. 'url': 'http://www.tv6play.se/program/den-sista-dokusapan/266636?autostart=true',
  87. 'info_dict': {
  88. 'id': '266636',
  89. 'ext': 'mp4',
  90. 'title': 'Den sista dokusåpan S01E08',
  91. 'description': 'md5:295be39c872520221b933830f660b110',
  92. 'duration': 1492,
  93. 'timestamp': 1330522854,
  94. 'upload_date': '20120229',
  95. 'age_limit': 18,
  96. },
  97. 'params': {
  98. 'skip_download': True,
  99. },
  100. },
  101. {
  102. 'url': 'http://www.tv8play.se/program/antikjakten/282756?autostart=true',
  103. 'info_dict': {
  104. 'id': '282756',
  105. 'ext': 'mp4',
  106. 'title': 'Antikjakten S01E10',
  107. 'description': 'md5:1b201169beabd97e20c5ad0ad67b13b8',
  108. 'duration': 2646,
  109. 'timestamp': 1348575868,
  110. 'upload_date': '20120925',
  111. },
  112. 'params': {
  113. 'skip_download': True,
  114. },
  115. },
  116. {
  117. 'url': 'http://www.tv3play.no/programmer/anna-anka-soker-assistent/230898?autostart=true',
  118. 'info_dict': {
  119. 'id': '230898',
  120. 'ext': 'mp4',
  121. 'title': 'Anna Anka søker assistent - Ep. 8',
  122. 'description': 'md5:f80916bf5bbe1c5f760d127f8dd71474',
  123. 'duration': 2656,
  124. 'timestamp': 1277720005,
  125. 'upload_date': '20100628',
  126. },
  127. 'params': {
  128. 'skip_download': True,
  129. },
  130. },
  131. {
  132. 'url': 'http://www.viasat4play.no/programmer/budbringerne/21873?autostart=true',
  133. 'info_dict': {
  134. 'id': '21873',
  135. 'ext': 'mp4',
  136. 'title': 'Budbringerne program 10',
  137. 'description': 'md5:4db78dc4ec8a85bb04fd322a3ee5092d',
  138. 'duration': 1297,
  139. 'timestamp': 1254205102,
  140. 'upload_date': '20090929',
  141. },
  142. 'params': {
  143. 'skip_download': True,
  144. },
  145. },
  146. {
  147. 'url': 'http://www.tv6play.no/programmer/hotelinspektor-alex-polizzi/361883?autostart=true',
  148. 'info_dict': {
  149. 'id': '361883',
  150. 'ext': 'mp4',
  151. 'title': 'Hotelinspektør Alex Polizzi - Ep. 10',
  152. 'description': 'md5:3ecf808db9ec96c862c8ecb3a7fdaf81',
  153. 'duration': 2594,
  154. 'timestamp': 1393236292,
  155. 'upload_date': '20140224',
  156. },
  157. 'params': {
  158. 'skip_download': True,
  159. },
  160. },
  161. {
  162. 'url': 'http://play.novatv.bg/programi/zdravei-bulgariya/624952?autostart=true',
  163. 'info_dict': {
  164. 'id': '624952',
  165. 'ext': 'flv',
  166. 'title': 'Здравей, България (12.06.2015 г.) ',
  167. 'description': 'md5:99f3700451ac5bb71a260268b8daefd7',
  168. 'duration': 8838,
  169. 'timestamp': 1434100372,
  170. 'upload_date': '20150612',
  171. },
  172. 'params': {
  173. # rtmp download
  174. 'skip_download': True,
  175. },
  176. },
  177. {
  178. 'url': 'http://tvplay.skaties.lv/parraides/vinas-melo-labak/418113?autostart=true',
  179. 'only_matching': True,
  180. },
  181. {
  182. 'url': 'http://tv3play.tv3.ee/sisu/kodu-keset-linna/238551?autostart=true',
  183. 'only_matching': True,
  184. }
  185. ]
  186. def _real_extract(self, url):
  187. video_id = self._match_id(url)
  188. video = self._download_json(
  189. 'http://playapi.mtgx.tv/v1/videos/%s' % video_id, video_id, 'Downloading video JSON')
  190. title = video['title']
  191. if video.get('is_geo_blocked'):
  192. self.report_warning(
  193. 'This content might not be available in your country due to copyright reasons')
  194. streams = self._download_json(
  195. 'http://playapi.mtgx.tv/v1/videos/stream/%s' % video_id, video_id, 'Downloading streams JSON')
  196. quality = qualities(['hls', 'medium', 'high'])
  197. formats = []
  198. for format_id, video_url in streams.get('streams', {}).items():
  199. if not video_url or not isinstance(video_url, compat_str):
  200. continue
  201. ext = determine_ext(video_url)
  202. if ext == 'f4m':
  203. formats.extend(self._extract_f4m_formats(
  204. update_url_query(video_url, {
  205. 'hdcore': '3.5.0',
  206. 'plugin': 'aasp-3.5.0.151.81'
  207. }), video_id, f4m_id='hds', fatal=False))
  208. elif ext == 'm3u8':
  209. formats.extend(self._extract_m3u8_formats(
  210. video_url, video_id, 'mp4', 'm3u8_native',
  211. m3u8_id='hls', fatal=False))
  212. else:
  213. fmt = {
  214. 'format_id': format_id,
  215. 'quality': quality(format_id),
  216. 'ext': ext,
  217. }
  218. if video_url.startswith('rtmp'):
  219. m = re.search(r'^(?P<url>rtmp://[^/]+/(?P<app>[^/]+))/(?P<playpath>.+)$', video_url)
  220. if not m:
  221. continue
  222. fmt.update({
  223. 'ext': 'flv',
  224. 'url': m.group('url'),
  225. 'app': m.group('app'),
  226. 'play_path': m.group('playpath'),
  227. })
  228. else:
  229. fmt.update({
  230. 'url': video_url,
  231. })
  232. formats.append(fmt)
  233. self._sort_formats(formats)
  234. return {
  235. 'id': video_id,
  236. 'title': title,
  237. 'description': video.get('description'),
  238. 'duration': int_or_none(video.get('duration')),
  239. 'timestamp': parse_iso8601(video.get('created_at')),
  240. 'view_count': int_or_none(video.get('views', {}).get('total')),
  241. 'age_limit': int_or_none(video.get('age_limit', 0)),
  242. 'formats': formats,
  243. }