store video_id in LiveStreamError
Browse files- pytube/__main__.py +7 -7
- pytube/exceptions.py +9 -0
- pytube/extract.py +1 -1
- tests/test_extract.py +5 -0
pytube/__main__.py
CHANGED
|
@@ -22,7 +22,7 @@ from pytube import Stream
|
|
| 22 |
from pytube import StreamQuery
|
| 23 |
from pytube.extract import apply_descrambler, apply_signature, get_ytplayer_config
|
| 24 |
from pytube.helpers import install_proxy
|
| 25 |
-
from pytube.exceptions import VideoUnavailable
|
| 26 |
from pytube.monostate import OnProgress, OnComplete, Monostate
|
| 27 |
|
| 28 |
logger = logging.getLogger(__name__)
|
|
@@ -162,17 +162,17 @@ class YouTube:
|
|
| 162 |
which blocks for long periods of time.
|
| 163 |
|
| 164 |
:rtype: None
|
| 165 |
-
|
| 166 |
"""
|
| 167 |
self.watch_html = request.get(url=self.watch_url)
|
| 168 |
if self.watch_html is None:
|
| 169 |
raise VideoUnavailable(video_id=self.video_id)
|
| 170 |
self.age_restricted = extract.is_age_restricted(self.watch_html)
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
|
|
|
| 176 |
|
| 177 |
if self.age_restricted:
|
| 178 |
if not self.embed_html:
|
|
|
|
| 22 |
from pytube import StreamQuery
|
| 23 |
from pytube.extract import apply_descrambler, apply_signature, get_ytplayer_config
|
| 24 |
from pytube.helpers import install_proxy
|
| 25 |
+
from pytube.exceptions import VideoUnavailable, LiveStreamError
|
| 26 |
from pytube.monostate import OnProgress, OnComplete, Monostate
|
| 27 |
|
| 28 |
logger = logging.getLogger(__name__)
|
|
|
|
| 162 |
which blocks for long periods of time.
|
| 163 |
|
| 164 |
:rtype: None
|
|
|
|
| 165 |
"""
|
| 166 |
self.watch_html = request.get(url=self.watch_url)
|
| 167 |
if self.watch_html is None:
|
| 168 |
raise VideoUnavailable(video_id=self.video_id)
|
| 169 |
self.age_restricted = extract.is_age_restricted(self.watch_html)
|
| 170 |
+
|
| 171 |
+
if not self.age_restricted:
|
| 172 |
+
if "yt-badge-live" in self.watch_html:
|
| 173 |
+
raise LiveStreamError(self.video_id)
|
| 174 |
+
if "This video is private" in self.watch_html:
|
| 175 |
+
raise VideoUnavailable(video_id=self.video_id)
|
| 176 |
|
| 177 |
if self.age_restricted:
|
| 178 |
if not self.embed_html:
|
pytube/exceptions.py
CHANGED
|
@@ -35,6 +35,15 @@ class RegexMatchError(ExtractError):
|
|
| 35 |
class LiveStreamError(ExtractError):
|
| 36 |
"""Video is a live stream."""
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
class VideoUnavailable(PytubeError):
|
| 40 |
"""Video is unavailable."""
|
|
|
|
| 35 |
class LiveStreamError(ExtractError):
|
| 36 |
"""Video is a live stream."""
|
| 37 |
|
| 38 |
+
def __init__(self, video_id: str):
|
| 39 |
+
"""
|
| 40 |
+
:param str video_id:
|
| 41 |
+
A YouTube video identifier.
|
| 42 |
+
"""
|
| 43 |
+
super().__init__(f"{video_id} is streaming live and cannot be loaded")
|
| 44 |
+
|
| 45 |
+
self.video_id = video_id
|
| 46 |
+
|
| 47 |
|
| 48 |
class VideoUnavailable(PytubeError):
|
| 49 |
"""Video is unavailable."""
|
pytube/extract.py
CHANGED
|
@@ -231,7 +231,7 @@ def apply_signature(config_args: Dict, fmt: str, js: str) -> None:
|
|
| 231 |
url: str = stream["url"]
|
| 232 |
except KeyError:
|
| 233 |
if live_stream:
|
| 234 |
-
raise LiveStreamError("
|
| 235 |
# 403 Forbidden fix.
|
| 236 |
if "signature" in url or (
|
| 237 |
"s" not in stream and ("&sig=" in url or "&lsig=" in url)
|
|
|
|
| 231 |
url: str = stream["url"]
|
| 232 |
except KeyError:
|
| 233 |
if live_stream:
|
| 234 |
+
raise LiveStreamError("UNKNOWN")
|
| 235 |
# 403 Forbidden fix.
|
| 236 |
if "signature" in url or (
|
| 237 |
"s" not in stream and ("&sig=" in url or "&lsig=" in url)
|
tests/test_extract.py
CHANGED
|
@@ -77,3 +77,8 @@ def test_mime_type_codec():
|
|
| 77 |
def test_mime_type_codec_with_no_match_should_error():
|
| 78 |
with pytest.raises(RegexMatchError):
|
| 79 |
extract.mime_type_codec("audio/webm")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
def test_mime_type_codec_with_no_match_should_error():
|
| 78 |
with pytest.raises(RegexMatchError):
|
| 79 |
extract.mime_type_codec("audio/webm")
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def test_get_ytplayer_config_with_no_match_should_error():
|
| 83 |
+
with pytest.raises(RegexMatchError):
|
| 84 |
+
extract.get_ytplayer_config("")
|