李子柒回归! 用Python下载她的YouTube视频!

教育   2024-11-14 11:30   四川  


最近,李子柒官宣归来!而其在油管上的粉丝已达到2010万,刷新了中午频道的吉尼斯纪录!我们就以她的视频为例,云朵君将和大家一起学习使用三种不同的方法下载 YouTube 视频。

我们首先定义一个视频列表来测试我们的应用程序,以及一个获取完整 YouTube URL 并仅返回其id部分的函数。

# 要下载的视频
urls = [
    "https://www.youtube.com/watch?v=8Cg3p9K0il4",  # 送给所有知道我名字的人!
    "https://www.youtube.com/watch?v=IrXjnw8BpM0",  # 雕漆隐花,雕出紫气东来!
]

def get_video_id(url: str) -> str:
    """ Return the video ID, which is the part after 'v=' """
    return url.split("v=")[-1]

方法1

使用pytubefix 库下载 YouTube 视频,也下载 mp3 音频。这个库是的一个社区维护的分支pytube。它是为了快速修复官方pytube库面临的问题而创建的,特别是当 YouTube 的更新中断时pytube

from pytubefix import YouTube
from pytubefix.cli import on_progress

output_locn = f"{locations.output_dir}/pytubefix"

def process_yt_videos():
    for i, url in enumerate(urls):
        logger.info(f"Downloads progress: {i+1}/{len(urls)}")

        try:
            yt = YouTube(url, on_progress_callback=on_progress)
            logger.info(f"Getting: {yt.title}")
            video_stream = yt.streams.get_highest_resolution()
            if not video_stream:
                raise Exception("Stream not available.")
            
            # YouTube resource titles may contain special characters which 
            # can't be used when saving the file. So we need to clean the filename.
            cleaned = clean_filename(yt.title)
            
            video_output = f"{output_locn}/{cleaned}.mp4"
            logger.info(f"Downloading video {cleaned}.mp4 ...")
            video_stream.download(output_path=output_locn, filename=f"{cleaned}.mp4")
        
            logger.info(f"Creating audio...")
            audio_stream = yt.streams.get_audio_only()
            audio_stream.download(output_path=output_locn, filename=cleaned, mp3=True)
            
            logger.info("Done")
            
        except Exception as e:        
            logger.error(f"Error processing URL '{url}'.")
            logger.debug(f"The cause was: {e}"
            
    logger.info(f"Downloads finished. See files in {output_locn}.")
    
process_yt_videos()

该代码完成如下功能:

  • 我们首先定义一个以此方法命名的输出文件夹。
  • 我们遍历列表中的每个视频。
  • 我们获得了最高可用分辨率视频的流句柄。
  • 我们使用视频标题来设置下载视频的文件名。但我们必须清理这个文件名,因为标题可能包含文件系统不允许的字符。
  • 然后我们实际下载视频。
  • 我们通过从音频流下载来下载 mp3 音频文件。

优点:

  • 这个python库非常容易使用。
  • 我们可以处理视频、音频、频道、播放列表,甚至搜索和过滤。
  • 它可以通过命令行使用,具有简单的 CLI。
  • 它非常快!

缺点:

  • 不提供 所提供的一些更复杂的功能yt_dlp
  • 它似乎没有正确设置 mp3 标头。mp3 实际上被编码为 mp4a。我认为这不是问题,但值得牢记!

方法2

与之前相同,但这次我使用 Python MoviePy库提取音频。这是一个功能强大的视频和音频编辑库。

我们首先覆盖输出目录。

from pytubefix import YouTube
from pytubefix.cli import on_progress
from moviepy.editor import VideoFileClip

output_locn = f"{locations.output_dir}/pytubefix_with_moviepy"

def process_yt_videos():
    for i, url in enumerate(urls):
        logger.info(f"Downloads progress: {i+1}/{len(urls)}")

        try:
            yt = YouTube(url, on_progress_callback=on_progress)
            logger.info(f"Getting: {yt.title}")
            video_stream = yt.streams.get_highest_resolution()
            if not video_stream:
                raise Exception("Stream not available.")
            
            # YouTube 资源标题可能包含特殊字符,
            # 在保存文件时不能使用。所以我们需要清理文件名。
            cleaned = clean_filename(yt.title)

            video_output = f"{output_locn}/{cleaned}.mp4"
            logger.info(f"Downloading video {cleaned}.mp4 ...")
            video_stream.download(output_path=output_locn, filename=f"{cleaned}.mp4")
        
            logger.info(f"Creating audio...")
            video_clip = VideoFileClip(video_output) # purely to give us access to methods
            assert video_clip.audio is not None
            video_clip.audio.write_audiofile(f"{output_locn}/{cleaned}.mp3")
            video_clip.close()
            
            logger.info("Done")
            
        except Exception as e:        
            logger.error(f"Error processing URL '{url}'.")
            logger.debug(f"The cause was: {e}"
            
    logger.info(f"Downloads finished. See files in {output_locn}.")
    
process_yt_videos()

优点:

  • 我们可以将音频提取为具有正确标题的 mp3 格式。
  • 它很强大。我们可以用这个库进行更多的视频和音频处理。

缺点:

  • 提取音频比单独使用“pytubefix”更慢。
  • 意味着我们需要使用额外的库。

方法3:

我想尝试另一款流行的 YouTube 下载应用程序:yt-dlp。该python库是现已不再维护的youtube-dl``youtube-dl一个分支。

import yt_dlp

output_locn = f"{locations.output_dir}/yt_dlp"

def process_yt_videos():
    for i, url in enumerate(urls):
        logger.info(f"Downloads progress: {i+1}/{len(urls)}")

        try:
            # Options for downloading the video
            video_opts = {
                'format''best',  # Download the best quality video
                'outtmpl'f'{output_locn}/%(title)s.%(ext)s',  # Save video in output directory
            }
            
            # Download the video
            with yt_dlp.YoutubeDL(video_opts) as ydl:
                logger.info("Downloading video...")
                ydl.download([url])
            
            # Options for extracting audio and saving as MP3
            audio_opts = {
                'format''bestaudio',  # Download the best quality audio
                'outtmpl'f'{output_locn}/%(title)s.%(ext)s',  # Save audio in output directory
                'postprocessors': [{
                    'key''FFmpegExtractAudio',
                    'preferredcodec''mp3',
                }],
            }
            
            # Download and extract audio
            with yt_dlp.YoutubeDL(audio_opts) as ydl:
                logger.info("Extracting and saving audio as MP3...")
                ydl.download([url])
            
        except Exception as e:        
            logger.error(f"Error processing URL '{url}'.")
            logger.debug(f"The cause was: {e}"
            
    logger.info(f"Downloads finished. Check out files at {output_locn}.")
    
process_yt_videos()

如果你阅读文档, 你会发现代码本质上要求我们设置一堆键-值对,然后将它们作为字典传递给yt_dlp.YoutubeDL()

优点:

  • 它非常强大,具有比更多的选项和功能pytubefix
  • 它可以作为独立的命令行可执行文件安装,也可以作为可通过 pip 安装的 Python 包安装。
  • 它正确设置了 mp3 标头!
  • 它具有一些强大的网络和代理设置。例如,当您尝试下载受地理限制的视频时,这将非常有用。

缺点:

  • 使用起来比较复杂。文档很复杂,有点难以理解。而且没有真正针对 Python 的文档。
  • 某些用例需要安装 ffmpeg。
  • 执行视频下载和音频提取的速度明显较慢pytubefix

结论

对于基本用例,我非常喜欢使用pytubefix的方法 1。它简单、直观且快速。如果需要更复杂的用例,例如定义代理设置以避免地理位置限制,那么请使用方法 3。最后,如果您想在视频上进行一些叠加,或者增强/处理视频,那么方法 2 将是一个不错的选择。


🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉 PythonMySQL数据分析数据可视化机器学习与数据挖掘爬虫 等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

数据STUDIO
点击领取《Python学习手册》,后台回复「福利」获取。『数据STUDIO』专注于数据科学原创文章分享,内容以 Python 为核心语言,涵盖机器学习、数据分析、可视化、MySQL等领域干货知识总结及实战项目。
 最新文章