Skip to content

Commit

Permalink
Display the video size next to the resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
Hetari committed Mar 28, 2024
1 parent 6a53bab commit 8282820
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ reinstall.sh
*.mp4
# Byte-compiled / optimized / DLL files
__pycache__/
.pytest_cache/
*.py[cod]
*$py.class

Expand Down
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# Pyutube Changelog

## 1.1.7

- Added: Display the video size next to the resolution.
For example:

```
✅ There is internet connection
[?] Choose the file type you want to download:
Audio
> Video
> Cancel the download
Title: Write an Incredible Resume: 5 Golden Rules!
[?] Choose the resolution you want to download:
144p ~= 10.91 MB
240p ~= 15.17 MB
360p ~= 21.62 MB
480p ~= 38.37 MB
> 720p ~= 70.31 MB
1080p ~= 128.81 MB
Cancel the download
```

> **Note:** The video size is approximate, that's mean it's not exact 100%.
## 1.1.6

- Added: Ability to show the tool version with the `-v` or `--version` option.
Expand Down Expand Up @@ -36,6 +64,10 @@
pyutube https://youtube.com/watch?v=cMPnY7EuZvo
```

````

```

- Fix: Enhanced Output Representation when using `--help`

## 1.1.2
Expand All @@ -57,3 +89,5 @@
## 1.0.0

- Initial release
```
````
63 changes: 55 additions & 8 deletions pyutube/downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,21 @@ def get_available_resolutions(self, video: YouTube) -> set:
audio_stream = streams.filter(
only_audio=True).order_by('mime_type').first()

resolutions = {
stream.resolution for stream in available_streams if stream.resolution
}
resolutions_with_sizes = self.get_video_resolutions_sizes(
available_streams, audio_stream
)

resolutions_with_sizes = sorted(
resolutions_with_sizes, key=lambda x: int(
x[0][:-1]) if x[0][:-1].isdigit() else float('inf')
)

# sort resolutions
resolutions = sorted(resolutions, key=lambda x: int(x.split("p")[0]))
# Separate resolutions and sizes without using two loops
resolutions, sizes = zip(*resolutions_with_sizes)
resolutions = list(resolutions)
sizes = list(sizes)

return resolutions, available_streams, audio_stream
return resolutions, sizes, available_streams, audio_stream

@yaspin(text=colored("Downloading the video...", "green"), color="green", spinner=Spinners.dots13)
def get_video_streams(self, quality: str, streams: YouTube.streams) -> YouTube:
Expand Down Expand Up @@ -144,9 +151,9 @@ def get_selected_stream(self, video):
Returns:
YouTube: The selected video stream.
"""
resolutions, streams, video_audio = self.get_available_resolutions(
resolutions, sizes, streams, video_audio = self.get_available_resolutions(
video)
self.quality = ask_resolution(resolutions)
self.quality = ask_resolution(resolutions, sizes)

return [] if self.quality.startswith("cancel") else streams, video_audio

Expand Down Expand Up @@ -222,6 +229,46 @@ def merging(self, video_name: str, audio_name: str, video_id: str):
else:
print("Merged video file not found in the output directory.")

@staticmethod
def get_video_resolutions_sizes(available_streams: list[YouTube], audio_stream: YouTube) -> list:
"""
Get the available video resolutions.
Args:
available_streams: The available video streams.
audio_stream: The audio stream.
Returns:
list: The available video resolutions.
"""
if not available_streams:
return []

# Calculate the total audio file size in bytes
audio_filesize_bytes = audio_stream.filesize_approx

# Convert the audio file size to KB
audio_filesize_kb = audio_filesize_bytes / 1000

resolutions_with_sizes = []
for stream in available_streams:
if stream.resolution:
# Calculate the total video file size including audio in bytes
video_filesize_bytes = stream.filesize_approx + \
(2 * audio_filesize_bytes)
# Convert the video file size to KB or MB dynamically
if video_filesize_bytes >= 1024 * 1024:
# If size is >= 1 MB
video_filesize = \
f"{video_filesize_bytes / (1024 * 1024):.2f} MB"
else:
video_filesize = f"{video_filesize_bytes / 1024:.2f} KB"

resolutions_with_sizes.append(
(stream.resolution, video_filesize))

return resolutions_with_sizes

def download_video(self):
"""
Download a video from a given URL to a specified path.
Expand Down
14 changes: 11 additions & 3 deletions pyutube/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def file_type() -> str:
return answer


def ask_resolution(resolutions: set) -> str:
def ask_resolution(resolutions: set, sizes) -> str:
"""
Prompts the user to choose a resolution for download and returns the chosen resolution as a string.
Expand All @@ -177,7 +177,14 @@ def ask_resolution(resolutions: set) -> str:
Returns:
str: The chosen resolution as a string.
"""
resolution_choices = list(resolutions) + ["Cancel the download"]
# Create a dictionary to relate each size with its resolution
size_resolution_mapping = dict(zip(resolutions, sizes))

# Generate the choices for the user prompt
resolution_choices = [
f"{size} ~= {resolution}" for size, resolution in size_resolution_mapping.items()
] + ["Cancel the download"]

questions = [
inquirer.List(
"resolution",
Expand All @@ -195,7 +202,8 @@ def ask_resolution(resolutions: set) -> str:
except Exception as error:
error_console.print(f"Error: {error}")

return answer.lower()
# Extract the resolution part from the user's choice
return answer.split(" ~= ")[0]


def ask_rename_file(filename: str) -> str:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
name="pyutube",

# Version of the package
version="1.1.5",
version="1.1.7",

# Required dependencies
install_requires=[
Expand Down

0 comments on commit 8282820

Please sign in to comment.