JuanBindez / pytubefix

Python3 library for downloading YouTube Videos.
http://pytubefix.rtfd.io/
MIT License
589 stars 85 forks source link

Bad video quality #128

Closed cedraz closed 2 months ago

cedraz commented 2 months ago

When I ran this code:

`from pytube import YouTube from pytubefix.cli import on_progress

url = "https://youtu.be/6iwyq6tf6L0?si=dgQGngsEXZF9CZ0G"

yt = YouTube(url, on_progress_callback = on_progress) print(yt.title)

ys = yt.streams.get_highest_resolution() ys.download()`

the video quality is poor

hoesungryu commented 2 months ago

The problem is the last() in get_highest_resolution function So, I manually set the certain resolution to download high quality video code:

from pytubefix.cli import on_progress
from pytubefix import YouTube

url = "https://www.youtube.com/watch?v=XXXXXXXXX"
RES = '2160p'
yt = YouTube(url, on_progress_callback = on_progress)

for idx,i in enumerate(yt.streams):
   if i.resolution ==RES:
      print(idx)
      print(i.resolution)
      break
print(yt.streams[idx])
yt.streams[idx].download()
JuanBindez commented 2 months ago

The problem is the last() in get_highest_resolution function So, I manually set the certain resolution to download high quality video code:

from pytubefix.cli import on_progress
from pytubefix import YouTube

url = "https://www.youtube.com/watch?v=XXXXXXXXX"
RES = '2160p'
yt = YouTube(url, on_progress_callback = on_progress)

for idx,i in enumerate(yt.streams):
   if i.resolution ==RES:
      print(idx)
      print(i.resolution)
      break
print(yt.streams[idx])
yt.streams[idx].download()

this solution worked perfectly

3DebbieChen9 commented 2 months ago

The problem is the last() in get_highest_resolution function So, I manually set the certain resolution to download high quality video code:

from pytubefix.cli import on_progress
from pytubefix import YouTube

url = "https://www.youtube.com/watch?v=XXXXXXXXX"
RES = '2160p'
yt = YouTube(url, on_progress_callback = on_progress)

for idx,i in enumerate(yt.streams):
   if i.resolution ==RES:
      print(idx)
      print(i.resolution)
      break
print(yt.streams[idx])
yt.streams[idx].download()

I could get the video with the higher resolution through this method, however, I couldn't get the audio through this method. Is there any way to get the higher resolution and the audio all at once? Thank you.

cedraz commented 2 months ago

I'm having the same issue, now the quality is good but the video has no audio

hossam-elshabory commented 2 months ago

When I ran this code:

`from pytube import YouTube from pytubefix.cli import on_progress

url = "https://youtu.be/6iwyq6tf6L0?si=dgQGngsEXZF9CZ0G"

yt = YouTube(url, on_progress_callback = on_progress) print(yt.title)

ys = yt.streams.get_highest_resolution() ys.download()`

the video quality is poor Sure, here's a simplified and improved version of your explanation with examples:


The code you are using to get the highest quality gets the highest quality available as a progressive stream:

from pytube import YouTube
from pytubefix.cli import on_progress

url = "https://youtu.be/6iwyq6tf6L0?si=dgQGngsEXZF9CZ0G"

yt = YouTube(url, on_progress_callback=on_progress)
print(yt.title)

ys = yt.streams.get_highest_resolution()
ys.download()

this will result in either a 360p or 720p video/audio file. This happens because the .get_highest_resolution() method grabs the highest quality from the Progressive Streams, which include both video and audio. Unfortunately, these often don't offer the best resolution. You can read more about Progressive and DASH Streams here.

To see what Progressive Streams are available, you can use:

streams = yt.streams.filter(progressive=True)
for stream in streams:
    print(stream)

But if you want the best quality, you'll need to use DASH Streams to download the video and audio separately and then combine them. Here’s how you can do it:

  1. Download Video and Audio Separately:
video_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_video=True).order_by('resolution').desc().first()
audio_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_audio=True).order_by('abr').desc().first()

video_stream.download(filename='video.mp4')
audio_stream.download(filename='audio.mp4')

You can learn more about filtering streams in the documentation here.

  1. Combine Video and Audio:

To combine them, you can use Ffmpeg. Make sure you have it installed on your system, and then run:

ffmpeg -i video.mp4 -i audio.mp4 -c copy output.mp4

Or, if you prefer using Python, you can use the moviepy library:

from moviepy.editor import VideoFileClip, AudioFileClip

video_clip = VideoFileClip('video.mp4')
audio_clip = AudioFileClip('audio.mp4')

final_clip = video_clip.set_audio(audio_clip)
final_clip.write_videofile('output.mp4', codec='libx264')

This will give you a combined video with the highest quality available.