mirror of
https://github.com/neosubhamoy/pytubepp.git
synced 2026-02-05 02:32:23 +05:30
Compare commits
26 Commits
v1.0.4-sta
...
v1.1.0-sta
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
- name: 🐍 Setup Python
|
- name: 🐍 Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.10'
|
python-version: '3.12'
|
||||||
|
|
||||||
- name: 📦 Install dependencies
|
- name: 📦 Install dependencies
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
32
README.md
32
README.md
@@ -1,13 +1,15 @@
|
|||||||
# pytubePP - (Pytube Post Processor)
|
# PytubePP - (Pytube Post Processor)
|
||||||
|
|
||||||
### A Simple CLI Tool to Download Your Favourite YouTube Videos Effortlessly!
|
### A Simple CLI Tool to Download Your Favourite YouTube Videos Effortlessly!
|
||||||
|
|
||||||
[](https://github.com/neosubhamoy/pytubepp/)
|
[](https://github.com/neosubhamoy/pytubepp/)
|
||||||
[](https://github.com/neosubhamoy/pytubepp/)
|
[](https://pypi.org/project/pytubepp/)
|
||||||
[](https://www.python.org/downloads/)
|
[](https://pypi.org/project/pytubepp/)
|
||||||
|
[](https://www.python.org/downloads/)
|
||||||
[](https://github.com/neosubhamoy/pytubepp/)
|
[](https://github.com/neosubhamoy/pytubepp/)
|
||||||
[](https://github.com/neosubhamoy/pytubepp/)
|
[](https://github.com/neosubhamoy/pytubepp/)
|
||||||
|
|
||||||
|
😀 GOOD NEWS: If you are Windows(10/11) user and don't want to bother remembering PytubePP Commands! (You are not familier with Command Line Tools). We recently released a Browser Extension that can auto detect YouTube Videos and You can download the Video in one click directly from the browser using PytubePP CLI. Install [PytubePP Helper](https://github.com/neosubhamoy/pytubepp-helper) app in your System and add [PytubePP Extension](https://github.com/neosubhamoy/pytubepp-extension) in your Browser to get started.
|
||||||
|
|
||||||
### **🏷️ Features**
|
### **🏷️ Features**
|
||||||
* Auto Post-Process & Merge YouTube DASH Streams
|
* Auto Post-Process & Merge YouTube DASH Streams
|
||||||
@@ -28,23 +30,29 @@
|
|||||||
* [setuptools](https://pypi.org/project/setuptools/)
|
* [setuptools](https://pypi.org/project/setuptools/)
|
||||||
|
|
||||||
### **🛠️ Installation**
|
### **🛠️ Installation**
|
||||||
You can install pytubePP in your system via PIP by simply running the below command
|
You can install PytubePP in your system via PIP by simply running the below command
|
||||||
|
|
||||||
```terminal
|
```terminal
|
||||||
pip install pytubepp
|
pip install pytubepp
|
||||||
```
|
```
|
||||||
**IMPORTANT: Before installing pytubePP make sure FFmpeg is installed in your system and accesable via your cli interface (FFmpeg is Must Required as some of the core features of pytubePP relies on FFmpeg, but due to security reasons we can not ship it with the module)**
|
**IMPORTANT: Before installing PytubePP make sure FFmpeg is installed in your system and accesable via your cli interface (FFmpeg is Must Required as some of the core features of pytubePP relies on FFmpeg, but due to security reasons we can not ship it with the module)**
|
||||||
|
|
||||||
**>> Install FFmpeg (If you haven't already!)**
|
**>> Install FFmpeg (If you haven't already!)**
|
||||||
|
|
||||||
Linux (Ubuntu): `apt install ffmpeg`<br>
|
Linux (Ubuntu): `sudo apt install ffmpeg`<br>
|
||||||
|
Linux (Fedora): `sudo dnf install ffmpeg-free`<br>
|
||||||
Windows (10/11): `winget install ffmpeg`<br>
|
Windows (10/11): `winget install ffmpeg`<br>
|
||||||
MacOS (using Homebrew): `brew install ffmpeg`<br>
|
MacOS (using Homebrew): `brew install ffmpeg`<br>
|
||||||
Android (using Termux): `pkg install ffmpeg`
|
Android (using Termux): `pkg install ffmpeg`
|
||||||
|
|
||||||
|
**NOTE: Always make sure 'PytubePP' and 'Pytubefix' is on the latest version to avoid issues (update them at least once a week) (Use the command below to update)**
|
||||||
|
```
|
||||||
|
pip install pytubefix pytubepp --upgrade
|
||||||
|
```
|
||||||
|
|
||||||
### **📌 Commands and Flags**
|
### **📌 Commands and Flags**
|
||||||
Using pytubePP is as simple as just supplying it only the YouTube video url as argument!
|
Using PytubePP is as simple as just supplying it only the YouTube video url as argument!
|
||||||
** Before Starting Please NOTE: pytubePP follows a simple rule - "Use the Default Download Configuration if No Flags are Passed"
|
** Before Starting Please NOTE: PytubePP follows a simple rule - "Use the Default Download Configuration if No Flags are Passed"
|
||||||
* To download a video in maximum available resolution the command will look like:
|
* To download a video in maximum available resolution the command will look like:
|
||||||
```terminal
|
```terminal
|
||||||
pytubepp "https://youtube.com/watch?v=2lAe1cqCOXo"
|
pytubepp "https://youtube.com/watch?v=2lAe1cqCOXo"
|
||||||
@@ -67,9 +75,11 @@ pytubepp "https://youtube.com/watch?v=2lAe1cqCOXo" -i
|
|||||||
| Flag | Usage | Requires Parameter | Requires URL | Parameters | Default |
|
| Flag | Usage | Requires Parameter | Requires URL | Parameters | Default |
|
||||||
| :--- | :--- | :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- | :--- | :--- |
|
||||||
| -s | Choose preferred download stream | YES | YES | `144` `144p` `240` `240p` `360` `360p` `480` `480p` `720` `720p` `hd` `1080` `1080p` `fhd` `1440` `1440p` `2k` `2160` `2160p` `4k` `4320` `4320p` `8k` `mp3` (Pass any one of them) | Your chosen Default Stream via `-ds` flag |
|
| -s | Choose preferred download stream | YES | YES | `144` `144p` `240` `240p` `360` `360p` `480` `480p` `720` `720p` `hd` `1080` `1080p` `fhd` `1440` `1440p` `2k` `2160` `2160p` `4k` `4320` `4320p` `8k` `mp3` (Pass any one of them) | Your chosen Default Stream via `-ds` flag |
|
||||||
| -i | Shows the video information like: Title, Author, Views, Available Download Streams | NO | YES | No parameters | No default |
|
| -i | Shows the video information like: Title, Author, Views, Publication Date, Duration, Available Download Streams | NO | YES | No parameters | No default |
|
||||||
|
| -ri | Shows the video information in raw json format | NO | YES | No parameters | No default |
|
||||||
|
| -jp | Shows raw json output in prettified view (with indentation: 4) (primarily used with -ri flag)| NO | YES | No parameters | No default |
|
||||||
| -ds | Set default download stream | YES | NO | `144p` `240p` `360p` `480p` `720p` `1080p` `1440p` `2160p` `4320p` `mp3` `max` (Pass any one of them) | `max` |
|
| -ds | Set default download stream | YES | NO | `144p` `240p` `360p` `480p` `720p` `1080p` `1440p` `2160p` `4320p` `mp3` `max` (Pass any one of them) | `max` |
|
||||||
| -df | Set custom download folder path | YES | NO | Use the full path excluding the last trailing slash within double quotes eg(in Linux): `"/path/to/folder"` (Make sure the folder path you enterted is already created and accessable) | Within `Pytube Downloads` folder in your System's `Downloads` folder |
|
| -df | Set custom download folder path | YES | NO | Use the full path excluding the last trailing slash within double quotes eg(in Linux): `"/path/to/folder"` (Make sure the folder path you enterted is already created and accessable) | Within `PytubePP Downloads` folder in your System's `Downloads` folder |
|
||||||
| -r | Reset to default configuration (Download Folder, Default Stream) | NO | NO | No parameters | No default |
|
| -r | Reset to default configuration (Download Folder, Default Stream) | NO | NO | No parameters | No default |
|
||||||
| -sc | Show all current user configurations | NO | NO | No parameters | No default |
|
| -sc | Show all current user configurations | NO | NO | No parameters | No default |
|
||||||
| -ct | Clear temporary files (audio, video, thumbnail) of the failed, incomplete downloads | NO | NO | No parameters | No default |
|
| -ct | Clear temporary files (audio, video, thumbnail) of the failed, incomplete downloads | NO | NO | No parameters | No default |
|
||||||
@@ -79,7 +89,7 @@ pytubepp "https://youtube.com/watch?v=2lAe1cqCOXo" -i
|
|||||||
|
|
||||||
### 📝 License & Usage
|
### 📝 License & Usage
|
||||||
|
|
||||||
pytubePP - (Pytube Post Processor) is a Fully Open Sourced Project licensed under MIT License. Anyone can view, modify, use (personal and commercial) or distribute it's sources without any attribution and extra permissions.
|
PytubePP - (Pytube Post Processor) is a Fully Open Sourced Project licensed under MIT License. Anyone can view, modify, use (personal and commercial) or distribute it's sources without any attribution and extra permissions.
|
||||||
|
|
||||||
**🌟 Liked this project? Please consider giving it a star to show me your appreciation**
|
**🌟 Liked this project? Please consider giving it a star to show me your appreciation**
|
||||||
<br></br>
|
<br></br>
|
||||||
|
|||||||
280
pytubepp/main.py
280
pytubepp/main.py
@@ -3,7 +3,16 @@ from mutagen.id3 import ID3, APIC, TIT2, TPE1, TALB
|
|||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from importlib.metadata import version
|
from importlib.metadata import version
|
||||||
import appdirs, ffmpy, requests, re, os, sys, random, shutil, platform, json, argparse, tempfile
|
import appdirs, ffmpy, requests, re, os, sys, random, shutil, platform, json, argparse, tempfile, subprocess
|
||||||
|
|
||||||
|
def network_available():
|
||||||
|
try:
|
||||||
|
param = '-n' if platform.system().lower() == 'windows' else '-c'
|
||||||
|
command = ['ping', param, '1', 'youtube.com']
|
||||||
|
subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
|
||||||
|
return True
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return False
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
try:
|
try:
|
||||||
@@ -14,11 +23,11 @@ def get_version():
|
|||||||
def get_download_folder():
|
def get_download_folder():
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
if system in ["Windows", "Darwin", "Linux"]:
|
if system in ["Windows", "Darwin", "Linux"]:
|
||||||
cli_download_dir = os.path.join(os.path.expanduser("~"), "Downloads", "Pytube Downloads")
|
cli_download_dir = os.path.join(os.path.expanduser("~"), "Downloads", "PytubePP Downloads")
|
||||||
os.makedirs(cli_download_dir, exist_ok=True)
|
os.makedirs(cli_download_dir, exist_ok=True)
|
||||||
return cli_download_dir
|
return cli_download_dir
|
||||||
else:
|
else:
|
||||||
cli_download_dir = os.path.join(appdirs.user_download_dir(), "Pytube Downloads")
|
cli_download_dir = os.path.join(appdirs.user_download_dir(), "PytubePP Downloads")
|
||||||
os.makedirs(cli_download_dir, exist_ok=True)
|
os.makedirs(cli_download_dir, exist_ok=True)
|
||||||
return cli_download_dir
|
return cli_download_dir
|
||||||
|
|
||||||
@@ -85,7 +94,7 @@ def merge_audio_video(title, resolution, file_extention, random_filename, tempDI
|
|||||||
ff.run(stdout=devnull, stderr=devnull)
|
ff.run(stdout=devnull, stderr=devnull)
|
||||||
devnull.close()
|
devnull.close()
|
||||||
|
|
||||||
os.rename(output_temp_file, output_file)
|
shutil.move(output_temp_file, output_file)
|
||||||
postprocess_cleanup(tempDIR, ['_vdo.' + file_extention, '_ado.' + file_extention, '_merged.' + file_extention], random_filename)
|
postprocess_cleanup(tempDIR, ['_vdo.' + file_extention, '_ado.' + file_extention, '_merged.' + file_extention], random_filename)
|
||||||
print('Done! 🎉')
|
print('Done! 🎉')
|
||||||
|
|
||||||
@@ -133,7 +142,7 @@ def convert_to_mp3(title, thumbnail_url, random_filename, mp3_artist='Unknown',
|
|||||||
))
|
))
|
||||||
audio.save()
|
audio.save()
|
||||||
|
|
||||||
os.rename(output_temp_file, output_file)
|
shutil.move(output_temp_file, output_file)
|
||||||
postprocess_cleanup(tempDIR, ['_thumbnail.jpg', '_thumbnail.mp4', '_ado.mp4', '_merged.mp4'], random_filename)
|
postprocess_cleanup(tempDIR, ['_thumbnail.jpg', '_thumbnail.mp4', '_ado.mp4', '_merged.mp4'], random_filename)
|
||||||
print('Done! 🎉')
|
print('Done! 🎉')
|
||||||
|
|
||||||
@@ -148,7 +157,7 @@ def download_progressive(stream, itag, title, resolution, file_extention, tempDI
|
|||||||
output_file = os.path.join(downloadDIR, get_unique_filename(title + '_' + resolution + '.' + file_extention))
|
output_file = os.path.join(downloadDIR, get_unique_filename(title + '_' + resolution + '.' + file_extention))
|
||||||
selected_vdo.download(output_path=tempDIR, filename=filename)
|
selected_vdo.download(output_path=tempDIR, filename=filename)
|
||||||
print('Processing...')
|
print('Processing...')
|
||||||
os.rename(output_temp_file, output_file)
|
shutil.move(output_temp_file, output_file)
|
||||||
print('Done! 🎉')
|
print('Done! 🎉')
|
||||||
|
|
||||||
def download_nonprogressive(stream, itag_vdo, itag_ado, file_extention, output_path):
|
def download_nonprogressive(stream, itag_vdo, itag_ado, file_extention, output_path):
|
||||||
@@ -232,12 +241,16 @@ def is_valid_url(url):
|
|||||||
return match
|
return match
|
||||||
|
|
||||||
def set_global_video_info(link):
|
def set_global_video_info(link):
|
||||||
|
if not network_available():
|
||||||
|
print('\nRequest timeout! Please check your network and try again...!!')
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
if is_valid_url(link):
|
if is_valid_url(link):
|
||||||
global video, author, title, thumbnail, views, stream, stream_resolutions, maxres
|
global video, author, title, thumbnail, views, stream, stream_resolutions, maxres
|
||||||
link = is_valid_url(link).group(1)
|
link = is_valid_url(link).group(1)
|
||||||
video = YouTube(link, on_progress_callback=progress)
|
video = YouTube(link, on_progress_callback=progress)
|
||||||
author = video.author
|
author = video.author
|
||||||
title = re.sub(r'[\\/*?:"<>|]', '_', author + '-' + video.title)
|
title = re.sub(r'[\\/*?:"<>|]', '_', author + ' - ' + video.title)
|
||||||
thumbnail = video.thumbnail_url
|
thumbnail = video.thumbnail_url
|
||||||
views = str(video.views)
|
views = str(video.views)
|
||||||
stream = video.streams
|
stream = video.streams
|
||||||
@@ -306,7 +319,7 @@ def show_video_info(link):
|
|||||||
if matching_stream is not None:
|
if matching_stream is not None:
|
||||||
if res == '4320p':
|
if res == '4320p':
|
||||||
type = matching_stream.mime_type
|
type = matching_stream.mime_type
|
||||||
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024 * 1024):.2f} GB" if matching_stream.filesize + stream.get_by_itag(140).filesize >= 1073741824 else f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{matching_stream.fps}fps"
|
fps = f"{matching_stream.fps}fps"
|
||||||
vdo_codec = matching_stream.video_codec
|
vdo_codec = matching_stream.video_codec
|
||||||
ado_codec = stream.get_by_itag(140).audio_codec
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
@@ -315,7 +328,7 @@ def show_video_info(link):
|
|||||||
if res == '2160p':
|
if res == '2160p':
|
||||||
if stream.get_by_itag(701):
|
if stream.get_by_itag(701):
|
||||||
type = stream.get_by_itag(701).mime_type
|
type = stream.get_by_itag(701).mime_type
|
||||||
filesize = f"{(stream.get_by_itag(701).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(stream.get_by_itag(701).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024 * 1024):.2f} GB" if stream.get_by_itag(701).filesize + stream.get_by_itag(140).filesize >= 1073741824 else f"{(stream.get_by_itag(701).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{stream.get_by_itag(701).fps}fps"
|
fps = f"{stream.get_by_itag(701).fps}fps"
|
||||||
vdo_codec = stream.get_by_itag(701).video_codec
|
vdo_codec = stream.get_by_itag(701).video_codec
|
||||||
ado_codec = stream.get_by_itag(140).audio_codec
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
@@ -323,7 +336,7 @@ def show_video_info(link):
|
|||||||
ado_bitrate = stream.get_by_itag(140).abr
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
else:
|
else:
|
||||||
type = matching_stream.mime_type
|
type = matching_stream.mime_type
|
||||||
filesize = f"{(matching_stream.filesize + stream.get_by_itag(251).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(matching_stream.filesize + stream.get_by_itag(251).filesize) / (1024 * 1024 * 1024):.2f} GB" if matching_stream.filesize + stream.get_by_itag(251).filesize >= 1073741824 else f"{(matching_stream.filesize + stream.get_by_itag(251).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{matching_stream.fps}fps"
|
fps = f"{matching_stream.fps}fps"
|
||||||
vdo_codec = matching_stream.video_codec
|
vdo_codec = matching_stream.video_codec
|
||||||
ado_codec = stream.get_by_itag(251).audio_codec
|
ado_codec = stream.get_by_itag(251).audio_codec
|
||||||
@@ -332,7 +345,7 @@ def show_video_info(link):
|
|||||||
elif res == '1440p':
|
elif res == '1440p':
|
||||||
if stream.get_by_itag(700):
|
if stream.get_by_itag(700):
|
||||||
type = stream.get_by_itag(700).mime_type
|
type = stream.get_by_itag(700).mime_type
|
||||||
filesize = f"{(stream.get_by_itag(700).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(stream.get_by_itag(700).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024 * 1024):.2f} GB" if stream.get_by_itag(700).filesize + stream.get_by_itag(140).filesize >= 1073741824 else f"{(stream.get_by_itag(700).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{stream.get_by_itag(700).fps}fps"
|
fps = f"{stream.get_by_itag(700).fps}fps"
|
||||||
vdo_codec = stream.get_by_itag(700).video_codec
|
vdo_codec = stream.get_by_itag(700).video_codec
|
||||||
ado_codec = stream.get_by_itag(140).audio_codec
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
@@ -340,7 +353,7 @@ def show_video_info(link):
|
|||||||
ado_bitrate = stream.get_by_itag(140).abr
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
else:
|
else:
|
||||||
type = matching_stream.mime_type
|
type = matching_stream.mime_type
|
||||||
filesize = f"{(matching_stream.filesize + stream.get_by_itag(251).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(matching_stream.filesize + stream.get_by_itag(251).filesize) / (1024 * 1024 * 1024):.2f} GB" if matching_stream.filesize + stream.get_by_itag(251).filesize >= 1073741824 else f"{(matching_stream.filesize + stream.get_by_itag(251).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{matching_stream.fps}fps"
|
fps = f"{matching_stream.fps}fps"
|
||||||
vdo_codec = matching_stream.video_codec
|
vdo_codec = matching_stream.video_codec
|
||||||
ado_codec = stream.get_by_itag(251).audio_codec
|
ado_codec = stream.get_by_itag(251).audio_codec
|
||||||
@@ -349,7 +362,7 @@ def show_video_info(link):
|
|||||||
elif res == '1080p':
|
elif res == '1080p':
|
||||||
if stream.get_by_itag(699):
|
if stream.get_by_itag(699):
|
||||||
type = stream.get_by_itag(699).mime_type
|
type = stream.get_by_itag(699).mime_type
|
||||||
filesize = f"{(stream.get_by_itag(699).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(stream.get_by_itag(699).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024 * 1024):.2f} GB" if stream.get_by_itag(699).filesize + stream.get_by_itag(140).filesize >= 1073741824 else f"{(stream.get_by_itag(699).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{stream.get_by_itag(699).fps}fps"
|
fps = f"{stream.get_by_itag(699).fps}fps"
|
||||||
vdo_codec = stream.get_by_itag(699).video_codec
|
vdo_codec = stream.get_by_itag(699).video_codec
|
||||||
ado_codec = stream.get_by_itag(140).audio_codec
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
@@ -357,7 +370,7 @@ def show_video_info(link):
|
|||||||
ado_bitrate = stream.get_by_itag(140).abr
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
else:
|
else:
|
||||||
type = matching_stream.mime_type
|
type = matching_stream.mime_type
|
||||||
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024 * 1024):.2f} GB" if matching_stream.filesize + stream.get_by_itag(140).filesize >= 1073741824 else f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{matching_stream.fps}fps"
|
fps = f"{matching_stream.fps}fps"
|
||||||
vdo_codec = matching_stream.video_codec
|
vdo_codec = matching_stream.video_codec
|
||||||
ado_codec = stream.get_by_itag(140).audio_codec
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
@@ -366,7 +379,7 @@ def show_video_info(link):
|
|||||||
elif res == '720p':
|
elif res == '720p':
|
||||||
if stream.get_by_itag(698):
|
if stream.get_by_itag(698):
|
||||||
type = stream.get_by_itag(698).mime_type
|
type = stream.get_by_itag(698).mime_type
|
||||||
filesize = f"{(stream.get_by_itag(698).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(stream.get_by_itag(698).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024 * 1024):.2f} GB" if stream.get_by_itag(698).filesize + stream.get_by_itag(140).filesize >= 1073741824 else f"{(stream.get_by_itag(698).filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{stream.get_by_itag(698).fps}fps"
|
fps = f"{stream.get_by_itag(698).fps}fps"
|
||||||
vdo_codec = stream.get_by_itag(698).video_codec
|
vdo_codec = stream.get_by_itag(698).video_codec
|
||||||
ado_codec = stream.get_by_itag(140).audio_codec
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
@@ -374,7 +387,7 @@ def show_video_info(link):
|
|||||||
ado_bitrate = stream.get_by_itag(140).abr
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
else:
|
else:
|
||||||
type = matching_stream.mime_type
|
type = matching_stream.mime_type
|
||||||
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024 * 1024):.2f} GB" if matching_stream.filesize + stream.get_by_itag(140).filesize >= 1073741824 else f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{matching_stream.fps}fps"
|
fps = f"{matching_stream.fps}fps"
|
||||||
vdo_codec = matching_stream.video_codec
|
vdo_codec = matching_stream.video_codec
|
||||||
ado_codec = stream.get_by_itag(140).audio_codec
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
@@ -382,7 +395,7 @@ def show_video_info(link):
|
|||||||
ado_bitrate = stream.get_by_itag(140).abr
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
elif res == '480p':
|
elif res == '480p':
|
||||||
type = matching_stream.mime_type
|
type = matching_stream.mime_type
|
||||||
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024 * 1024):.2f} GB" if matching_stream.filesize + stream.get_by_itag(140).filesize >= 1073741824 else f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{matching_stream.fps}fps"
|
fps = f"{matching_stream.fps}fps"
|
||||||
vdo_codec = matching_stream.video_codec
|
vdo_codec = matching_stream.video_codec
|
||||||
ado_codec = stream.get_by_itag(140).audio_codec
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
@@ -390,7 +403,7 @@ def show_video_info(link):
|
|||||||
ado_bitrate = stream.get_by_itag(140).abr
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
elif res == '360p':
|
elif res == '360p':
|
||||||
type = matching_stream.mime_type
|
type = matching_stream.mime_type
|
||||||
filesize = f"{matching_stream.filesize / (1024 * 1024):.2f} MB"
|
filesize = f"{matching_stream.filesize / (1024 * 1024 * 1024):.2f} GB" if matching_stream.filesize >= 1073741824 else f"{matching_stream.filesize / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{matching_stream.fps}fps"
|
fps = f"{matching_stream.fps}fps"
|
||||||
vdo_codec = matching_stream.video_codec
|
vdo_codec = matching_stream.video_codec
|
||||||
ado_codec = matching_stream.audio_codec
|
ado_codec = matching_stream.audio_codec
|
||||||
@@ -398,7 +411,7 @@ def show_video_info(link):
|
|||||||
ado_bitrate = matching_stream.abr
|
ado_bitrate = matching_stream.abr
|
||||||
elif res in ['240p', '144p']:
|
elif res in ['240p', '144p']:
|
||||||
type = matching_stream.mime_type
|
type = matching_stream.mime_type
|
||||||
filesize = f"{(matching_stream.filesize + stream.get_by_itag(139).filesize) / (1024 * 1024):.2f} MB"
|
filesize = f"{(matching_stream.filesize + stream.get_by_itag(139).filesize) / (1024 * 1024 * 1024):.2f} GB" if matching_stream.filesize + stream.get_by_itag(139).filesize >= 1073741824 else f"{(matching_stream.filesize + stream.get_by_itag(139).filesize) / (1024 * 1024):.2f} MB"
|
||||||
fps = f"{matching_stream.fps}fps"
|
fps = f"{matching_stream.fps}fps"
|
||||||
vdo_codec = matching_stream.video_codec
|
vdo_codec = matching_stream.video_codec
|
||||||
ado_codec = stream.get_by_itag(139).audio_codec
|
ado_codec = stream.get_by_itag(139).audio_codec
|
||||||
@@ -406,7 +419,7 @@ def show_video_info(link):
|
|||||||
ado_bitrate = stream.get_by_itag(139).abr
|
ado_bitrate = stream.get_by_itag(139).abr
|
||||||
elif res == 'mp3':
|
elif res == 'mp3':
|
||||||
type = "audio/mp3"
|
type = "audio/mp3"
|
||||||
filesize = f"{matching_stream.filesize / (1024 * 1024):.2f} MB"
|
filesize = f"{matching_stream.filesize / (1024 * 1024 * 1024):.2f} GB" if matching_stream.filesize >= 1073741824 else f"{matching_stream.filesize / (1024 * 1024):.2f} MB"
|
||||||
fps = "none"
|
fps = "none"
|
||||||
vdo_codec = "none"
|
vdo_codec = "none"
|
||||||
ado_codec = matching_stream.audio_codec
|
ado_codec = matching_stream.audio_codec
|
||||||
@@ -422,12 +435,214 @@ def show_video_info(link):
|
|||||||
print('Sorry, No video streams found....!!!')
|
print('Sorry, No video streams found....!!!')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
print(f'\nTitle: {video.title}\nAuthor: {author}\nViews: {views}\n')
|
print(f'\nTitle: {video.title}\nAuthor: {author}\nPublished On: {video.publish_date.strftime("%d/%m/%Y")}\nDuration: {video.length}\nViews: {views}\n')
|
||||||
print(tabulate(table, headers=['Stream', 'Alias (for -s flag)', 'Format', 'Size', 'FrameRate', 'V-Codec', 'A-Codec', 'V-BitRate', 'A-BitRate']))
|
print(tabulate(table, headers=['Stream', 'Alias (for -s flag)', 'Format', 'Size', 'FrameRate', 'V-Codec', 'A-Codec', 'V-BitRate', 'A-BitRate']))
|
||||||
print('\n')
|
print('\n')
|
||||||
else:
|
else:
|
||||||
print('\nInvalid video link! Please enter a valid video url...!!')
|
print('\nInvalid video link! Please enter a valid video url...!!')
|
||||||
|
|
||||||
|
def show_raw_info(link, prettify=False):
|
||||||
|
if set_global_video_info(link):
|
||||||
|
streams_list = []
|
||||||
|
found = False
|
||||||
|
|
||||||
|
for res in stream_resolutions.keys():
|
||||||
|
if found or (res not in ['mp3'] and stream.filter(res=res)) or (res == 'mp3' and stream.get_by_itag(140)):
|
||||||
|
found = True
|
||||||
|
if res == 'mp3':
|
||||||
|
matching_stream = stream.get_by_itag(140)
|
||||||
|
else:
|
||||||
|
matching_stream = next((s for s in stream if s.resolution == res), None)
|
||||||
|
if matching_stream is not None:
|
||||||
|
if res == '4320p':
|
||||||
|
itag = matching_stream.itag
|
||||||
|
resolution = '4320p'
|
||||||
|
type = matching_stream.mime_type
|
||||||
|
filesize = matching_stream.filesize + stream.get_by_itag(140).filesize
|
||||||
|
fps = matching_stream.fps
|
||||||
|
vdo_codec = matching_stream.video_codec
|
||||||
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
|
vdo_bitrate = f"{matching_stream.bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
|
is_hdr = True if matching_stream.itag == 702 else False
|
||||||
|
if res == '2160p':
|
||||||
|
resolution = '2160p'
|
||||||
|
if stream.get_by_itag(701):
|
||||||
|
itag = 701
|
||||||
|
type = stream.get_by_itag(701).mime_type
|
||||||
|
filesize = stream.get_by_itag(701).filesize + stream.get_by_itag(140).filesize
|
||||||
|
fps = stream.get_by_itag(701).fps
|
||||||
|
vdo_codec = stream.get_by_itag(701).video_codec
|
||||||
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
|
vdo_bitrate = f"{stream.get_by_itag(701).bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
|
is_hdr = True
|
||||||
|
else:
|
||||||
|
itag = matching_stream.itag
|
||||||
|
type = matching_stream.mime_type
|
||||||
|
filesize = matching_stream.filesize + stream.get_by_itag(251).filesize
|
||||||
|
fps = matching_stream.fps
|
||||||
|
vdo_codec = matching_stream.video_codec
|
||||||
|
ado_codec = stream.get_by_itag(251).audio_codec
|
||||||
|
vdo_bitrate = f"{matching_stream.bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(251).abr
|
||||||
|
is_hdr = False
|
||||||
|
elif res == '1440p':
|
||||||
|
resolution = '1440p'
|
||||||
|
if stream.get_by_itag(700):
|
||||||
|
itag = 700
|
||||||
|
type = stream.get_by_itag(700).mime_type
|
||||||
|
filesize = stream.get_by_itag(700).filesize + stream.get_by_itag(140).filesize
|
||||||
|
fps = stream.get_by_itag(700).fps
|
||||||
|
vdo_codec = stream.get_by_itag(700).video_codec
|
||||||
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
|
vdo_bitrate = f"{stream.get_by_itag(700).bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
|
is_hdr = True
|
||||||
|
else:
|
||||||
|
itag = matching_stream.itag
|
||||||
|
type = matching_stream.mime_type
|
||||||
|
filesize = matching_stream.filesize + stream.get_by_itag(251).filesize
|
||||||
|
fps = matching_stream.fps
|
||||||
|
vdo_codec = matching_stream.video_codec
|
||||||
|
ado_codec = stream.get_by_itag(251).audio_codec
|
||||||
|
vdo_bitrate = f"{matching_stream.bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(251).abr
|
||||||
|
is_hdr = False
|
||||||
|
elif res == '1080p':
|
||||||
|
resolution = '1080p'
|
||||||
|
if stream.get_by_itag(699):
|
||||||
|
itag = 699
|
||||||
|
type = stream.get_by_itag(699).mime_type
|
||||||
|
filesize = stream.get_by_itag(699).filesize + stream.get_by_itag(140).filesize
|
||||||
|
fps = stream.get_by_itag(699).fps
|
||||||
|
vdo_codec = stream.get_by_itag(699).video_codec
|
||||||
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
|
vdo_bitrate = f"{stream.get_by_itag(699).bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
|
is_hdr = True
|
||||||
|
else:
|
||||||
|
itag = matching_stream.itag
|
||||||
|
type = matching_stream.mime_type
|
||||||
|
filesize = matching_stream.filesize + stream.get_by_itag(140).filesize
|
||||||
|
fps = matching_stream.fps
|
||||||
|
vdo_codec = matching_stream.video_codec
|
||||||
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
|
vdo_bitrate = f"{matching_stream.bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
|
is_hdr = False
|
||||||
|
elif res == '720p':
|
||||||
|
resolution = '720p'
|
||||||
|
if stream.get_by_itag(698):
|
||||||
|
itag = 698
|
||||||
|
type = stream.get_by_itag(698).mime_type
|
||||||
|
filesize = stream.get_by_itag(698).filesize + stream.get_by_itag(140).filesize
|
||||||
|
fps = stream.get_by_itag(698).fps
|
||||||
|
vdo_codec = stream.get_by_itag(698).video_codec
|
||||||
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
|
vdo_bitrate = f"{stream.get_by_itag(698).bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
|
is_hdr = True
|
||||||
|
else:
|
||||||
|
itag = matching_stream.itag
|
||||||
|
type = matching_stream.mime_type
|
||||||
|
filesize = matching_stream.filesize + stream.get_by_itag(140).filesize
|
||||||
|
fps = matching_stream.fps
|
||||||
|
vdo_codec = matching_stream.video_codec
|
||||||
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
|
vdo_bitrate = f"{matching_stream.bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
|
is_hdr = False
|
||||||
|
elif res == '480p':
|
||||||
|
itag = matching_stream.itag
|
||||||
|
resolution = '480p'
|
||||||
|
type = matching_stream.mime_type
|
||||||
|
filesize = matching_stream.filesize + stream.get_by_itag(140).filesize
|
||||||
|
fps = matching_stream.fps
|
||||||
|
vdo_codec = matching_stream.video_codec
|
||||||
|
ado_codec = stream.get_by_itag(140).audio_codec
|
||||||
|
vdo_bitrate = f"{matching_stream.bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(140).abr
|
||||||
|
is_hdr = False
|
||||||
|
elif res == '360p':
|
||||||
|
itag = matching_stream.itag
|
||||||
|
resolution = '360p'
|
||||||
|
type = matching_stream.mime_type
|
||||||
|
filesize = matching_stream.filesize
|
||||||
|
fps = matching_stream.fps
|
||||||
|
vdo_codec = matching_stream.video_codec
|
||||||
|
ado_codec = matching_stream.audio_codec
|
||||||
|
vdo_bitrate = f"{matching_stream.bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = matching_stream.abr
|
||||||
|
is_hdr = False
|
||||||
|
elif res in ['240p', '144p']:
|
||||||
|
itag = matching_stream.itag
|
||||||
|
resolution = res
|
||||||
|
type = matching_stream.mime_type
|
||||||
|
filesize = matching_stream.filesize + stream.get_by_itag(139).filesize
|
||||||
|
fps = matching_stream.fps
|
||||||
|
vdo_codec = matching_stream.video_codec
|
||||||
|
ado_codec = stream.get_by_itag(139).audio_codec
|
||||||
|
vdo_bitrate = f"{matching_stream.bitrate / 1024:.0f}kbps"
|
||||||
|
ado_bitrate = stream.get_by_itag(139).abr
|
||||||
|
is_hdr = False
|
||||||
|
elif res == 'mp3':
|
||||||
|
itag = matching_stream.itag
|
||||||
|
resolution = 'mp3'
|
||||||
|
type = "audio/mp3"
|
||||||
|
filesize = matching_stream.filesize
|
||||||
|
fps = None
|
||||||
|
vdo_codec = None
|
||||||
|
ado_codec = matching_stream.audio_codec
|
||||||
|
vdo_bitrate = None
|
||||||
|
ado_bitrate = matching_stream.abr
|
||||||
|
is_hdr = False
|
||||||
|
|
||||||
|
else:
|
||||||
|
filesize = "N/A"
|
||||||
|
current_stream = {
|
||||||
|
'itag': itag,
|
||||||
|
'res': resolution,
|
||||||
|
'mime_type': type,
|
||||||
|
'file_size': filesize,
|
||||||
|
'fps': fps,
|
||||||
|
'vcodec': vdo_codec,
|
||||||
|
'acodec': ado_codec,
|
||||||
|
'vbitrate': vdo_bitrate,
|
||||||
|
'abitrate': ado_bitrate,
|
||||||
|
'is_hdr': is_hdr
|
||||||
|
}
|
||||||
|
streams_list.append(current_stream)
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
print('Sorry, No video streams found....!!!')
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
if prettify:
|
||||||
|
print(json.dumps({
|
||||||
|
'id': video.video_id,
|
||||||
|
'title': video.title,
|
||||||
|
'author': author,
|
||||||
|
'thumbnail_url': thumbnail,
|
||||||
|
'views': video.views,
|
||||||
|
'published_on': video.publish_date.strftime('%d/%m/%Y'),
|
||||||
|
'duration': video.length,
|
||||||
|
'streams': streams_list,
|
||||||
|
}, indent=4))
|
||||||
|
else:
|
||||||
|
print(json.dumps({
|
||||||
|
'id': video.video_id,
|
||||||
|
'title': video.title,
|
||||||
|
'author': author,
|
||||||
|
'thumbnail_url': thumbnail,
|
||||||
|
'views': video.views,
|
||||||
|
'published_on': video.publish_date.strftime('%d/%m/%Y'),
|
||||||
|
'duration': video.length,
|
||||||
|
'streams': streams_list,
|
||||||
|
}))
|
||||||
|
else:
|
||||||
|
print('\nInvalid video link! Please enter a valid video url...!!')
|
||||||
|
|
||||||
def get_allowed_streams(link):
|
def get_allowed_streams(link):
|
||||||
if set_global_video_info(link):
|
if set_global_video_info(link):
|
||||||
allowed_streams = []
|
allowed_streams = []
|
||||||
@@ -527,12 +742,14 @@ def download_stream(link, chosen_stream):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description=f'pytubePP (Pytube Post Processor) v{version} - A Simple CLI Tool to Download Your Favorite YouTube Videos Effortlessly!')
|
parser = argparse.ArgumentParser(description=f'PytubePP (Pytube Post Processor) v{version} - A Simple CLI Tool to Download Your Favorite YouTube Videos Effortlessly!')
|
||||||
parser.add_argument('url', nargs='?', default=None, help='url of the youtube video')
|
parser.add_argument('url', nargs='?', default=None, help='url of the youtube video')
|
||||||
parser.add_argument('-df', '--download-folder', default=argparse.SUPPRESS, help='set custom download folder path (default: ~/Downloads/Pytube Downloads) [arg eg: "/path/to/folder"]')
|
parser.add_argument('-df', '--download-folder', default=argparse.SUPPRESS, help='set custom download folder path (default: ~/Downloads/Pytube Downloads) [arg eg: "/path/to/folder"]')
|
||||||
parser.add_argument('-ds', '--default-stream', default=argparse.SUPPRESS, help='set default download stream (default: max) [available arguments: 144p, 240p, 360p, 480p, 720p, 1080p, 1440p, 2160p, 4320p, mp3, max]')
|
parser.add_argument('-ds', '--default-stream', default=argparse.SUPPRESS, help='set default download stream (default: max) [available arguments: 144p, 240p, 360p, 480p, 720p, 1080p, 1440p, 2160p, 4320p, mp3, max]')
|
||||||
parser.add_argument('-s', '--stream', default=argparse.SUPPRESS, help='choose download stream for the current video (default: your chosen --default-stream) [available arguments: 144p, 240p, 360p, 480p, 720p, 1080p, 1440p, 2160p, 4320p, 144, 240, 360, 480, 720, 1080, 1440, 2160, 4320, mp3, hd, fhd, 2k, 4k, 8k]')
|
parser.add_argument('-s', '--stream', default=argparse.SUPPRESS, help='choose download stream for the current video (default: your chosen --default-stream) [available arguments: 144p, 240p, 360p, 480p, 720p, 1080p, 1440p, 2160p, 4320p, 144, 240, 360, 480, 720, 1080, 1440, 2160, 4320, mp3, hd, fhd, 2k, 4k, 8k]')
|
||||||
parser.add_argument('-i', '--show-info', action='store_true', help='show video info (title, author, views and available_streams)')
|
parser.add_argument('-i', '--show-info', action='store_true', help='show video info (title, author, views and available_streams)')
|
||||||
|
parser.add_argument('-ri', '--raw-info', action='store_true', help='show video info in raw json format')
|
||||||
|
parser.add_argument('-jp', '--json-prettify', action='store_true', help='show json in prettified indented view')
|
||||||
parser.add_argument('-sc', '--show-config', action='store_true', help='show all current user config settings')
|
parser.add_argument('-sc', '--show-config', action='store_true', help='show all current user config settings')
|
||||||
parser.add_argument('-r', '--reset-default', action='store_true', help='reset to default settings (download_folder and default_stream)')
|
parser.add_argument('-r', '--reset-default', action='store_true', help='reset to default settings (download_folder and default_stream)')
|
||||||
parser.add_argument('-ct', '--clear-temp', action='store_true', help='clear temporary files (audio, video, thumbnail files of the failed, incomplete downloads)')
|
parser.add_argument('-ct', '--clear-temp', action='store_true', help='clear temporary files (audio, video, thumbnail files of the failed, incomplete downloads)')
|
||||||
@@ -563,10 +780,19 @@ def main():
|
|||||||
if args.show_info:
|
if args.show_info:
|
||||||
show_video_info(args.url)
|
show_video_info(args.url)
|
||||||
|
|
||||||
|
if args.raw_info:
|
||||||
|
if args.json_prettify:
|
||||||
|
show_raw_info(args.url, True)
|
||||||
|
else:
|
||||||
|
show_raw_info(args.url)
|
||||||
|
|
||||||
|
if args.json_prettify and not args.raw_info:
|
||||||
|
print('\nMissing flag! -jp flag must be used with a flag which returns json data...!! (eg: -ri)')
|
||||||
|
|
||||||
if 'stream' in args:
|
if 'stream' in args:
|
||||||
download_stream(args.url, args.stream)
|
download_stream(args.url, args.stream)
|
||||||
|
|
||||||
if 'stream' not in args and not args.show_info:
|
if 'stream' not in args and not args.show_info and not args.raw_info and not args.json_prettify:
|
||||||
if set_global_video_info(args.url):
|
if set_global_video_info(args.url):
|
||||||
if defaultStream == 'max' and maxres != None:
|
if defaultStream == 'max' and maxres != None:
|
||||||
download_stream(args.url, maxres)
|
download_stream(args.url, maxres)
|
||||||
@@ -621,11 +847,17 @@ def main():
|
|||||||
print(f'\ndownloadDIR: {downloadDIR}\ntempDIR: {tempDIR}\nconfigDIR: {configDIR}\ndefaultStream: {defaultStream}\n')
|
print(f'\ndownloadDIR: {downloadDIR}\ntempDIR: {tempDIR}\nconfigDIR: {configDIR}\ndefaultStream: {defaultStream}\n')
|
||||||
|
|
||||||
if args.version:
|
if args.version:
|
||||||
print(f'\npytubePP (Pytube Post Processor) - version: {version}\n')
|
print(f'pytubepp {version}')
|
||||||
|
|
||||||
if args.show_info:
|
if args.show_info:
|
||||||
print('\nNo video url supplied! exiting...!!')
|
print('\nNo video url supplied! exiting...!!')
|
||||||
|
|
||||||
|
if args.raw_info:
|
||||||
|
print('\nNo video url supplied! exiting...!!')
|
||||||
|
|
||||||
|
if args.json_prettify and not args.raw_info:
|
||||||
|
print('\nMissing flag! -jp flag must be used with a flag which returns json data...!! (eg: -ri)')
|
||||||
|
|
||||||
if 'stream' in args:
|
if 'stream' in args:
|
||||||
print('\nNo video url supplied! exiting...!!')
|
print('\nNo video url supplied! exiting...!!')
|
||||||
|
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -6,7 +6,7 @@ with open('README.md', 'r', encoding='utf8') as file:
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='pytubepp',
|
name='pytubepp',
|
||||||
version='1.0.4',
|
version='1.1.0',
|
||||||
description='A Simple CLI Tool to Download Your Favorite YouTube Videos Effortlessly!',
|
description='A Simple CLI Tool to Download Your Favorite YouTube Videos Effortlessly!',
|
||||||
long_description=readme,
|
long_description=readme,
|
||||||
long_description_content_type='text/markdown',
|
long_description_content_type='text/markdown',
|
||||||
|
|||||||
Reference in New Issue
Block a user