Taylor Fox Dahlin commited on
Commit
685331f
·
unverified ·
1 Parent(s): 3601142

Improvement/docs (#924)

Browse files

* Moved most of the documentation out of the README and into the readthedocs.

* Created additional documentation in readthedocs.

* Moved bumpversion and twine from packages to dev-packages.

* Updated contributor solicitation to be more general

* Capitalization consistency in Features section

* Added prerequisite of python 3.6+ to documentation.

* Removed travis CI build widget since we're using github actions instead.

* Slight rearrangement of the README to improve flow.

* General cleaning of documentation.

Pipfile CHANGED
@@ -4,10 +4,10 @@ verify_ssl = true
4
  name = "pypi"
5
 
6
  [packages]
7
- bumpversion = "*"
8
- twine = "*"
9
 
10
  [dev-packages]
 
 
11
  black = "==19.10b0"
12
  codecov = "*"
13
  coveralls = "*"
 
4
  name = "pypi"
5
 
6
  [packages]
 
 
7
 
8
  [dev-packages]
9
+ bumpversion = "*"
10
+ twine = "*"
11
  black = "==19.10b0"
12
  codecov = "*"
13
  coveralls = "*"
README.md CHANGED
@@ -4,23 +4,73 @@
4
  </p>
5
  <p align="center">
6
  <img src="https://img.shields.io/pypi/v/pytube.svg" alt="pypi">
7
- <a href="https://travis-ci.org/nficano/pytube"><img src="https://travis-ci.org/nficano/pytube.svg?branch=master" /></a>
8
- <a href="http://python-pytube.readthedocs.io/en/latest/?badge=latest"><img src="https://readthedocs.org/projects/python-pytube/badge/?version=latest" /></a>
9
- <a href="https://codecov.io/gh/nficano/pytube"><img src="https://codecov.io/gh/nficano/pytube/branch/master/graph/badge.svg" /></a>
10
- <a href="https://pypi.org/project/pytube/"><img src="https://img.shields.io/pypi/dm/pytube.svg" alt="pypi"></a>
11
- <a href="https://pypi.python.org/pypi/pytube/"><img src="https://img.shields.io/pypi/pyversions/pytube.svg" /></a>
12
- <p>
 
 
 
 
 
 
13
  </p>
14
  </div>
15
 
16
 
17
- ### 24 July 2020 Actively soliciting contributers!
18
- Ping @ronncc if you would like to help out!
 
19
 
20
  # pytube
21
- *pytube* is a very serious, lightweight, dependency-free Python library (and command-line utility) for downloading YouTube Videos.
 
22
 
23
- ## Installation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  To install from pypi with pip:
26
 
@@ -28,24 +78,20 @@ To install from pypi with pip:
28
  $ python -m pip install pytube
29
  ```
30
 
31
- Sometime, the pypi release becomes slightly outdated. To install from the source with pip:
 
32
 
33
  ```bash
34
  $ python -m pip install git+https://github.com/pytube/pytube
35
  ```
36
 
37
- ## Description
38
- YouTube is the most popular video-sharing platform in the world and as a hacker you may encounter a situation where you want to script something to download videos. For this I present to you *pytube*.
39
-
40
- *pytube* is a lightweight library written in Python. It has no third party dependencies and aims to be highly reliable.
41
-
42
- *pytube* also makes pipelining easy, allowing you to specify callback functions for different download events, such as ``on progress`` or ``on complete``.
43
-
44
- Finally *pytube* also includes a command-line utility, allowing you to quickly download videos right from terminal.
45
-
46
- ### Behold, a perfect balance of simplicity versus flexibility:
47
 
48
  ```python
 
49
  >>> YouTube('https://youtu.be/2lAe1cqCOXo').streams.first().download()
50
  >>> yt = YouTube('http://youtube.com/watch?v=2lAe1cqCOXo')
51
  >>> yt.streams
@@ -56,231 +102,14 @@ Finally *pytube* also includes a command-line utility, allowing you to quickly d
56
  ... .download()
57
  ```
58
 
59
- ## Features
60
- - Support for Both Progressive & DASH Streams
61
- - Support for downloading complete playlist
62
- - Easily Register ``on_download_progress`` & ``on_download_complete`` callbacks
63
- - Command-line Interfaced Included
64
- - Caption Track Support
65
- - Outputs Caption Tracks to .srt format (SubRip Subtitle)
66
- - Ability to Capture Thumbnail URL.
67
- - Extensively Documented Source Code
68
- - No Third-Party Dependencies
69
-
70
- ## Getting started
71
-
72
- Let's begin with showing how easy it is to download a video with pytube:
73
-
74
- ```python
75
- >>> from pytube import YouTube
76
- >>> YouTube('https://youtube.com/watch?v=2lAe1cqCOXo').streams.first().download()
77
- ```
78
- This example will download the highest quality progressive download stream available.
79
-
80
- Next, let's explore how we would view what video streams are available:
81
-
82
- ```python
83
- >>> yt = YouTube('https://youtube.com/watch?v=2lAe1cqCOXo')
84
- >>> yt.streams
85
- [<Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">,
86
- <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">,
87
- <Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028" progressive="False" type="video">,
88
- <Stream: itag="248" mime_type="video/webm" res="1080p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
89
- <Stream: itag="399" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.08M.08" progressive="False" type="video">,
90
- <Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d401f" progressive="False" type="video">,
91
- <Stream: itag="247" mime_type="video/webm" res="720p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
92
- <Stream: itag="398" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.05M.08" progressive="False" type="video">,
93
- <Stream: itag="135" mime_type="video/mp4" res="480p" fps="30fps" vcodec="avc1.4d401e" progressive="False" type="video">,
94
- <Stream: itag="244" mime_type="video/webm" res="480p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
95
- <Stream: itag="397" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.04M.08" progressive="False" type="video">,
96
- <Stream: itag="134" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.4d401e" progressive="False" type="video">,
97
- <Stream: itag="243" mime_type="video/webm" res="360p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
98
- <Stream: itag="396" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.01M.08" progressive="False" type="video">,
99
- <Stream: itag="133" mime_type="video/mp4" res="240p" fps="30fps" vcodec="avc1.4d4015" progressive="False" type="video">,
100
- <Stream: itag="242" mime_type="video/webm" res="240p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
101
- <Stream: itag="395" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.00M.08" progressive="False" type="video">,
102
- <Stream: itag="160" mime_type="video/mp4" res="144p" fps="30fps" vcodec="avc1.4d400c" progressive="False" type="video">,
103
- <Stream: itag="278" mime_type="video/webm" res="144p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
104
- <Stream: itag="394" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.00M.08" progressive="False" type="video">,
105
- <Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2" progressive="False" type="audio">,
106
- <Stream: itag="249" mime_type="audio/webm" abr="50kbps" acodec="opus" progressive="False" type="audio">,
107
- <Stream: itag="250" mime_type="audio/webm" abr="70kbps" acodec="opus" progressive="False" type="audio">,
108
- <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus" progressive="False" type="audio">]
109
- ```
110
- You may notice that some streams listed have both a video codec and audio codec, while others have just video or just audio, this is a result of YouTube supporting a streaming technique called Dynamic Adaptive Streaming over HTTP (DASH).
111
-
112
- In the context of pytube, the implications are for the highest quality streams; you now need to download both the audio and video tracks and then post-process them with software like FFmpeg to merge them.
113
-
114
- The legacy streams that contain the audio and video in a single file (referred to as "progressive download") are still available, but only for resolutions 720p and below.
115
-
116
- To only view these progressive download streams:
117
-
118
- ```python
119
- >>> yt.streams.filter(progressive=True)
120
- [<Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">,
121
- <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">]
122
- ```
123
-
124
- Conversely, if you only want to see the DASH streams (also referred to as "adaptive") you can do:
125
-
126
- ```python
127
- >>> yt.streams.filter(adaptive=True)
128
- [<Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028" progressive="False" type="video">,
129
- <Stream: itag="248" mime_type="video/webm" res="1080p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
130
- <Stream: itag="399" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.08M.08" progressive="False" type="video">,
131
- <Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d401f" progressive="False" type="video">,
132
- <Stream: itag="247" mime_type="video/webm" res="720p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
133
- <Stream: itag="398" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.05M.08" progressive="False" type="video">,
134
- <Stream: itag="135" mime_type="video/mp4" res="480p" fps="30fps" vcodec="avc1.4d401e" progressive="False" type="video">,
135
- <Stream: itag="244" mime_type="video/webm" res="480p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
136
- <Stream: itag="397" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.04M.08" progressive="False" type="video">,
137
- <Stream: itag="134" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.4d401e" progressive="False" type="video">,
138
- <Stream: itag="243" mime_type="video/webm" res="360p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
139
- <Stream: itag="396" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.01M.08" progressive="False" type="video">,
140
- <Stream: itag="133" mime_type="video/mp4" res="240p" fps="30fps" vcodec="avc1.4d4015" progressive="False" type="video">,
141
- <Stream: itag="242" mime_type="video/webm" res="240p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
142
- <Stream: itag="395" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.00M.08" progressive="False" type="video">,
143
- <Stream: itag="160" mime_type="video/mp4" res="144p" fps="30fps" vcodec="avc1.4d400c" progressive="False" type="video">,
144
- <Stream: itag="278" mime_type="video/webm" res="144p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
145
- <Stream: itag="394" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.00M.08" progressive="False" type="video">,
146
- <Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2" progressive="False" type="audio">,
147
- <Stream: itag="249" mime_type="audio/webm" abr="50kbps" acodec="opus" progressive="False" type="audio">,
148
- <Stream: itag="250" mime_type="audio/webm" abr="70kbps" acodec="opus" progressive="False" type="audio">,
149
- <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus" progressive="False" type="audio">]
150
- ```
151
-
152
- You can also interact with Youtube playlists:
153
-
154
- ```python
155
- >>> from pytube import Playlist
156
- >>> pl = Playlist("https://www.youtube.com/watch?v=Edpy1szoG80&list=PL153hDY-y1E00uQtCVCVC8xJ25TYX8yPU")
157
- >>> for video in pl.videos:
158
- >>> video.streams.first().download()
159
- ```
160
-
161
- Pytube allows you to filter on every property available (see the documentation for the complete list), let's take a look at some of the most useful ones.
162
-
163
- To list the audio only streams:
164
-
165
- ```python
166
- >>> yt.streams.filter(only_audio=True)
167
- [<Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2" progressive="False" type="audio">,
168
- <Stream: itag="249" mime_type="audio/webm" abr="50kbps" acodec="opus" progressive="False" type="audio">,
169
- <Stream: itag="250" mime_type="audio/webm" abr="70kbps" acodec="opus" progressive="False" type="audio">,
170
- <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus" progressive="False" type="audio">]
171
- ```
172
-
173
- To list only ``mp4`` streams:
174
-
175
- ```python
176
- >>> yt.streams.filter(subtype='mp4').all()
177
- [<Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">,
178
- <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">,
179
- <Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028" progressive="False" type="video">,
180
- <Stream: itag="399" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.08M.08" progressive="False" type="video">,
181
- <Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d401f" progressive="False" type="video">,
182
- <Stream: itag="398" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.05M.08" progressive="False" type="video">,
183
- <Stream: itag="135" mime_type="video/mp4" res="480p" fps="30fps" vcodec="avc1.4d401e" progressive="False" type="video">,
184
- <Stream: itag="397" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.04M.08" progressive="False" type="video">,
185
- <Stream: itag="134" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.4d401e" progressive="False" type="video">,
186
- <Stream: itag="396" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.01M.08" progressive="False" type="video">,
187
- <Stream: itag="133" mime_type="video/mp4" res="240p" fps="30fps" vcodec="avc1.4d4015" progressive="False" type="video">,
188
- <Stream: itag="395" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.00M.08" progressive="False" type="video">,
189
- <Stream: itag="160" mime_type="video/mp4" res="144p" fps="30fps" vcodec="avc1.4d400c" progressive="False" type="video">,
190
- <Stream: itag="394" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.00M.08" progressive="False" type="video">,
191
- <Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2" progressive="False" type="audio">]
192
- ```
193
-
194
- Multiple filters can also be specified:
195
-
196
- ```python
197
- >>> yt.streams.filter(subtype='mp4', progressive=True).all()
198
- >>> # this can also be expressed as:
199
- >>> yt.streams.filter(subtype='mp4').filter(progressive=True).all()
200
- [<Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">,
201
- <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">]
202
- ```
203
- You also have an interface to select streams by their itag, without needing to filter:
204
-
205
- ```python
206
- >>> yt.streams.get_by_itag(22)
207
- <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">
208
- ```
209
-
210
- If you need to optimize for a specific feature, such as the "highest resolution" or "lowest average bitrate":
211
-
212
- ```python
213
- >>> yt.streams.filter(progressive=True).order_by('resolution').desc().all()
214
- [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">,
215
- <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">]
216
- ```
217
- Note that ``order_by`` cannot be used if your attribute is undefined in any of the Stream instances, so be sure to apply a filter to remove those before calling it.
218
-
219
- If your application requires post-processing logic, pytube allows you to specify an "on download complete" callback function:
220
-
221
- ```python
222
- >>> def convert_to_aac(stream, file_handle):
223
- return # do work
224
-
225
- >>> yt.register_on_complete_callback(convert_to_aac)
226
- ```
227
-
228
- Similarly, if your application requires on-download progress logic, pytube exposes a callback for this as well:
229
-
230
- ```python
231
- >>> def show_progress_bar(stream, chunk, bytes_remaining):
232
- return # do work
233
-
234
- >>> yt.register_on_progress_callback(show_progress_bar)
235
- ```
236
-
237
- You can also download videos to a specific directory with specific filename:
238
-
239
- ```python
240
- >>> yt = YouTube('https://youtube.com/watch?v=2lAe1cqCOXo')
241
- >>> yt.streams.first().download(output_path="/tmp" ,filename='output')
242
- ```
243
-
244
- ## Command-line interface (CLI)
245
-
246
- Pytube also ships with a tiny CLI for interacting with videos and playlists.
247
-
248
- To download the highest resolution progressive stream:
249
-
250
- ```bash
251
- $ pytube https://www.youtube.com/watch?v=2lAe1cqCOXo
252
- ```
253
-
254
- To view available streams:
255
-
256
- ```bash
257
- $ pytube https://www.youtube.com/watch?v=2lAe1cqCOXo --list
258
- ```
259
-
260
- To download a specific stream, use the itag
261
-
262
- ```bash
263
- $ pytube https://www.youtube.com/watch?v=2lAe1cqCOXo --itag=22
264
- ```
265
-
266
- To get a list of all subtitles (caption codes)
267
-
268
- ```bash
269
- $ pytube https://www.youtube.com/watch?v=2lAe1cqCOXo --list-captions
270
- ```
271
-
272
- To download a specific subtitle (caption code) - in this case the
273
- english subtitles (in srt format) - use:
274
-
275
  ```bash
276
- $ pytube https://www.youtube.com/watch?v=2lAe1cqCOXo -c en
277
  ```
278
 
279
- It is also possible to just download the audio stream (default AAC/mp4):
280
-
281
  ```bash
282
- $ pytube https://www.youtube.com/watch?v=2lAe1cqCOXo -a
283
  ```
284
-
285
-
286
- Finally, if you're filing a bug report, the cli contains a switch called ``--build-playback-report``, which bundles up the state, allowing others to easily replay your issue.
 
4
  </p>
5
  <p align="center">
6
  <img src="https://img.shields.io/pypi/v/pytube.svg" alt="pypi">
7
+ <a href="http://python-pytube.readthedocs.io/en/latest/?badge=latest">
8
+ <img src="https://readthedocs.org/projects/python-pytube/badge/?version=latest" />
9
+ </a>
10
+ <a href="https://codecov.io/gh/nficano/pytube">
11
+ <img src="https://codecov.io/gh/nficano/pytube/branch/master/graph/badge.svg" />
12
+ </a>
13
+ <a href="https://pypi.org/project/pytube/">
14
+ <img src="https://img.shields.io/pypi/dm/pytube.svg" alt="pypi">
15
+ </a>
16
+ <a href="https://pypi.python.org/pypi/pytube/">
17
+ <img src="https://img.shields.io/pypi/pyversions/pytube.svg" />
18
+ </a>
19
  </p>
20
  </div>
21
 
22
 
23
+ ### Actively soliciting contributers!
24
+ Have ideas for how pytube can be improved? Feel free to open an issue or a pull
25
+ request!
26
 
27
  # pytube
28
+ *pytube* is a very serious, lightweight, dependency-free Python library (and
29
+ command-line utility) for downloading YouTube Videos.
30
 
31
+
32
+ ## Documentation
33
+ Detailed documentation about how to use the library can be found on our
34
+ [readthedocs](https://python-pytube.readthedocs.io) page. This is recommended
35
+ for most use cases. If you just want to quickly download a single video,
36
+ the [quickstart](#Quickstart) guide below might be what you're looking for.
37
+
38
+
39
+ ## Description
40
+ YouTube is the most popular video-sharing platform in the world and as a hacker
41
+ you may encounter a situation where you want to script something to download
42
+ videos. For this I present to you *pytube*.
43
+
44
+ *pytube* is a lightweight library written in Python. It has no third party
45
+ dependencies and aims to be highly reliable.
46
+
47
+ *pytube* also makes pipelining easy, allowing you to specify callback functions
48
+ for different download events, such as ``on progress`` or ``on complete``.
49
+
50
+ Finally *pytube* also includes a command-line utility, allowing you to quickly
51
+ download videos right from terminal.
52
+
53
+
54
+ ## Features
55
+ - Support for both progressive & DASH streams
56
+ - Support for downloading complete playlist
57
+ - Easily register ``on_download_progress`` & ``on_download_complete`` callbacks
58
+ - Command-line interfaced included
59
+ - Caption track support
60
+ - Outputs caption tracks to .srt format (SubRip Subtitle)
61
+ - Ability to capture thumbnail URL
62
+ - Extensively documented source code
63
+ - No third-party dependencies
64
+
65
+ ## Quickstart
66
+ This guide is only meant to cover the most basic usage of the library. For more
67
+ detailed information, please refer to our
68
+ [readthedocs](https://python-pytube.readthedocs.io) page.
69
+
70
+ ### Installation
71
+ Pytube requires an installation of python 3.6 or greater, as well as pip.
72
+ Pip is typically bundled with python installations, and you can find options
73
+ for how to install python at https://python.org.
74
 
75
  To install from pypi with pip:
76
 
 
78
  $ python -m pip install pytube
79
  ```
80
 
81
+ Sometime, the pypi release becomes slightly outdated. To install from the
82
+ source with pip:
83
 
84
  ```bash
85
  $ python -m pip install git+https://github.com/pytube/pytube
86
  ```
87
 
88
+ ### Using pytube in a python script
89
+ To download a video using the library in a script, you'll need to first import
90
+ the YouTube class from the library, and pass it an argument of the video url.
91
+ From there, you can access the streams and download them.
 
 
 
 
 
 
92
 
93
  ```python
94
+ >>> from pytube import YouTube
95
  >>> YouTube('https://youtu.be/2lAe1cqCOXo').streams.first().download()
96
  >>> yt = YouTube('http://youtube.com/watch?v=2lAe1cqCOXo')
97
  >>> yt.streams
 
102
  ... .download()
103
  ```
104
 
105
+ ### Using the command-line interface
106
+ Using the CLI is extremely straightforward as well. To download a video at the
107
+ highest progressive quality, you can use the following command:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  ```bash
109
+ $ pytube https://youtube.com/watch?v=2lAe1cqCOXo
110
  ```
111
 
112
+ You can also do the same for a playlist:
 
113
  ```bash
114
+ $ pytube https://www.youtube.com/playlist?list=PLS1QulWo1RIaJECMeUT4LFwJ-ghgoSH6n
115
  ```
 
 
 
docs/index.rst CHANGED
@@ -20,7 +20,8 @@ Release v\ |version|. (:ref:`Installation<install>`)
20
  :alt: Python Versions
21
  :target: https://pypi.python.org/pypi/pytube/
22
 
23
- **pytube** is a lightweight, Pythonic, dependency-free, library (and command-line utility) for downloading YouTube Videos.
 
24
 
25
  -------------------
26
 
@@ -48,28 +49,28 @@ Features
48
  - Extensively Documented Source Code
49
  - No Third-Party Dependencies
50
 
51
- Roadmap
52
- -------
53
-
54
- - Allow downloading age restricted content
55
- - Complete ffmpeg integration
56
-
57
  The User Guide
58
  --------------
59
- This part of the documentation begins with some background information about the project, then focuses on step-by-step instructions for getting the most out of pytube.
 
 
60
 
61
  .. toctree::
62
  :maxdepth: 2
63
 
64
  user/install
65
  user/quickstart
 
 
66
  user/playlist
67
  user/cli
 
68
 
69
- The API Documentation / Guide
70
  -----------------------------
71
 
72
- If you are looking for information on a specific function, class, or method, this part of the documentation is for you.
 
73
 
74
  .. toctree::
75
  :maxdepth: 2
 
20
  :alt: Python Versions
21
  :target: https://pypi.python.org/pypi/pytube/
22
 
23
+ **pytube** is a lightweight, Pythonic, dependency-free, library (and
24
+ command-line utility) for downloading YouTube Videos.
25
 
26
  -------------------
27
 
 
49
  - Extensively Documented Source Code
50
  - No Third-Party Dependencies
51
 
 
 
 
 
 
 
52
  The User Guide
53
  --------------
54
+ This part of the documentation begins with some background information about
55
+ the project, then focuses on step-by-step instructions for getting the most out
56
+ of pytube.
57
 
58
  .. toctree::
59
  :maxdepth: 2
60
 
61
  user/install
62
  user/quickstart
63
+ user/streams
64
+ user/captions
65
  user/playlist
66
  user/cli
67
+ user/exceptions
68
 
69
+ The API Documentation
70
  -----------------------------
71
 
72
+ If you are looking for information on a specific function, class, or method,
73
+ this part of the documentation is for you.
74
 
75
  .. toctree::
76
  :maxdepth: 2
docs/user/captions.rst ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .. _captions:
2
+
3
+ Subtitle/Caption Tracks
4
+ =======================
5
+
6
+ Pytube exposes the caption tracks in much the same way as querying the media
7
+ streams. Let's begin by switching to a video that contains them::
8
+
9
+ >>> yt = YouTube('http://youtube.com/watch?v=2lAe1cqCOXo')
10
+ >>> yt.captions
11
+ {'ar': <Caption lang="Arabic" code="ar">, 'zh-HK': <Caption lang="Chinese (Hong Kong)" code="zh-HK">, 'zh-TW': <Caption lang="Chinese (Taiwan)" code="zh-TW">, 'hr': <Caption lang="Croatian" code="hr">, 'cs': <Caption lang="Czech" code="cs">, 'da': <Caption lang="Danish" code="da">, 'nl': <Caption lang="Dutch" code="nl">, 'en': <Caption lang="English" code="en">, 'en-GB': <Caption lang="English (United Kingdom)" code="en-GB">, 'et': <Caption lang="Estonian" code="et">, 'fil': <Caption lang="Filipino" code="fil">, 'fi': <Caption lang="Finnish" code="fi">, 'fr-CA': <Caption lang="French (Canada)" code="fr-CA">, 'fr-FR': <Caption lang="French (France)" code="fr-FR">, 'de': <Caption lang="German" code="de">, 'el': <Caption lang="Greek" code="el">, 'iw': <Caption lang="Hebrew" code="iw">, 'hu': <Caption lang="Hungarian" code="hu">, 'id': <Caption lang="Indonesian" code="id">, 'it': <Caption lang="Italian" code="it">, 'ja': <Caption lang="Japanese" code="ja">, 'ko': <Caption lang="Korean" code="ko">, 'lv': <Caption lang="Latvian" code="lv">, 'lt': <Caption lang="Lithuanian" code="lt">, 'ms': <Caption lang="Malay" code="ms">, 'no': <Caption lang="Norwegian" code="no">, 'pl': <Caption lang="Polish" code="pl">, 'pt-BR': <Caption lang="Portuguese (Brazil)" code="pt-BR">, 'pt-PT': <Caption lang="Portuguese (Portugal)" code="pt-PT">, 'ro': <Caption lang="Romanian" code="ro">, 'ru': <Caption lang="Russian" code="ru">, 'sk': <Caption lang="Slovak" code="sk">, 'es-419': <Caption lang="Spanish (Latin America)" code="es-419">, 'es-ES': <Caption lang="Spanish (Spain)" code="es-ES">, 'sv': <Caption lang="Swedish" code="sv">, 'th': <Caption lang="Thai" code="th">, 'tr': <Caption lang="Turkish" code="tr">, 'uk': <Caption lang="Ukrainian" code="uk">, 'ur': <Caption lang="Urdu" code="ur">, 'vi': <Caption lang="Vietnamese" code="vi">}
12
+
13
+ Now let's checkout the english captions::
14
+
15
+ >>> caption = yt.captions.get_by_language_code('en')
16
+
17
+ Great, now let's see how YouTube formats them::
18
+
19
+ >>> caption.xml_captions
20
+ '<?xml version="1.0" encoding="utf-8" ?><transcript><text start="10.2" dur="0.94">K-pop!</text>...'
21
+
22
+ Oh, this isn't very easy to work with, let's convert them to the srt format::
23
+
24
+ >>> print(caption.generate_srt_captions())
25
+ 1
26
+ 00:00:10,200 --> 00:00:11,140
27
+ K-pop!
28
+
29
+ 2
30
+ 00:00:13,400 --> 00:00:16,200
31
+ That is so awkward to watch.
32
+ ...
docs/user/cli.rst CHANGED
@@ -30,7 +30,7 @@ To get a list of all subtitles (caption codes)
30
  $ pytube https://www.youtube.com/watch?v=2lAe1cqCOXo --list-captions
31
 
32
  To download a specific subtitle (caption code) - in this case the
33
- english subtitles (in srt format) - use:
34
 
35
  .. code:: bash
36
 
 
30
  $ pytube https://www.youtube.com/watch?v=2lAe1cqCOXo --list-captions
31
 
32
  To download a specific subtitle (caption code) - in this case the
33
+ English subtitles (in srt format) - use:
34
 
35
  .. code:: bash
36
 
docs/user/exceptions.rst ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .. _exceptions:
2
+
3
+ Exception handling
4
+ ==================
5
+
6
+ Pytube implements a number of useful exceptions for handling program flow.
7
+ There are a number of cases where pytube simply cannot access videos on YouTube
8
+ and relies on the user to handle these exceptions. Generally speaking, if a
9
+ video is unaccessible for any reason, this can be caught with the generic
10
+ VideoUnavailable exception. This could be used, for example, to skip private
11
+ videos in a playlist, videos that are region-restricted, and more.
12
+
13
+ Let's see what your code might look like if you need to do exception handling::
14
+
15
+ >>> from pytube import Playlist, YouTube
16
+ >>> playlist_url = 'https://youtube.com/playlist?list=special_playlist_id'
17
+ >>> p = Playlist(playlist_url)
18
+ >>> for url in p.video_urls:
19
+ ... try:
20
+ ... yt = YouTube(url)
21
+ ... except VideoUnavailable:
22
+ ... print(f'Video {url} is unavaialable, skipping.')
23
+ ... else:
24
+ ... print(f'Downloading video: {url}')
25
+ ... yt.streams.first().download()
26
+
27
+ This will automatically skip over videos that could not be downloaded due to a
28
+ limitation with the pytube library. You can find more details about what
29
+ specific exceptions can be handled here: :py:mod:`pytube.exceptions`.
docs/user/install.rst CHANGED
@@ -3,7 +3,7 @@
3
  Installation of pytube
4
  ======================
5
 
6
- This part of the documentation covers the installation of pytube.
7
 
8
  To install pytube, run the following command in your terminal::
9
 
@@ -12,18 +12,18 @@ To install pytube, run the following command in your terminal::
12
  Get the Source Code
13
  -------------------
14
 
15
- pytube is actively developed on GitHub, where the source is `available <https://github.com/nficano/pytube>`_.
16
 
17
  You can either clone the public repository::
18
 
19
- $ git clone git://github.com/nficano/pytube.git
20
 
21
- Or, download the `tarball <https://github.com/nficano/pytube/tarball/master>`_::
22
 
23
- $ curl -OL https://github.com/nficano/pytube/tarball/master
24
  # optionally, zipball is also available (for Windows users).
25
 
26
  Once you have a copy of the source, you can embed it in your Python package, or install it into your site-packages by running::
27
 
28
  $ cd pytube
29
- $ pip install .
 
3
  Installation of pytube
4
  ======================
5
 
6
+ This guide assumes you already have python and pip installed.
7
 
8
  To install pytube, run the following command in your terminal::
9
 
 
12
  Get the Source Code
13
  -------------------
14
 
15
+ pytube is actively developed on GitHub, where the source is `available <https://github.com/pytube/pytube>`_.
16
 
17
  You can either clone the public repository::
18
 
19
+ $ git clone git://github.com/pytube/pytube.git
20
 
21
+ Or, download the `tarball <https://github.com/pytube/pytube/tarball/master>`_::
22
 
23
+ $ curl -OL https://github.com/pytube/pytube/tarball/master
24
  # optionally, zipball is also available (for Windows users).
25
 
26
  Once you have a copy of the source, you can embed it in your Python package, or install it into your site-packages by running::
27
 
28
  $ cd pytube
29
+ $ python -m pip install .
docs/user/quickstart.rst CHANGED
@@ -17,9 +17,9 @@ Begin by importing the YouTube class::
17
  >>> from pytube import YouTube
18
 
19
  Now, let's try to download a video. For this example, let's take something
20
- popular like PSY - Gangnam Style::
21
 
22
- >>> yt = YouTube('https://www.youtube.com/watch?v=9bZkp7q19f0')
23
 
24
  Now, we have a :class:`YouTube <pytube.YouTube>` object called ``yt``.
25
 
@@ -27,182 +27,35 @@ The pytube API makes all information intuitive to access. For example, this is
27
  how you would get the video's title::
28
 
29
  >>> yt.title
30
- PSY - GANGNAM STYLE(강남스타일) M/V
31
 
32
  And this would be how you would get the thumbnail url::
33
 
34
  >>> yt.thumbnail_url
35
- 'https://i.ytimg.com/vi/mTOYClXhJD0/default.jpg'
36
-
37
- Neat, right? Next let's see the available media formats::
38
-
39
- >>> yt.streams.all()
40
- [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
41
- <Stream: itag="43" mime_type="video/webm" res="360p" fps="30fps" vcodec="vp8.0" acodec="vorbis">,
42
- <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">,
43
- <Stream: itag="36" mime_type="video/3gpp" res="240p" fps="30fps" vcodec="mp4v.20.3" acodec="mp4a.40.2">,
44
- <Stream: itag="17" mime_type="video/3gpp" res="144p" fps="30fps" vcodec="mp4v.20.3" acodec="mp4a.40.2">,
45
- <Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028">,
46
- <Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d401f">,
47
- <Stream: itag="135" mime_type="video/mp4" res="480p" fps="30fps" vcodec="avc1.4d401f">,
48
- <Stream: itag="134" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.4d401e">,
49
- <Stream: itag="133" mime_type="video/mp4" res="240p" fps="30fps" vcodec="avc1.4d4015">,
50
- <Stream: itag="160" mime_type="video/mp4" res="144p" fps="30fps" vcodec="avc1.4d400c">,
51
- <Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2">,
52
- <Stream: itag="171" mime_type="audio/webm" abr="128kbps" acodec="vorbis">]
53
 
54
- Let's say we want to get the first stream::
55
-
56
- >>> stream = yt.streams.first()
57
- >>> stream
58
- <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">
59
-
60
- And to download it to the current working directory::
61
-
62
- >>> stream.download()
63
-
64
- You can also specify a destination path::
65
-
66
- >>> stream.download('/tmp')
67
-
68
-
69
- Working with Streams
70
- ====================
71
-
72
- The next section will explore the various options available for working with media
73
- streams, but before we can dive in, we need to review a new-ish streaming technique
74
- adopted by YouTube.
75
-
76
- DASH vs Progressive Streams
77
- ---------------------------
78
-
79
- Begin by running the following::
80
-
81
- >>> yt.streams.all()
82
- [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
83
- <Stream: itag="43" mime_type="video/webm" res="360p" fps="30fps" vcodec="vp8.0" acodec="vorbis">,
84
- <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">,
85
- <Stream: itag="36" mime_type="video/3gpp" res="240p" fps="30fps" vcodec="mp4v.20.3" acodec="mp4a.40.2">,
86
- <Stream: itag="17" mime_type="video/3gpp" res="144p" fps="30fps" vcodec="mp4v.20.3" acodec="mp4a.40.2">,
87
- <Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028">,
88
- <Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d401f">,
89
- <Stream: itag="135" mime_type="video/mp4" res="480p" fps="30fps" vcodec="avc1.4d401f">,
90
- <Stream: itag="134" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.4d401e">,
91
- <Stream: itag="133" mime_type="video/mp4" res="240p" fps="30fps" vcodec="avc1.4d4015">,
92
- <Stream: itag="160" mime_type="video/mp4" res="144p" fps="30fps" vcodec="avc1.4d400c">,
93
- <Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2">,
94
- <Stream: itag="171" mime_type="audio/webm" abr="128kbps" acodec="vorbis">]
95
-
96
-
97
- You may notice that some streams listed have both a video codec and audio
98
- codec, while others have just video or just audio, this is a result of YouTube
99
- supporting a streaming technique called Dynamic Adaptive Streaming over HTTP
100
- (DASH).
101
-
102
- In the context of pytube, the implications are for the highest quality streams;
103
- you now need to download both the audio and video tracks and then post-process
104
- them with software like FFmpeg to merge them.
105
-
106
- The legacy streams that contain the audio and video in a single file (referred
107
- to as "progressive download") are still available, but only for resolutions
108
- 720p and below.
109
-
110
- To only view these progressive download streams::
111
-
112
- >>> yt.streams.filter(progressive=True).all()
113
- [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
114
- <Stream: itag="43" mime_type="video/webm" res="360p" fps="30fps" vcodec="vp8.0" acodec="vorbis">,
115
- <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">,
116
- <Stream: itag="36" mime_type="video/3gpp" res="240p" fps="30fps" vcodec="mp4v.20.3" acodec="mp4a.40.2">,
117
- <Stream: itag="17" mime_type="video/3gpp" res="144p" fps="30fps" vcodec="mp4v.20.3" acodec="mp4a.40.2">]
118
-
119
- Conversely, if you only want to see the DASH streams (also referred to as
120
- "adaptive") you can do::
121
-
122
- >>> yt.streams.filter(adaptive=True).all()
123
- [<Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028">,
124
- <Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d401f">,
125
- <Stream: itag="135" mime_type="video/mp4" res="480p" fps="30fps" vcodec="avc1.4d401f">,
126
- <Stream: itag="134" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.4d401e">,
127
- <Stream: itag="133" mime_type="video/mp4" res="240p" fps="30fps" vcodec="avc1.4d4015">,
128
- <Stream: itag="160" mime_type="video/mp4" res="144p" fps="30fps" vcodec="avc1.4d400c">,
129
- <Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2">,
130
- <Stream: itag="171" mime_type="audio/webm" abr="128kbps" acodec="vorbis">]
131
-
132
- Pytube allows you to filter on every property available (see
133
- :py:meth:`pytube.StreamQuery.filter` for a complete list of filter options),
134
- let's take a look at some common examples:
135
-
136
- Query audio only Streams
137
- ------------------------
138
-
139
- To query the streams that contain only the audio track::
140
-
141
- >>> yt.streams.filter(only_audio=True).all()
142
- [<Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2">,
143
- <Stream: itag="171" mime_type="audio/webm" abr="128kbps" acodec="vorbis">]
144
-
145
- Query MPEG-4 Streams
146
- --------------------
147
 
148
- To query only streams in the MPEG-4 format::
 
 
 
 
 
149
 
150
- >>> yt.streams.filter(file_extension='mp4').all()
151
- [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
152
- <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">,
153
- <Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028">,
154
- <Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d401f">,
155
- <Stream: itag="135" mime_type="video/mp4" res="480p" fps="30fps" vcodec="avc1.4d401f">,
156
- <Stream: itag="134" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.4d401e">,
157
- <Stream: itag="133" mime_type="video/mp4" res="240p" fps="30fps" vcodec="avc1.4d4015">,
158
- <Stream: itag="160" mime_type="video/mp4" res="144p" fps="30fps" vcodec="avc1.4d400c">,
159
- <Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2">]
160
 
161
- Get Streams by itag
162
- -------------------
163
-
164
- To get a stream by a specific itag::
165
-
166
- >>> yt.streams.get_by_itag('22')
167
- <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">
168
-
169
- Subtitle/Caption Tracks
170
- =======================
171
-
172
- Pytube exposes the caption tracks in much the same way as querying the media
173
- streams. Let's begin by switching to a video that contains them::
174
-
175
- >>> yt = YouTube('https://youtube.com/watch?v=XJGiS83eQLk')
176
- >>> yt.captions.all()
177
- [<Caption lang="Arabic" code="ar">,
178
- <Caption lang="English (auto-generated)" code="en">,
179
- <Caption lang="English" code="en">,
180
- <Caption lang="English (United Kingdom)" code="en-GB">,
181
- <Caption lang="German" code="de">,
182
- <Caption lang="Greek" code="el">,
183
- <Caption lang="Indonesian" code="id">,
184
- <Caption lang="Sinhala" code="si">,
185
- <Caption lang="Spanish" code="es">,
186
- <Caption lang="Turkish" code="tr">]
187
-
188
- Now let's checkout the english captions::
189
-
190
- >>> caption = yt.captions.get_by_language_code('en')
191
-
192
- Great, now let's see how YouTube formats them::
193
-
194
- >>> caption.xml_captions
195
- '<?xml version="1.0" encoding="utf-8" ?><transcript><text start="0" dur="5.541">well i&amp;#39...'
196
-
197
- Oh, this isn't very easy to work with, let's convert them to the srt format::
198
-
199
- >>> print(caption.generate_srt_captions())
200
- 1
201
- 000:000:00,000 --> 000:000:05,541
202
- well i'm just an editor and i dont know what to type
203
 
204
- 2
205
- 000:000:05,541 --> 000:000:12,321
206
- not new to video. In fact, most films before 1930 were silent and used captions with video
 
207
 
208
- ...
 
 
17
  >>> from pytube import YouTube
18
 
19
  Now, let's try to download a video. For this example, let's take something
20
+ like the YouTube Rewind video for 2019::
21
 
22
+ >>> yt = YouTube('http://youtube.com/watch?v=2lAe1cqCOXo')
23
 
24
  Now, we have a :class:`YouTube <pytube.YouTube>` object called ``yt``.
25
 
 
27
  how you would get the video's title::
28
 
29
  >>> yt.title
30
+ YouTube Rewind 2019: For the Record | #YouTubeRewind
31
 
32
  And this would be how you would get the thumbnail url::
33
 
34
  >>> yt.thumbnail_url
35
+ 'https://i.ytimg.com/vi/2lAe1cqCOXo/maxresdefault.jpg'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
+ Neat, right? For advanced use cases, you can provide some additional arguments
38
+ when you create a YouTube object::
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ >>> yt = YouTube(
41
+ 'http://youtube.com/watch?v=2lAe1cqCOXo',
42
+ on_progress_callback=progress_func,
43
+ on_complete_callback=complete_func,
44
+ proxies=my_proxies
45
+ )
46
 
47
+ When instantiating a YouTube object, these named arguments can be passed in to
48
+ improve functionality.
 
 
 
 
 
 
 
 
49
 
50
+ The on_progress_callback function will run whenever a chunk is downloaded from
51
+ a video, and is called with three arguments: the stream, the data chunk, and
52
+ the bytes remaining in the video. This could be used, for example, to display a
53
+ progress bar.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
+ The on_complete_callback function will run after a video has been fully
56
+ downloaded, and is called with two arguments: the stream and the file path.
57
+ This could be used, for example, to perform post-download processing on a video
58
+ like trimming the length of it.
59
 
60
+ Once you have a YouTube object set up, you're ready to start looking at
61
+ different media streams for the video, which is discussed in the next section.
docs/user/streams.rst ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .. _streams:
2
+
3
+ Working with Streams and StreamQuery
4
+ ====================================
5
+
6
+ The next section will explore the various options available for working with
7
+ media streams, but before we can dive in, we need to review a new-ish streaming
8
+ technique adopted by YouTube. It assumes that you have already created a
9
+ YouTube object in your code called "yt".
10
+
11
+ DASH vs Progressive Streams
12
+ ---------------------------
13
+
14
+ Begin by running the following to list all streams::
15
+
16
+ >>> yt.streams
17
+ [<Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">,
18
+ <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">,
19
+ <Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028" progressive="False" type="video">,
20
+ ...
21
+ <Stream: itag="250" mime_type="audio/webm" abr="70kbps" acodec="opus" progressive="False" type="audio">,
22
+ <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus" progressive="False" type="audio">]
23
+
24
+
25
+ You may notice that some streams listed have both a video codec and audio
26
+ codec, while others have just video or just audio, this is a result of YouTube
27
+ supporting a streaming technique called Dynamic Adaptive Streaming over HTTP
28
+ (DASH).
29
+
30
+ In the context of pytube, the implications are for the highest quality streams;
31
+ you now need to download both the audio and video tracks and then post-process
32
+ them with software like FFmpeg to merge them.
33
+
34
+ The legacy streams that contain the audio and video in a single file (referred
35
+ to as "progressive download") are still available, but only for resolutions
36
+ 720p and below.
37
+
38
+ Filtering Streams
39
+ =================
40
+
41
+ Pytube has built-in functionality to filter the streams available in a YouTube
42
+ object with the .filter() method. You can pass it a number of different keyword
43
+ arguments, so let's review some of the different options you're most likely to
44
+ use. For a complete list of available properties to filter on, you can view the
45
+ API documentation here: :py:meth:`pytube.StreamQuery.filter`.
46
+
47
+ Filtering by streaming method
48
+ -----------------------------
49
+
50
+ As mentioned before, progressive streams have the video and audio in a single
51
+ file, but typically do not provide the highest quality media; meanwhile,
52
+ adaptive streams split the video and audio tracks but can provide much higher
53
+ quality. Pytube makes it easy to filter based on the type of stream that you're
54
+ interested.
55
+
56
+ For example, you can filter to only progressive streams with the following::
57
+
58
+ >>> yt.streams.filter(progressive=True)
59
+ [<Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">,
60
+ <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">]
61
+
62
+ Conversely, if you only want to see the DASH streams (also referred to as
63
+ "adaptive") you can do::
64
+
65
+ >>> yt.streams.filter(adaptive=True)
66
+ [<Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028" progressive="False" type="video">,
67
+ <Stream: itag="248" mime_type="video/webm" res="1080p" fps="30fps" vcodec="vp9" progressive="False" type="video">,
68
+ <Stream: itag="399" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.08M.08" progressive="False" type="video">,
69
+ ...
70
+ <Stream: itag="250" mime_type="audio/webm" abr="70kbps" acodec="opus" progressive="False" type="audio">,
71
+ <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus" progressive="False" type="audio">]
72
+
73
+ Filtering for audio-only streams
74
+ --------------------------------
75
+
76
+ To query the streams that contain only the audio track::
77
+
78
+ >>> yt.streams.filter(only_audio=True)
79
+ [<Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2" progressive="False" type="audio">,
80
+ <Stream: itag="249" mime_type="audio/webm" abr="50kbps" acodec="opus" progressive="False" type="audio">,
81
+ <Stream: itag="250" mime_type="audio/webm" abr="70kbps" acodec="opus" progressive="False" type="audio">,
82
+ <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus" progressive="False" type="audio">]
83
+
84
+ Filtering for MP4 streams
85
+ -------------------------
86
+
87
+ To query only streams in the MP4 format::
88
+
89
+ >>> yt.streams.filter(file_extension='mp4')
90
+ [<Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">,
91
+ <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">,
92
+ <Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028" progressive="False" type="video">,
93
+ ...
94
+ <Stream: itag="394" mime_type="video/mp4" res="None" fps="30fps" vcodec="av01.0.00M.08" progressive="False" type="video">,
95
+ <Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2" progressive="False" type="audio">]