logo

oasis-root

Compiled tree of Oasis Linux based on own branch at <https://hacktivis.me/git/oasis/> git clone https://anongit.hacktivis.me/git/oasis-root.git

beacon.py (2710B)


  1. import json
  2. from .common import InfoExtractor
  3. from ..utils import (
  4. ExtractorError,
  5. parse_iso8601,
  6. traverse_obj,
  7. )
  8. class BeaconTvIE(InfoExtractor):
  9. _VALID_URL = r'https?://(?:www\.)?beacon\.tv/content/(?P<id>[\w-]+)'
  10. _TESTS = [{
  11. 'url': 'https://beacon.tv/content/welcome-to-beacon',
  12. 'md5': 'b3f5932d437f288e662f10f3bfc5bd04',
  13. 'info_dict': {
  14. 'id': 'welcome-to-beacon',
  15. 'ext': 'mp4',
  16. 'upload_date': '20240509',
  17. 'description': 'md5:ea2bd32e71acf3f9fca6937412cc3563',
  18. 'thumbnail': 'https://cdn.jwplayer.com/v2/media/I4CkkEvN/poster.jpg?width=720',
  19. 'title': 'Your home for Critical Role!',
  20. 'timestamp': 1715227200,
  21. 'duration': 105.494,
  22. },
  23. }, {
  24. 'url': 'https://beacon.tv/content/re-slayers-take-trailer',
  25. 'md5': 'd879b091485dbed2245094c8152afd89',
  26. 'info_dict': {
  27. 'id': 're-slayers-take-trailer',
  28. 'ext': 'mp4',
  29. 'title': 'The Re-Slayer’s Take | Official Trailer',
  30. 'timestamp': 1715189040,
  31. 'upload_date': '20240508',
  32. 'duration': 53.249,
  33. 'thumbnail': 'https://cdn.jwplayer.com/v2/media/PW5ApIw3/poster.jpg?width=720',
  34. },
  35. }]
  36. def _real_extract(self, url):
  37. video_id = self._match_id(url)
  38. webpage = self._download_webpage(url, video_id)
  39. content_data = traverse_obj(self._search_nextjs_data(webpage, video_id), (
  40. 'props', 'pageProps', '__APOLLO_STATE__',
  41. lambda k, v: k.startswith('Content:') and v['slug'] == video_id, any))
  42. if not content_data:
  43. raise ExtractorError('Failed to extract content data')
  44. jwplayer_data = traverse_obj(content_data, (
  45. (('contentVideo', 'video', 'videoData'),
  46. ('contentPodcast', 'podcast', 'audioData')), {json.loads}, {dict}, any))
  47. if not jwplayer_data:
  48. if content_data.get('contentType') not in ('videoPodcast', 'video', 'podcast'):
  49. raise ExtractorError('Content is not a video/podcast', expected=True)
  50. if traverse_obj(content_data, ('contentTier', '__ref')) != 'MemberTier:65b258d178f89be87b4dc0a4':
  51. self.raise_login_required('This video/podcast is for members only')
  52. raise ExtractorError('Failed to extract content')
  53. return {
  54. **self._parse_jwplayer_data(jwplayer_data, video_id),
  55. **traverse_obj(content_data, {
  56. 'title': ('title', {str}),
  57. 'description': ('description', {str}),
  58. 'timestamp': ('publishedAt', {parse_iso8601}),
  59. }),
  60. }