hbmartin commited on
Commit
dc3bd9b
·
1 Parent(s): 3014619

is_dash property, more tests

Browse files
pytube/contrib/playlist.py CHANGED
@@ -6,6 +6,7 @@ import logging
6
  import re
7
  from collections import OrderedDict
8
  from typing import List, Optional
 
9
 
10
  from pytube import request
11
  from pytube.__main__ import YouTube
@@ -25,9 +26,8 @@ class Playlist:
25
 
26
  if "watch?v=" in url:
27
  base_url = "https://www.youtube.com/playlist?list="
28
- # TODO: should be parse q
29
- playlist_code = self.playlist_url.split("&list=")[1]
30
- self.playlist_url = base_url + playlist_code
31
 
32
  @staticmethod
33
  def _find_load_more_url(req: str) -> Optional[str]:
 
6
  import re
7
  from collections import OrderedDict
8
  from typing import List, Optional
9
+ from urllib.parse import parse_qs
10
 
11
  from pytube import request
12
  from pytube.__main__ import YouTube
 
26
 
27
  if "watch?v=" in url:
28
  base_url = "https://www.youtube.com/playlist?list="
29
+ query_parameters = parse_qs(url.split("?")[1])
30
+ self.playlist_url = base_url + query_parameters["list"][0]
 
31
 
32
  @staticmethod
33
  def _find_load_more_url(req: str) -> Optional[str]:
pytube/itags.py CHANGED
@@ -98,7 +98,8 @@ _3D = [82, 83, 84, 85, 100, 101, 102]
98
  LIVE = [91, 92, 93, 94, 95, 96, 132, 151]
99
  DASH_MP4_VIDEO = [133, 134, 135, 136, 137, 138, 160, 212, 264, 266, 298, 299]
100
  DASH_MP4_AUDIO = [139, 140, 141, 256, 258, 325, 328]
101
-
 
102
 
103
  def get_format_profile(itag: int) -> Dict:
104
  """Get additional format information for a given itag.
@@ -118,5 +119,5 @@ def get_format_profile(itag: int) -> Dict:
118
  "is_3d": itag in _3D,
119
  "is_hdr": itag in HDR,
120
  "fps": 60 if itag in _60FPS else 30,
121
- "is_dash": itag in DASH_MP4_VIDEO or itag in DASH_MP4_AUDIO,
122
  }
 
98
  LIVE = [91, 92, 93, 94, 95, 96, 132, 151]
99
  DASH_MP4_VIDEO = [133, 134, 135, 136, 137, 138, 160, 212, 264, 266, 298, 299]
100
  DASH_MP4_AUDIO = [139, 140, 141, 256, 258, 325, 328]
101
+ DASH_WEBM_VIDEO = [167, 168, 169, 170, 218, 219, 278, 242, 243, 244, 245, 246, 247, 248, 271, 272, 302, 303, 308, 313, 315]
102
+ DASH_WEBM_AUDIO = [171, 172, 249, 250, 251]
103
 
104
  def get_format_profile(itag: int) -> Dict:
105
  """Get additional format information for a given itag.
 
119
  "is_3d": itag in _3D,
120
  "is_hdr": itag in HDR,
121
  "fps": 60 if itag in _60FPS else 30,
122
+ "is_dash": itag in DASH_MP4_VIDEO or itag in DASH_MP4_AUDIO or itag in DASH_WEBM_VIDEO or itag in DASH_WEBM_AUDIO,
123
  }
pytube/query.py CHANGED
@@ -34,6 +34,7 @@ class StreamQuery:
34
  only_video=None,
35
  progressive=None,
36
  adaptive=None,
 
37
  custom_filter_functions=None,
38
  ):
39
  """Apply the given filtering criterion.
@@ -103,6 +104,9 @@ class StreamQuery:
103
  Excludes progressive streams (audio and video are on separate
104
  tracks).
105
 
 
 
 
106
  :param bool only_audio:
107
  Excludes streams with video tracks.
108
 
@@ -161,6 +165,9 @@ class StreamQuery:
161
  for fn in custom_filter_functions:
162
  filters.append(fn)
163
 
 
 
 
164
  fmt_streams = self.fmt_streams
165
  for fn in filters:
166
  fmt_streams = list(filter(fn, fmt_streams))
 
34
  only_video=None,
35
  progressive=None,
36
  adaptive=None,
37
+ is_dash=None,
38
  custom_filter_functions=None,
39
  ):
40
  """Apply the given filtering criterion.
 
104
  Excludes progressive streams (audio and video are on separate
105
  tracks).
106
 
107
+ :param bool is_dash:
108
+ Include/exclude dash streams.
109
+
110
  :param bool only_audio:
111
  Excludes streams with video tracks.
112
 
 
165
  for fn in custom_filter_functions:
166
  filters.append(fn)
167
 
168
+ if is_dash is not None:
169
+ filters.append(lambda s: s.is_dash == is_dash)
170
+
171
  fmt_streams = self.fmt_streams
172
  for fn in filters:
173
  fmt_streams = list(filter(fn, fmt_streams))
pytube/streams.py CHANGED
@@ -59,6 +59,7 @@ class Stream:
59
  self.codecs: List[str] = [] # audio/video encoders (e.g.: vp8, mp4a)
60
  self.audio_codec = None # audio codec of the stream (e.g.: vorbis)
61
  self.video_codec = None # video codec of the stream (e.g.: vp8)
 
62
 
63
  # Iterates over the key/values of stream and sets them as class
64
  # attributes. This is an anti-pattern and should be removed.
 
59
  self.codecs: List[str] = [] # audio/video encoders (e.g.: vp8, mp4a)
60
  self.audio_codec = None # audio codec of the stream (e.g.: vorbis)
61
  self.video_codec = None # video codec of the stream (e.g.: vp8)
62
+ self.is_dash: Optional[bool] = None
63
 
64
  # Iterates over the key/values of stream and sets them as class
65
  # attributes. This is an anti-pattern and should be removed.
tests/contrib/test_playlist.py CHANGED
@@ -14,3 +14,15 @@ def test_title(request_get):
14
  pl = Playlist(url)
15
  pl_title = pl.title()
16
  assert pl_title == "(149) Python Tutorial for Beginners (For Absolute Beginners)"
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  pl = Playlist(url)
15
  pl_title = pl.title()
16
  assert pl_title == "(149) Python Tutorial for Beginners (For Absolute Beginners)"
17
+
18
+
19
+ def test_init_with_playlist_url():
20
+ url = "https://www.youtube.com/playlist?list=PLynhp4cZEpTbRs_PYISQ8v_uwO0_mDg_X"
21
+ playlist = Playlist(url)
22
+ assert playlist.playlist_url == url
23
+
24
+
25
+ def test_init_with_watch_url():
26
+ url = "https://www.youtube.com/watch?v=1KeYzjILqDo&list=PLynhp4cZEpTbRs_PYISQ8v_uwO0_mDg_X&index=2&t=661s"
27
+ playlist = Playlist(url)
28
+ assert playlist.playlist_url == "https://www.youtube.com/playlist?list=PLynhp4cZEpTbRs_PYISQ8v_uwO0_mDg_X"
tests/test_query.py CHANGED
@@ -137,3 +137,11 @@ def test_get_by_itag(cipher_signature):
137
 
138
  def test_get_by_non_existent_itag(cipher_signature):
139
  assert not cipher_signature.streams.get_by_itag(22983)
 
 
 
 
 
 
 
 
 
137
 
138
  def test_get_by_non_existent_itag(cipher_signature):
139
  assert not cipher_signature.streams.get_by_itag(22983)
140
+
141
+
142
+ def test_get_by_resolution(cipher_signature):
143
+ assert cipher_signature.streams.get_by_resolution("360p").itag == 18
144
+
145
+
146
+ def test_get_lowest_resolution(cipher_signature):
147
+ assert cipher_signature.streams.get_lowest_resolution().itag == 18