warp-beacon 2.7.12__py3-none-any.whl → 2.7.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- __version__ = "2.7.12"
1
+ __version__ = "2.7.13"
2
2
 
@@ -13,6 +13,7 @@ from typing import Callable, Optional, Union
13
13
  from urllib.parse import parse_qs, urlparse
14
14
 
15
15
  import numpy as np
16
+ import av
16
17
  import pytubefix
17
18
  import pytubefix.exceptions
18
19
  import requests
@@ -387,3 +388,30 @@ class YoutubeAbstract(ScraperAbstract):
387
388
  raise Unavailable("Сontent unvailable")
388
389
 
389
390
  return ret
391
+
392
+ def mux_raw_copy(self, video_path: str, audio_path: str, output_path: str) -> str:
393
+ try:
394
+ with av.open(video_path) as input_video, av.open(audio_path) as input_audio, av.open(output_path, mode='w') as output:
395
+ in_video_stream = input_video.streams.video[0]
396
+ in_audio_stream = input_audio.streams.audio[0]
397
+
398
+ video_stream_map = output.add_stream(template=in_video_stream)
399
+ audio_stream_map = output.add_stream(template=in_audio_stream)
400
+
401
+ for packet in input_video.demux(in_video_stream):
402
+ if packet.dts is None:
403
+ continue
404
+ packet.stream = video_stream_map
405
+ output.mux(packet)
406
+
407
+ for packet in input_audio.demux(in_audio_stream):
408
+ if packet.dts is None:
409
+ continue
410
+ packet.stream = audio_stream_map
411
+ output.mux(packet)
412
+ except Exception as e:
413
+ logging.error("Failed to mux audio and video!")
414
+ logging.exception(e)
415
+ return ''
416
+
417
+ return output_path
@@ -1,13 +1,16 @@
1
+ import os
1
2
  import io
2
3
  from typing import Optional
4
+ import time
3
5
 
4
6
  import logging
5
7
 
8
+ from pytubefix.exceptions import AgeRestrictedError
9
+
6
10
  from warp_beacon.jobs.types import JobType
7
11
  from warp_beacon.scraper.youtube.abstract import YoutubeAbstract
8
- from warp_beacon.scraper.exceptions import NotFound
9
12
 
10
- from warp_beacon.mediainfo.video import VideoInfo
13
+ from warp_beacon.scraper.exceptions import NotFound, YotubeAgeRestrictedError
11
14
 
12
15
  class YoutubeShortsScraper(YoutubeAbstract):
13
16
  YT_MAX_RETRIES_DEFAULT = 8
@@ -15,7 +18,14 @@ class YoutubeShortsScraper(YoutubeAbstract):
15
18
  YT_TIMEOUT_DEFAULT = 2
16
19
  YT_TIMEOUT_INCREMENT_DEFAULT = 60
17
20
 
18
- def _download(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 0) -> list:
21
+ def _download(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 60) -> list:
22
+ res = self._download_pytubefix_max_res(url=url, session=session, thumbnail=thumbnail, timeout=timeout)
23
+ if not res:
24
+ res = self._download_pytube_dash(url=url, session=session, thumbnail=thumbnail, timeout=timeout)
25
+
26
+ return res
27
+
28
+ def _download_pytube_dash(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 0) -> list:
19
29
  res = []
20
30
  yt = self.build_yt(url, session=session)
21
31
  stream = yt.streams.get_highest_resolution()
@@ -58,4 +68,57 @@ class YoutubeShortsScraper(YoutubeAbstract):
58
68
  "media_type": JobType.VIDEO
59
69
  })
60
70
 
71
+ return res
72
+
73
+ def _download_pytubefix_max_res(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 60) -> list:
74
+ res = []
75
+ local_video_file, local_audio_file = '', ''
76
+ try:
77
+ yt = self.build_yt(url, session=session)
78
+
79
+ video_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_video=True).order_by('resolution').desc().first()
80
+ audio_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_audio=True).order_by('abr').desc().first()
81
+
82
+ local_video_file = video_stream.download(
83
+ output_path=self.DOWNLOAD_DIR,
84
+ max_retries=3,
85
+ timeout=timeout,
86
+ skip_existing=False,
87
+ filename_prefix="yt_download_video_"
88
+ )
89
+ local_video_file = self.rename_local_file(local_video_file)
90
+ logging.debug("Temp video filename: '%s'", local_video_file)
91
+ local_audio_file = audio_stream.download(
92
+ output_path=self.DOWNLOAD_DIR,
93
+ max_retries=3,
94
+ timeout=timeout,
95
+ skip_existing=False,
96
+ filename_prefix="yt_download_audio_"
97
+ )
98
+ local_audio_file = self.rename_local_file(local_audio_file)
99
+ logging.debug("Temp audio filename: '%s'", local_audio_file)
100
+
101
+ muxed_video = self.mux_raw_copy(
102
+ video_path=local_video_file,
103
+ audio_path=local_audio_file,
104
+ output_path=f"{self.DOWNLOAD_DIR}/yt_muxed_video_{int(time.time())}.mp4")
105
+ if muxed_video:
106
+ muxed_video = self.rename_local_file(muxed_video)
107
+ logging.debug("Temp muxed filename: '%s'", muxed_video)
108
+
109
+ res.append({
110
+ "local_media_path": muxed_video,
111
+ "performer": yt.author,
112
+ "thumb": thumbnail,
113
+ "canonical_name": yt.title,
114
+ "media_type": JobType.VIDEO
115
+ })
116
+ except AgeRestrictedError as e:
117
+ raise YotubeAgeRestrictedError("Youtube Age Restricted error")
118
+ finally:
119
+ if os.path.exists(local_video_file):
120
+ os.unlink(local_video_file)
121
+ if os.path.exists(local_audio_file):
122
+ os.unlink(local_audio_file)
123
+
61
124
  return res
@@ -4,7 +4,6 @@ import io
4
4
  from typing import Optional
5
5
  import logging
6
6
 
7
- import av
8
7
  from pytubefix.exceptions import AgeRestrictedError
9
8
 
10
9
  from warp_beacon.jobs.types import JobType
@@ -39,33 +38,6 @@ class YoutubeScraper(YoutubeAbstract):
39
38
  res = self._download_pytube_dash(url=url, session=session, thumbnail=thumbnail, timeout=timeout)
40
39
 
41
40
  return res
42
-
43
- def mux_raw_copy(self, video_path: str, audio_path: str, output_path: str) -> str:
44
- try:
45
- with av.open(video_path) as input_video, av.open(audio_path) as input_audio, av.open(output_path, mode='w') as output:
46
- in_video_stream = input_video.streams.video[0]
47
- in_audio_stream = input_audio.streams.audio[0]
48
-
49
- video_stream_map = output.add_stream(template=in_video_stream)
50
- audio_stream_map = output.add_stream(template=in_audio_stream)
51
-
52
- for packet in input_video.demux(in_video_stream):
53
- if packet.dts is None:
54
- continue
55
- packet.stream = video_stream_map
56
- output.mux(packet)
57
-
58
- for packet in input_audio.demux(in_audio_stream):
59
- if packet.dts is None:
60
- continue
61
- packet.stream = audio_stream_map
62
- output.mux(packet)
63
- except Exception as e:
64
- logging.error("Failed to mux audio and video!")
65
- logging.exception(e)
66
- return ''
67
-
68
- return output_path
69
41
 
70
42
  def _download_pytubefix_max_res(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 60) -> list:
71
43
  res = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: warp_beacon
3
- Version: 2.7.12
3
+ Version: 2.7.13
4
4
  Summary: Telegram bot for expanding external media links
5
5
  Home-page: https://github.com/sb0y/warp_beacon
6
6
  Author: Andrey Bagrintsev
@@ -4,7 +4,7 @@ var/warp_beacon/accounts.json,sha256=OsXdncs6h88xrF_AP6_WDCK1waGBn9SR-uYdIeK37GM
4
4
  var/warp_beacon/placeholder.gif,sha256=cE5CGJVaop4Sx21zx6j4AyoHU0ncmvQuS2o6hJfEH88,6064
5
5
  var/warp_beacon/proxies.json,sha256=VnjlQDXumOEq72ZFjbh6IqHS1TEHqn8HPYAZqWCeSIA,95
6
6
  warp_beacon/__init__.py,sha256=_rThNODmz0nDp_n4mWo_HKaNFE5jk1_7cRhHyYaencI,163
7
- warp_beacon/__version__.py,sha256=fmDPRrhg7swPQM39gTcuUdHQiY9U-FSActIV5FAD_lQ,24
7
+ warp_beacon/__version__.py,sha256=x219y8Xqh6qOh4lcwrZPGXW00waIfTBdHsot4GpeNiI,24
8
8
  warp_beacon/warp_beacon.py,sha256=ADCR30uGXIsDrt9WoiI9Ghu2QtWs0qZIK6x3pQKM_B4,1109
9
9
  warp_beacon/yt_auth.py,sha256=GUTKqYr_tzDC-07Lx_ahWXSag8EyLxXBUnQbDBIkEmk,6022
10
10
  warp_beacon/compress/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -34,10 +34,10 @@ warp_beacon/scraper/instagram/captcha.py,sha256=9UYziuqB3Tsat_ET6ex-cnZDbi6yCnsX
34
34
  warp_beacon/scraper/instagram/instagram.py,sha256=oVXP6VweJCeffhyDU-GZLa66ESW06GvfuGcW2V6YdQ4,18629
35
35
  warp_beacon/scraper/instagram/wb_instagrapi.py,sha256=M5NCtLwdUvByjmDBZMWljgB275R0LSBFblsGpapluD0,5968
36
36
  warp_beacon/scraper/youtube/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- warp_beacon/scraper/youtube/abstract.py,sha256=dCvNoXX4B7cY-gLNqF3LfYJQ855CBS4SFCehw9JjK6U,15278
37
+ warp_beacon/scraper/youtube/abstract.py,sha256=H53RjCGB5W-uvKEgFrPn0kSBxc8EQgpme-9DJF9I7rU,16193
38
38
  warp_beacon/scraper/youtube/music.py,sha256=5AeSBQyUgVCJT2hoBCV2WvlyuV9US09SYJhmBG_P9F8,2755
39
- warp_beacon/scraper/youtube/shorts.py,sha256=1GtoYUlxAwcgSQcn80u5ehNJytH5AN5dPOicmX-XD8E,1705
40
- warp_beacon/scraper/youtube/youtube.py,sha256=x9v9p1coA9TvBhxjNAofGu4UBkAEdYPE2ePRnU-5tK0,7233
39
+ warp_beacon/scraper/youtube/shorts.py,sha256=y0591kpWU35rt5OoWamkcHIstNZ98SXUlUKvYmUsyEY,4030
40
+ warp_beacon/scraper/youtube/youtube.py,sha256=i-3Z5l3S-EltIFbxkbvDjXMgH8fGOrB5-ua1p6iH_Bc,6316
41
41
  warp_beacon/storage/__init__.py,sha256=0Vajd0oITKJfu2vmNx5uQSt3-L6vwIvUYWJo8HZCjco,3398
42
42
  warp_beacon/storage/mongo.py,sha256=qC4ZiO8XXvPnP0rJwz4CJx42pqFsyAjCiW10W5QdT6E,527
43
43
  warp_beacon/telegram/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -52,9 +52,9 @@ warp_beacon/telegram/progress_file_reader.py,sha256=e3equyNKlKs764AD-iE9QRsh3YDH
52
52
  warp_beacon/telegram/types.py,sha256=Kvdng6uCF1HRoqQgGW1ZYYPJoVuYkFb-LDvMBbW5Hjk,89
53
53
  warp_beacon/telegram/utils.py,sha256=S1N_JbHM_ExiM5tS0CeYKWIlvaJMlyq85TQNbK_GVds,5029
54
54
  warp_beacon/uploader/__init__.py,sha256=ewvR60k9osJxw_kb5U-TlZkCGR_574biq3w_aR1tjIU,5689
55
- warp_beacon-2.7.12.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
56
- warp_beacon-2.7.12.dist-info/METADATA,sha256=HvkC9EFodqkA0lHCM0mihERU8p1v4G-Nf-iooEA6I4o,23215
57
- warp_beacon-2.7.12.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
58
- warp_beacon-2.7.12.dist-info/entry_points.txt,sha256=eSB61Rb89d56WY0O-vEIQwkn18J-4CMrJcLA_R_8h3g,119
59
- warp_beacon-2.7.12.dist-info/top_level.txt,sha256=5YQRN46STNg81V_3jdzZ6bftkMxhe1hTPSFvJugDu84,1405
60
- warp_beacon-2.7.12.dist-info/RECORD,,
55
+ warp_beacon-2.7.13.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
56
+ warp_beacon-2.7.13.dist-info/METADATA,sha256=wRZPk7SRIYDZ9xSsAVfRdW_TK206mInTQIiZYLRD_sY,23215
57
+ warp_beacon-2.7.13.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
58
+ warp_beacon-2.7.13.dist-info/entry_points.txt,sha256=eSB61Rb89d56WY0O-vEIQwkn18J-4CMrJcLA_R_8h3g,119
59
+ warp_beacon-2.7.13.dist-info/top_level.txt,sha256=5YQRN46STNg81V_3jdzZ6bftkMxhe1hTPSFvJugDu84,1405
60
+ warp_beacon-2.7.13.dist-info/RECORD,,