Guy
commited on
Commit
·
4030ef4
1
Parent(s):
2ede878
Detect live videos #263 (#266)
Browse files- raises an exception if video is a live stream (https://www.youtube.com/channel/UC4R8DWoMoI7CAwX8_LjQHig for examples)
- if live stream has finished, download video as normal, e.g. https://www.youtube.com/watch?v=7CefpC0jdqE
- .gitignore +3 -0
- pytube/exceptions.py +4 -0
- pytube/mixins.py +8 -1
.gitignore
CHANGED
@@ -17,6 +17,9 @@ pkg
|
|
17 |
*.egg
|
18 |
*.egg-info
|
19 |
|
|
|
|
|
|
|
20 |
# Debian Files
|
21 |
debian/files
|
22 |
debian/python-beaver*
|
|
|
17 |
*.egg
|
18 |
*.egg-info
|
19 |
|
20 |
+
# Test files
|
21 |
+
.pytest_cache/
|
22 |
+
|
23 |
# Debian Files
|
24 |
debian/files
|
25 |
debian/python-beaver*
|
pytube/exceptions.py
CHANGED
@@ -36,5 +36,9 @@ class RegexMatchError(ExtractError):
|
|
36 |
"""Regex pattern did not return any matches."""
|
37 |
|
38 |
|
|
|
|
|
|
|
|
|
39 |
class VideoUnavailable(PytubeError):
|
40 |
"""Video is unavailable."""
|
|
|
36 |
"""Regex pattern did not return any matches."""
|
37 |
|
38 |
|
39 |
+
class LiveStreamError(ExtractError):
|
40 |
+
"""Video is a live stream."""
|
41 |
+
|
42 |
+
|
43 |
class VideoUnavailable(PytubeError):
|
44 |
"""Video is unavailable."""
|
pytube/mixins.py
CHANGED
@@ -2,12 +2,14 @@
|
|
2 |
"""Applies in-place data mutations."""
|
3 |
from __future__ import absolute_import
|
4 |
|
|
|
5 |
import logging
|
6 |
import pprint
|
7 |
|
8 |
from pytube import cipher
|
9 |
from pytube.compat import parse_qsl
|
10 |
from pytube.compat import unquote
|
|
|
11 |
|
12 |
|
13 |
logger = logging.getLogger(__name__)
|
@@ -27,8 +29,13 @@ def apply_signature(config_args, fmt, js):
|
|
27 |
|
28 |
"""
|
29 |
stream_manifest = config_args[fmt]
|
|
|
|
|
30 |
for i, stream in enumerate(stream_manifest):
|
31 |
-
url
|
|
|
|
|
|
|
32 |
|
33 |
if 'signature=' in url:
|
34 |
# For certain videos, YouTube will just provide them pre-signed, in
|
|
|
2 |
"""Applies in-place data mutations."""
|
3 |
from __future__ import absolute_import
|
4 |
|
5 |
+
import json
|
6 |
import logging
|
7 |
import pprint
|
8 |
|
9 |
from pytube import cipher
|
10 |
from pytube.compat import parse_qsl
|
11 |
from pytube.compat import unquote
|
12 |
+
from pytube.exceptions import LiveStreamError
|
13 |
|
14 |
|
15 |
logger = logging.getLogger(__name__)
|
|
|
29 |
|
30 |
"""
|
31 |
stream_manifest = config_args[fmt]
|
32 |
+
live_stream = json.loads(config_args['player_response']).get(
|
33 |
+
'playabilityStatus', {}).get('liveStreamability')
|
34 |
for i, stream in enumerate(stream_manifest):
|
35 |
+
if 'url' in stream:
|
36 |
+
url = stream['url']
|
37 |
+
elif live_stream:
|
38 |
+
raise LiveStreamError('Video is currently being streamed live')
|
39 |
|
40 |
if 'signature=' in url:
|
41 |
# For certain videos, YouTube will just provide them pre-signed, in
|