kanal2.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. from .common import InfoExtractor
  2. from ..utils import (
  3. ExtractorError,
  4. join_nonempty,
  5. traverse_obj,
  6. unified_timestamp,
  7. update_url_query,
  8. )
  9. class Kanal2IE(InfoExtractor):
  10. _VALID_URL = r'https?://kanal2\.postimees\.ee/[^?#]+\?([^#]+&)?id=(?P<id>\d+)'
  11. _TESTS = [{
  12. 'note': 'Test standard url (#5575)',
  13. 'url': 'https://kanal2.postimees.ee/pluss/video/?id=40792',
  14. 'md5': '7ea7b16266ec1798743777df241883dd',
  15. 'info_dict': {
  16. 'id': '40792',
  17. 'ext': 'mp4',
  18. 'title': 'Aedniku aabits / Osa 53 (05.08.2016 20:00)',
  19. 'thumbnail': r're:https?://.*\.jpg$',
  20. 'description': 'md5:53cabf3c5d73150d594747f727431248',
  21. 'upload_date': '20160805',
  22. 'timestamp': 1470420000,
  23. },
  24. }]
  25. def _real_extract(self, url):
  26. video_id = self._match_id(url)
  27. playlist = self._download_json(
  28. f'https://kanal2.postimees.ee/player/playlist/{video_id}',
  29. video_id, query={'type': 'episodes'},
  30. headers={'X-Requested-With': 'XMLHttpRequest'})
  31. return {
  32. 'id': video_id,
  33. 'title': join_nonempty(*traverse_obj(playlist, ('info', ('title', 'subtitle'))), delim=' / '),
  34. 'description': traverse_obj(playlist, ('info', 'description')),
  35. 'thumbnail': traverse_obj(playlist, ('data', 'image')),
  36. 'formats': self.get_formats(playlist, video_id),
  37. 'timestamp': unified_timestamp(self._search_regex(
  38. r'\((\d{2}\.\d{2}\.\d{4}\s\d{2}:\d{2})\)$',
  39. traverse_obj(playlist, ('info', 'subtitle')), 'timestamp', default='') + ' +0200'),
  40. }
  41. def get_formats(self, playlist, video_id):
  42. path = traverse_obj(playlist, ('data', 'path'))
  43. if not path:
  44. raise ExtractorError('Path value not found in playlist JSON response')
  45. session = self._download_json(
  46. 'https://sts.postimees.ee/session/register',
  47. video_id, note='Creating session', errnote='Error creating session',
  48. headers={
  49. 'X-Original-URI': path,
  50. 'Accept': 'application/json',
  51. })
  52. if session.get('reason') != 'OK' or not session.get('session'):
  53. reason = session.get('reason', 'unknown error')
  54. raise ExtractorError(f'Unable to obtain session: {reason}')
  55. formats = []
  56. for stream in traverse_obj(playlist, ('data', 'streams', ..., 'file')):
  57. formats.extend(self._extract_m3u8_formats(
  58. update_url_query(stream, {'s': session['session']}), video_id, 'mp4'))
  59. return formats