nficano commited on
Commit
5c83b18
·
unverified ·
1 Parent(s): 8c59837

Update readme, precommit config, and makefile

Browse files
Files changed (4) hide show
  1. .pre-commit-config.yaml +50 -23
  2. Makefile +39 -33
  3. README.md +67 -137
  4. images/pytube.png +0 -0
.pre-commit-config.yaml CHANGED
@@ -1,27 +1,54 @@
1
- - repo: https://github.com/pre-commit/pre-commit-hooks
2
- sha: v0.9.5
 
3
  hooks:
4
- - id: autopep8-wrapper
5
- - id: check-ast
6
- - id: check-case-conflict
7
- - id: check-merge-conflict
8
- - id: double-quote-string-fixer
9
- - id: end-of-file-fixer
10
- - id: flake8
11
- - id: requirements-txt-fixer
12
- - id: trailing-whitespace
13
- - id: fix-encoding-pragma
14
- - id: debug-statements
15
- - repo: https://github.com/asottile/reorder_python_imports
16
- sha: v0.3.5
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  hooks:
18
- - id: reorder-python-imports
19
- language_version: python3.7
20
- - repo: https://github.com/Lucas-C/pre-commit-hooks-safety
21
- sha: v1.1.0
22
  hooks:
23
- - id: python-safety-dependencies-check
24
- - repo: https://github.com/asottile/add-trailing-comma
25
- sha: v0.6.4
 
 
 
 
 
 
 
 
 
26
  hooks:
27
- - id: add-trailing-comma
 
 
 
 
 
1
+ repos:
2
+ - repo: 'https://github.com/pre-commit/pre-commit-hooks'
3
+ rev: v3.1.0
4
  hooks:
5
+ - id: pretty-format-json
6
+ name: 'Pretty format JSON'
7
+ args:
8
+ - '--no-sort-keys'
9
+ - '--autofix'
10
+ - '--indent=2'
11
+ - id: trailing-whitespace
12
+ name: 'Fix trailing whitespace'
13
+ exclude: setup.cfg
14
+ - id: end-of-file-fixer
15
+ name: 'Fix missing EOF'
16
+ exclude: setup.cfg
17
+ - id: check-executables-have-shebangs
18
+ name: 'Check exeutables for shebangs'
19
+ - id: check-merge-conflict
20
+ name: 'Check for merge conflict fragments'
21
+ - id: check-case-conflict
22
+ name: 'Check for filesystem character case conflicts'
23
+ - id: detect-private-key
24
+ name: 'Check for cleartext private keys stored'
25
+ - id: check-json
26
+ name: 'Validate JSON'
27
+ - id: check-ast
28
+ name: 'Check Python abstract syntax tree'
29
+ - repo: 'https://github.com/asottile/reorder_python_imports'
30
+ rev: v1.8.0
31
  hooks:
32
+ - id: reorder-python-imports
33
+ name: 'Reorder Python imports'
34
+ - repo: 'https://github.com/pre-commit/mirrors-autopep8'
35
+ rev: ''
36
  hooks:
37
+ - id: autopep8
38
+ name: 'Pretty format Python'
39
+ args:
40
+ - '--in-place'
41
+ - '--aggressive'
42
+ - '--aggressive'
43
+ - '--experimental'
44
+ - '--remove-all-unused-imports'
45
+ - '--ignore-init-module-imports'
46
+ - '--remove-unused-variable'
47
+ - repo: https://github.com/psf/black
48
+ rev: stable
49
  hooks:
50
+ - id: black
51
+ name: 'Ruthlessly format Python'
52
+ language_version: python3.7
53
+ args:
54
+ - '--line-length=79'
Makefile CHANGED
@@ -1,22 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  help:
2
  @echo "clean - remove all build, test, coverage and Python artifacts"
3
  @echo "clean-build - remove build artifacts"
4
  @echo "clean-pyc - remove Python file artifacts"
5
  @echo "install - install the package to the active Python's site-packages"
6
 
7
- pipenv:
8
  pip install pipenv
9
- pipenv install --dev
10
-
11
- test:
12
- pipenv run flake8 pytube/
13
- pipenv run flake8 tests/
14
- pipenv run black pytube --check
15
- pipenv run black tests --check
16
- pipenv run mypy pytube
17
- pipenv run pytest --cov-report term-missing --cov=pytube
18
-
19
- ci: pipenv test
20
 
21
  clean: clean-build clean-pyc
22
 
@@ -33,27 +60,6 @@ clean-pyc:
33
  find . -name '*.pyo' -exec rm -f {} +
34
  find . -name '*~' -exec rm -f {} +
35
  find . -name '__pycache__' -exec rm -fr {} +
36
- find . -name '.pytest_cache' -exec rm -fr {} +
37
- find . -name '.mypy_cache' -exec rm -fr {} +
38
 
39
  install: clean
40
  python setup.py install
41
-
42
- package: clean
43
- pipenv run python setup.py sdist bdist_wheel
44
-
45
- upload:
46
- twine upload dist/*
47
-
48
- tag:
49
- git diff-index --quiet HEAD -- # checks for unstaged/uncomitted files
50
- git tag "v`pipenv run python pytube/version.py`"
51
- git push --tags
52
-
53
- check-master:
54
- if [[ `git rev-parse --abbrev-ref HEAD` != "master" ]]; then exit 1; fi
55
-
56
- pull:
57
- git pull
58
-
59
- release: check-master pull clean test tag package upload
 
1
+ dev:
2
+ pipenv install --dev
3
+
4
+ pipenv:
5
+ pip install pipenv
6
+ pipenv install --dev
7
+
8
+ deploy-patch: clean requirements bumpversion-patch upload clean
9
+
10
+ deploy-minor: clean requirements bumpversion-minor upload clean
11
+
12
+ deploy-major: clean requirements bumpversion-major upload clean
13
+
14
+ requirements:
15
+ pipenv_to_requirements
16
+
17
+ bumpversion-patch:
18
+ bumpversion patch
19
+ git push
20
+ git push --tags
21
+
22
+ bumpversion-minor:
23
+ bumpversion minor
24
+ git push
25
+ git push --tags
26
+
27
+ bumpversion-major:
28
+ bumpversion major
29
+ git push
30
+ git push --tags
31
+
32
+ upload:
33
+ python setup.py sdist bdist_wheel
34
+ twine upload dist/*
35
+
36
  help:
37
  @echo "clean - remove all build, test, coverage and Python artifacts"
38
  @echo "clean-build - remove build artifacts"
39
  @echo "clean-pyc - remove Python file artifacts"
40
  @echo "install - install the package to the active Python's site-packages"
41
 
42
+ ci:
43
  pip install pipenv
44
+ pipenv install --dev --skip-lock
45
+ pipenv run flake8
46
+ pipenv run pytest --cov-report term-missing --cov=humps
 
 
 
 
 
 
 
 
47
 
48
  clean: clean-build clean-pyc
49
 
 
60
  find . -name '*.pyo' -exec rm -f {} +
61
  find . -name '*~' -exec rm -f {} +
62
  find . -name '__pycache__' -exec rm -fr {} +
 
 
63
 
64
  install: clean
65
  python setup.py install
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -1,68 +1,74 @@
1
 
2
  <div align="center">
 
 
 
3
  <p align="center">
4
- <a href="https://pypi.org/project/pytube3/"><img src="https://img.shields.io/pypi/v/pytube3.svg" alt="pypi"></a>
5
- <a href="https://pypi.python.org/pypi/pytube3/"><img src="https://img.shields.io/pypi/pyversions/pytube3.svg" /></a>
6
- <a href="https://travis-ci.com/hbmartin/pytube3/"><img src="https://travis-ci.org/hbmartin/pytube3.svg?branch=master" /></a>
7
- <a href='https://pytube3.readthedocs.io/en/latest/?badge=latest'><img src='https://readthedocs.org/projects/pytube3/badge/?version=latest' alt='Documentation Status' /></a>
8
- <a href="https://codecov.io/gh/hbmartin/pytube3"><img src="https://codecov.io/gh/hbmartin/pytube3/branch/master/graph/badge.svg" /></a>
9
- <a href="https://www.codefactor.io/repository/github/hbmartin/pytube3/overview/master"><img src="https://www.codefactor.io/repository/github/hbmartin/pytube3/badge/master" alt="CodeFactor" /></a>
10
- <a href="https://gitter.im/pytube3/community"><img src="https://img.shields.io/badge/chat-gitter-lightgrey" /></a>
11
  </p>
12
  </div>
13
 
14
- # pytube3
 
15
 
16
- ## Table of Contents
17
- * [Installation](#installation)
18
- * [Quick start](#quick-start)
19
- * [Features](#features)
20
- * [Usage](#usage)
21
- * [Command-line interface](#command-line-interface)
22
- * [Development](#development)
23
- * [GUIs and other libraries](#guis-and-other-libraries)
24
 
25
- ## Installation
 
26
 
27
- Download using pip via pypi.
28
 
29
- ```bash
30
- $ pip install pytube3 --upgrade
31
- ```
32
- (Mac/homebrew users may need to use ``pip3``)
33
 
 
 
 
34
 
35
- ## Quick start
36
  ```python
37
- >>> from pytube import YouTube
38
- >>> YouTube('https://youtu.be/9bZkp7q19f0').streams.get_highest_resolution().download()
39
- >>>
40
  >>> yt = YouTube('http://youtube.com/watch?v=9bZkp7q19f0')
41
  >>> yt.streams
42
  ... .filter(progressive=True, file_extension='mp4')
43
- ... .order_by('resolution')[-1]
 
 
44
  ... .download()
45
  ```
46
- A GUI frontend for pytube3 is available at [YouTubeDownload](https://github.com/YouTubeDownload/YouTubeDownload)
47
 
48
  ## Features
49
- * Support for Both Progressive & DASH Streams
50
- * Support for downloading complete playlist
51
- * Easily Register ``on_download_progress`` & ``on_download_complete`` callbacks
52
- * Command-line Interfaced Included
53
- * Caption Track Support
54
- * Outputs Caption Tracks to .srt format (SubRip Subtitle)
55
- * Ability to Capture Thumbnail URL.
56
- * Extensively Documented Source Code
57
- * No Third-Party Dependencies
58
-
59
- ## Usage
 
 
 
 
 
 
 
 
60
 
61
  Let's begin with showing how easy it is to download a video with pytube:
62
 
63
  ```python
64
  >>> from pytube import YouTube
65
- >>> YouTube('http://youtube.com/watch?v=9bZkp7q19f0').streams[0].download()
66
  ```
67
  This example will download the highest quality progressive download stream available.
68
 
@@ -70,7 +76,7 @@ Next, let's explore how we would view what video streams are available:
70
 
71
  ```python
72
  >>> yt = YouTube('http://youtube.com/watch?v=9bZkp7q19f0')
73
- >>> print(yt.streams)
74
  [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
75
  <Stream: itag="43" mime_type="video/webm" res="360p" fps="30fps" vcodec="vp8.0" acodec="vorbis">,
76
  <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">,
@@ -94,9 +100,6 @@ Next, let's explore how we would view what video streams are available:
94
  <Stream: itag="250" mime_type="audio/webm" abr="70kbps" acodec="opus">,
95
  <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus">]
96
  ```
97
-
98
- ### Selecting an itag
99
-
100
  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).
101
 
102
  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.
@@ -106,7 +109,7 @@ The legacy streams that contain the audio and video in a single file (referred t
106
  To only view these progressive download streams:
107
 
108
  ```python
109
- >>> yt.streams.filter(progressive=True)
110
  [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
111
  <Stream: itag="43" mime_type="video/webm" res="360p" fps="30fps" vcodec="vp8.0" acodec="vorbis">,
112
  <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">,
@@ -117,7 +120,7 @@ To only view these progressive download streams:
117
  Conversely, if you only want to see the DASH streams (also referred to as "adaptive") you can do:
118
 
119
  ```python
120
- >>> yt.streams.filter(adaptive=True)
121
  [<Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028">,
122
  <Stream: itag="248" mime_type="video/webm" res="1080p" fps="30fps" vcodec="vp9">,
123
  <Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d401f">,
@@ -137,26 +140,24 @@ Conversely, if you only want to see the DASH streams (also referred to as "adapt
137
  <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus">]
138
  ```
139
 
140
- ### Playlists
141
-
142
  You can also download a complete Youtube playlist:
143
 
144
  ```python
145
  >>> from pytube import Playlist
146
- >>> playlist = Playlist("https://www.youtube.com/playlist?list=PLynhp4cZEpTbRs_PYISQ8v_uwO0_mDg_X")
147
- >>> for video in playlist:
148
- >>> video.streams.get_highest_resolution().download()
 
149
  ```
150
- This will download the highest progressive stream available (generally 720p) from the given playlist.
151
-
152
- ### Filtering
153
 
154
  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.
155
 
156
  To list the audio only streams:
157
 
158
  ```python
159
- >>> yt.streams.filter(only_audio=True)
160
  [<Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2">,
161
  <Stream: itag="171" mime_type="audio/webm" abr="128kbps" acodec="vorbis">,
162
  <Stream: itag="249" mime_type="audio/webm" abr="50kbps" acodec="opus">,
@@ -167,7 +168,7 @@ To list the audio only streams:
167
  To list only ``mp4`` streams:
168
 
169
  ```python
170
- >>> yt.streams.filter(subtype='mp4')
171
  [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
172
  <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">,
173
  <Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028">,
@@ -182,9 +183,9 @@ To list only ``mp4`` streams:
182
  Multiple filters can also be specified:
183
 
184
  ```python
185
- >>> yt.streams.filter(subtype='mp4', progressive=True)
186
  >>> # this can also be expressed as:
187
- >>> yt.streams.filter(subtype='mp4').filter(progressive=True)
188
  [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
189
  <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">]
190
  ```
@@ -198,16 +199,14 @@ You also have an interface to select streams by their itag, without needing to f
198
  If you need to optimize for a specific feature, such as the "highest resolution" or "lowest average bitrate":
199
 
200
  ```python
201
- >>> yt.streams.filter(progressive=True).order_by('resolution').desc()
202
  ```
203
- Note: Using ``order_by`` on a given attribute will filter out all streams missing that attribute.
204
-
205
- ### Callbacks
206
 
207
  If your application requires post-processing logic, pytube allows you to specify an "on download complete" callback function:
208
 
209
  ```python
210
- >>> def convert_to_aac(stream: Stream, file_path: str):
211
  return # do work
212
 
213
  >>> yt.register_on_complete_callback(convert_to_aac)
@@ -216,7 +215,7 @@ If your application requires post-processing logic, pytube allows you to specify
216
  Similarly, if your application requires on-download progress logic, pytube exposes a callback for this as well:
217
 
218
  ```python
219
- >>> def show_progress_bar(stream: Stream, chunk: bytes, bytes_remaining: int):
220
  return # do work
221
 
222
  >>> yt.register_on_progress_callback(show_progress_bar)
@@ -224,86 +223,17 @@ Similarly, if your application requires on-download progress logic, pytube expos
224
 
225
  ## Command-line interface
226
 
227
- pytube3 ships with a simple CLI interface for downloading videos, playlists, and captions.
228
 
229
  Let's start with downloading:
230
 
231
  ```bash
232
- $ pytube3 http://youtube.com/watch?v=9bZkp7q19f0 --itag=18
233
  ```
234
  To view available streams:
235
 
236
  ```bash
237
- $ pytube3 http://youtube.com/watch?v=9bZkp7q19f0 --list
238
- ```
239
-
240
- The complete set of flags are:
241
-
242
- ```
243
- usage: pytube3 [-h] [--version] [--itag ITAG] [-r RESOLUTION] [-l] [-v]
244
- [--build-playback-report] [-c [CAPTION_CODE]] [-t TARGET]
245
- [-a [AUDIO]] [-f [FFMPEG]]
246
- [url]
247
-
248
- Command line application to download youtube videos.
249
-
250
- positional arguments:
251
- url The YouTube /watch or /playlist url
252
-
253
- optional arguments:
254
- -h, --help show this help message and exit
255
- --version show program's version number and exit
256
- --itag ITAG The itag for the desired stream
257
- -r RESOLUTION, --resolution RESOLUTION
258
- The resolution for the desired stream
259
- -l, --list The list option causes pytube cli to return a list of
260
- streams available to download
261
- -v, --verbose Verbosity level, use up to 4 to increase logging -vvvv
262
- --build-playback-report
263
- Save the html and js to disk
264
- -c [CAPTION_CODE], --caption-code [CAPTION_CODE]
265
- Download srt captions for given language code. Prints
266
- available language codes if no argument given
267
- -t TARGET, --target TARGET
268
- The output directory for the downloaded stream.
269
- Default is current working directory
270
- -a [AUDIO], --audio [AUDIO]
271
- Download the audio for a given URL at the highest
272
- bitrate availableDefaults to mp4 format if none is
273
- specified
274
- -f [FFMPEG], --ffmpeg [FFMPEG]
275
- Downloads the audio and video stream for resolution
276
- providedIf no resolution is provided, downloads the
277
- best resolutionRuns the command line program ffmpeg to
278
- combine the audio and video
279
  ```
280
 
281
-
282
- ## Development
283
-
284
- <a href="https://deepsource.io/gh/hbmartin/pytube3/?ref=repository-badge" target="_blank"><img alt="DeepSource" title="DeepSource" src="https://static.deepsource.io/deepsource-badge-light-mini.svg"></a>
285
- <a href="https://www.codacy.com/manual/hbmartin/pytube3?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=hbmartin/pytube3&amp;utm_campaign=Badge_Grade"><img src="https://api.codacy.com/project/badge/Grade/53794f06983a46829620b3284c6a5596"/></a>
286
- <a href="https://github.com/ambv/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg" /></a>
287
-
288
- Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
289
-
290
- To run code checking before a PR use ``make test``
291
-
292
- #### Virtual environment
293
-
294
- Virtual environment is setup with [pipenv](https://pipenv-fork.readthedocs.io/en/latest/) and can be automatically activated with [direnv](https://direnv.net/docs/installation.html)
295
-
296
- #### Code Formatting
297
-
298
- This project is linted with [pyflakes](https://github.com/PyCQA/pyflakes), formatted with [black](https://github.com/ambv/black), and typed with [mypy](https://mypy.readthedocs.io/en/latest/introduction.html)
299
-
300
-
301
- #### Code of Conduct
302
-
303
- Treat other people with helpfulness, gratitude, and consideration! See the [Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/).
304
-
305
- ## GUIs and other libraries
306
- * [YouTubeDownload](https://github.com/YouTubeDownload/YouTubeDownload) - Featured GUI frontend for pytube3
307
- * [Pytube-GUI](https://github.com/GAO23/Pytube-GUI) - Simple GUI frontend for pytube3
308
- * [StackOverflow questions](https://stackoverflow.com/questions/tagged/pytube)
309
- * [PySlackers](https://pyslackers.com/web) - Python Slack group
 
1
 
2
  <div align="center">
3
+ <p>
4
+ <img src="https://github.com/nficano/pytube/blob/master/images/pytube.png?raw=true" width="350" height="328" alt="pytube logo" />
5
+ </p>
6
  <p align="center">
7
+ <img src="https://img.shields.io/pypi/v/pytube.svg" alt="pypi">
8
+ <a href="https://travis-ci.org/nficano/pytube"><img src="https://travis-ci.org/nficano/pytube.svg?branch=master" /></a>
9
+ <a href="http://python-pytube.readthedocs.io/en/latest/?badge=latest"><img src="https://readthedocs.org/projects/python-pytube/badge/?version=latest" /></a>
10
+ <a href="https://coveralls.io/github/nficano/pytube?branch=master"><img src="https://coveralls.io/repos/github/nficano/pytube/badge.svg?branch=master#23e6f7ac56dd3bde" /></a>
11
+ <a href="https://pypi.org/project/pytube/"><img src="https://img.shields.io/pypi/dm/pytube.svg" alt="pypi"></a>
12
+ <a href="https://pypi.python.org/pypi/pytube/"><img src="https://img.shields.io/pypi/pyversions/pytube.svg" /></a>
13
+ <p>
14
  </p>
15
  </div>
16
 
17
+ # pytube
18
+ *pytube* is a very serious, lightweight, dependency-free Python library (and command-line utility) for downloading YouTube Videos.
19
 
20
+ *pytube* is sponsored by:
21
+ <a href="https://tracking.gitads.io/?repo=pytube/"><img src="https://images.gitads.io/pytube/" alt="GitAds"/></a>
22
+ </p>
 
 
 
 
 
23
 
24
+ ## Description
25
+ 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*.
26
 
27
+ *pytube* is a lightweight library written in Python. It has no third party dependencies and aims to be highly reliable.
28
 
29
+ *pytube* also makes pipelining easy, allowing you to specify callback functions for different download events, such as ``on progress`` or ``on complete``.
 
 
 
30
 
31
+ Finally *pytube* also includes a command-line utility, allowing you to quickly download videos right from terminal.
32
+
33
+ ### Behold, a perfect balance of simplicity versus flexibility:
34
 
 
35
  ```python
36
+ >>> YouTube('https://youtu.be/9bZkp7q19f0').streams.first().download()
 
 
37
  >>> yt = YouTube('http://youtube.com/watch?v=9bZkp7q19f0')
38
  >>> yt.streams
39
  ... .filter(progressive=True, file_extension='mp4')
40
+ ... .order_by('resolution')
41
+ ... .desc()
42
+ ... .first()
43
  ... .download()
44
  ```
 
45
 
46
  ## Features
47
+ - Support for Both Progressive & DASH Streams
48
+ - Support for downloading complete playlist
49
+ - Easily Register ``on_download_progress`` & ``on_download_complete`` callbacks
50
+ - Command-line Interfaced Included
51
+ - Caption Track Support
52
+ - Outputs Caption Tracks to .srt format (SubRip Subtitle)
53
+ - Ability to Capture Thumbnail URL.
54
+ - Extensively Documented Source Code
55
+ - No Third-Party Dependencies
56
+
57
+ ## Installation
58
+
59
+ Download using pip via pypi.
60
+
61
+ ```bash
62
+ $ pip install pytube
63
+ ```
64
+
65
+ ## Getting started
66
 
67
  Let's begin with showing how easy it is to download a video with pytube:
68
 
69
  ```python
70
  >>> from pytube import YouTube
71
+ >>> YouTube('http://youtube.com/watch?v=9bZkp7q19f0').streams.first().download()
72
  ```
73
  This example will download the highest quality progressive download stream available.
74
 
 
76
 
77
  ```python
78
  >>> yt = YouTube('http://youtube.com/watch?v=9bZkp7q19f0')
79
+ >>> yt.streams.all()
80
  [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
81
  <Stream: itag="43" mime_type="video/webm" res="360p" fps="30fps" vcodec="vp8.0" acodec="vorbis">,
82
  <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">,
 
100
  <Stream: itag="250" mime_type="audio/webm" abr="70kbps" acodec="opus">,
101
  <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus">]
102
  ```
 
 
 
103
  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).
104
 
105
  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.
 
109
  To only view these progressive download streams:
110
 
111
  ```python
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">,
 
120
  Conversely, if you only want to see the DASH streams (also referred to as "adaptive") you can do:
121
 
122
  ```python
123
+ >>> yt.streams.filter(adaptive=True).all()
124
  [<Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028">,
125
  <Stream: itag="248" mime_type="video/webm" res="1080p" fps="30fps" vcodec="vp9">,
126
  <Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d401f">,
 
140
  <Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus">]
141
  ```
142
 
 
 
143
  You can also download a complete Youtube playlist:
144
 
145
  ```python
146
  >>> from pytube import Playlist
147
+ >>> pl = Playlist("https://www.youtube.com/watch?v=Edpy1szoG80&list=PL153hDY-y1E00uQtCVCVC8xJ25TYX8yPU")
148
+ >>> pl.download_all()
149
+ >>> # or if you want to download in a specific directory
150
+ >>> pl.download_all('/path/to/directory/')
151
  ```
152
+ This will download the highest progressive stream available (generally 720p) from the given playlist. Later more options would be given for user's flexibility
153
+ to choose video resolution.
 
154
 
155
  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.
156
 
157
  To list the audio only streams:
158
 
159
  ```python
160
+ >>> yt.streams.filter(only_audio=True).all()
161
  [<Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2">,
162
  <Stream: itag="171" mime_type="audio/webm" abr="128kbps" acodec="vorbis">,
163
  <Stream: itag="249" mime_type="audio/webm" abr="50kbps" acodec="opus">,
 
168
  To list only ``mp4`` streams:
169
 
170
  ```python
171
+ >>> yt.streams.filter(subtype='mp4').all()
172
  [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
173
  <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">,
174
  <Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.640028">,
 
183
  Multiple filters can also be specified:
184
 
185
  ```python
186
+ >>> yt.streams.filter(subtype='mp4', progressive=True).all()
187
  >>> # this can also be expressed as:
188
+ >>> yt.streams.filter(subtype='mp4').filter(progressive=True).all()
189
  [<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">,
190
  <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">]
191
  ```
 
199
  If you need to optimize for a specific feature, such as the "highest resolution" or "lowest average bitrate":
200
 
201
  ```python
202
+ >>> yt.streams.filter(progressive=True).order_by('resolution').desc().all()
203
  ```
204
+ 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.
 
 
205
 
206
  If your application requires post-processing logic, pytube allows you to specify an "on download complete" callback function:
207
 
208
  ```python
209
+ >>> def convert_to_aac(stream, file_handle):
210
  return # do work
211
 
212
  >>> yt.register_on_complete_callback(convert_to_aac)
 
215
  Similarly, if your application requires on-download progress logic, pytube exposes a callback for this as well:
216
 
217
  ```python
218
+ >>> def show_progress_bar(stream, chunk, file_handle, bytes_remaining):
219
  return # do work
220
 
221
  >>> yt.register_on_progress_callback(show_progress_bar)
 
223
 
224
  ## Command-line interface
225
 
226
+ pytube also ships with a tiny cli interface for downloading and probing videos.
227
 
228
  Let's start with downloading:
229
 
230
  ```bash
231
+ $ pytube http://youtube.com/watch?v=9bZkp7q19f0 --itag=22
232
  ```
233
  To view available streams:
234
 
235
  ```bash
236
+ $ pytube http://youtube.com/watch?v=9bZkp7q19f0 --list
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  ```
238
 
239
+ 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.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
images/pytube.png ADDED