1
1
mirror of https://github.com/neosubhamoy/pytubepp.git synced 2026-02-04 18:22:23 +05:30

8 Commits

3 changed files with 114 additions and 23 deletions

View File

@@ -1,16 +1,18 @@
# pytubePP - (Pytube Post Processor)
# PytubePP - (Pytube Post Processor)
### A Simple CLI Tool to Download Your Favourite YouTube Videos Effortlessly!
[![status](https://img.shields.io/badge/status-active-brightgreen.svg?style=flat)](https://github.com/neosubhamoy/pytubepp/)
[![verion](https://img.shields.io/badge/version-v1.0.3_stable-yellow.svg?style=flat)](https://github.com/neosubhamoy/pytubepp/)
[![verion](https://img.shields.io/badge/version-v1.0.5_stable-yellow.svg?style=flat)](https://github.com/neosubhamoy/pytubepp/)
[![python](https://img.shields.io/badge/python-v3.12.x-blue?logo=python&style=flat)](https://www.python.org/downloads/)
[![builds](https://img.shields.io/badge/builds-passing-brightgreen.svg?style=flat)](https://github.com/neosubhamoy/pytubepp/)
[![PRs](https://img.shields.io/badge/PRs-welcome-blue.svg?style=flat)](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 Computer and add [PytubePP Extension](https://github.com/neosubhamoy/pytubepp-extension) in your Browser to get started.
### **🏷️ Features**
* Auto Post-Process & Merge YouTube DASH Streams
* Supports upto 8K 60fps HDR Stream Download
* Supports MP3 Download (with Embeded Thumbnail and Tags)
* Smart Stream Selection
* Highly Configurable and Many More 😉
@@ -56,7 +58,11 @@ pytubepp "https://youtube.com/watch?v=2lAe1cqCOXo" -s 480p
```terminal
pytubepp "https://youtube.com/watch?v=2lAe1cqCOXo" -s mp3
```
* To cancel/stop an ongoing download press `CTRL` + `C` on keyboard.
* To fetch the video information the command will be:
```terminal
pytubepp "https://youtube.com/watch?v=2lAe1cqCOXo" -i
```
* To cancel/stop an ongoing download press `CTRL` + `C` on keyboard (it is recommended to run the `-ct` flag once after canceling an ongoing download).
* List of all available flags are given below:
| Flag | Usage | Requires Parameter | Requires URL | Parameters | Default |

View File

@@ -2,12 +2,22 @@ from pytubefix import YouTube
from mutagen.id3 import ID3, APIC, TIT2, TPE1, TALB
from tabulate import tabulate
from tqdm import tqdm
import appdirs, ffmpy, requests, re, os, sys, random, shutil, platform, json, argparse, tempfile, pkg_resources
from importlib.metadata import version
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():
try:
return pkg_resources.get_distribution("pytubepp").version
except pkg_resources.DistributionNotFound:
return version('pytubepp')
except Exception as e:
return "Unknown"
def get_download_folder():
@@ -231,6 +241,10 @@ def is_valid_url(url):
return match
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):
global video, author, title, thumbnail, views, stream, stream_resolutions, maxres
link = is_valid_url(link).group(1)
@@ -311,7 +325,16 @@ def show_video_info(link):
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
if res in ['2160p', '1440p']:
if res == '2160p':
if stream.get_by_itag(701):
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"
fps = f"{stream.get_by_itag(701).fps}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
else:
type = matching_stream.mime_type
filesize = f"{(matching_stream.filesize + stream.get_by_itag(251).filesize) / (1024 * 1024):.2f} MB"
fps = f"{matching_stream.fps}fps"
@@ -319,7 +342,58 @@ def show_video_info(link):
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
elif res in ['1080p', '720p', '480p']:
elif res == '1440p':
if stream.get_by_itag(700):
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"
fps = f"{stream.get_by_itag(700).fps}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
else:
type = matching_stream.mime_type
filesize = f"{(matching_stream.filesize + stream.get_by_itag(251).filesize) / (1024 * 1024):.2f} MB"
fps = f"{matching_stream.fps}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
elif res == '1080p':
if stream.get_by_itag(699):
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"
fps = f"{stream.get_by_itag(699).fps}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
else:
type = matching_stream.mime_type
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
fps = f"{matching_stream.fps}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
elif res == '720p':
if stream.get_by_itag(698):
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"
fps = f"{stream.get_by_itag(698).fps}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
else:
type = matching_stream.mime_type
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
fps = f"{matching_stream.fps}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
elif res == '480p':
type = matching_stream.mime_type
filesize = f"{(matching_stream.filesize + stream.get_by_itag(140).filesize) / (1024 * 1024):.2f} MB"
fps = f"{matching_stream.fps}fps"
@@ -362,7 +436,7 @@ def show_video_info(link):
sys.exit()
print(f'\nTitle: {video.title}\nAuthor: {author}\nViews: {views}\n')
print(tabulate(table, headers=['Stream', 'Alias', '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')
else:
print('\nInvalid video link! Please enter a valid video url...!!')
@@ -411,13 +485,17 @@ def download_stream(link, chosen_stream):
download_progressive(stream, 18, title, '360p', 'mp4')
elif chosen_stream in ['1080', '1080p', 'fhd']:
if stream.get_by_itag(299):
if stream.get_by_itag(699):
merge_audio_video(title, '1080p', 'mp4', download_nonprogressive(stream, 699, 140, 'mp4', tempDIR))
elif stream.get_by_itag(299):
merge_audio_video(title, '1080p', 'mp4', download_nonprogressive(stream, 299, 140, 'mp4', tempDIR))
elif stream.get_by_itag(137):
merge_audio_video(title, '1080p', 'mp4', download_nonprogressive(stream, 137, 140, 'mp4', tempDIR))
elif chosen_stream in ['720', '720p', 'hd']:
if stream.get_by_itag(298):
if stream.get_by_itag(698):
merge_audio_video(title, '720p', 'mp4', download_nonprogressive(stream, 698, 140, 'mp4', tempDIR))
elif stream.get_by_itag(298):
merge_audio_video(title, '720p', 'mp4', download_nonprogressive(stream, 298, 140, 'mp4', tempDIR))
elif stream.get_by_itag(136):
merge_audio_video(title, '720p', 'mp4', download_nonprogressive(stream, 136, 140, 'mp4', tempDIR))
@@ -432,16 +510,23 @@ def download_stream(link, chosen_stream):
merge_audio_video(title, '144p', 'mp4', download_nonprogressive(stream, 160, 139, 'mp4', tempDIR))
elif chosen_stream in ['4320', '4320p', '8k']:
if stream.get_by_itag(702):
merge_audio_video(title, '8k', 'mp4', download_nonprogressive(stream, 702, 140, 'mp4', tempDIR))
elif stream.get_by_itag(571):
merge_audio_video(title, '8k', 'mp4', download_nonprogressive(stream, 571, 140, 'mp4', tempDIR))
elif chosen_stream in ['2160', '2160p', '4k']:
if stream.get_by_itag(315):
if stream.get_by_itag(701):
merge_audio_video(title, '4k', 'mp4', download_nonprogressive(stream, 701, 140, 'mp4', tempDIR))
elif stream.get_by_itag(315):
merge_audio_video(title, '4k', 'webm', download_nonprogressive(stream, 315, 251, 'webm', tempDIR))
elif stream.get_by_itag(313):
merge_audio_video(title, '4k', 'webm', download_nonprogressive(stream, 313, 251, 'webm', tempDIR))
elif chosen_stream in ['1440', '1440p', '2k']:
if stream.get_by_itag(308):
if stream.get_by_itag(700):
merge_audio_video(title, '2k', 'mp4', download_nonprogressive(stream, 700, 140, 'mp4', tempDIR))
elif stream.get_by_itag(308):
merge_audio_video(title, '2k', 'webm', download_nonprogressive(stream, 308, 251, 'webm', tempDIR))
elif stream.get_by_itag(271):
merge_audio_video(title, '2k', 'webm', download_nonprogressive(stream, 271, 251, 'webm', tempDIR))
@@ -549,7 +634,7 @@ def main():
print(f'\ndownloadDIR: {downloadDIR}\ntempDIR: {tempDIR}\nconfigDIR: {configDIR}\ndefaultStream: {defaultStream}\n')
if args.version:
print(f'\npytubePP (Pytube Post Processor) - version: {version}\n')
print(f'pytubepp {version}')
if args.show_info:
print('\nNo video url supplied! exiting...!!')

View File

@@ -6,7 +6,7 @@ with open('README.md', 'r', encoding='utf8') as file:
setup(
name='pytubepp',
version='1.0.3',
version='1.0.5',
description='A Simple CLI Tool to Download Your Favorite YouTube Videos Effortlessly!',
long_description=readme,
long_description_content_type='text/markdown',