YouTube-dl下载视频

最后来看progress_hooks这个参数,给这个参数的值是个函数列表:

ydl_opts = {
            ……

            'progress_hooks': [my_hook],          
             # my_hook是钩子函数,传入函数的是一个视频信息的字典

            ……
            }

函数my_hook()用作钩子函数,启动下载进程时被调用。下载进程启动后可以有三个状态:正在下载"downloading"、出错 "error"、 下载完毕"finished"。定义的钩子函数可以根据下载状态输出相应信息,比如my_hook()规定如果下载成功,则显示视频信息:

import youtube_dl

# 定义视频下载后的存放位置和视频链接
destPath = '/Users/PythonABC/Documents/tmp/'   

# 音频文件存放的目标字串
videoPage = 'https://www.youtube.com/watch?v=FLhzB_DJQb4'

# 定义钩子函数
def my_hook(d):

    if d['status'] == 'finished':       # 如果视频下载完毕
        print('\n下载完毕后再输出视频信息:')
        for key, value in d.items():
            print("{}: {}".format(key, value))

# 定义下载选项
ydl_opts = {
            'outtmpl': destPath+'%(title)s.%(ext)s',
            'format': 'best',
            'progress_hooks': [my_hook],      # my_hook是钩子函数
            }

ydl = youtube_dl.YoutubeDL(ydl_opts)         # 生成下载对象

ydl.download([videoPage])                     # 下载视频

视频下载成功的提示之后还会出现:

 

图23.5 下载完毕后启动输出钩子函数my_hook()里指定的信息

因为下载进程中钩子函数不断被调用,视频下载成功满足if语句设定的条件,按照设定输出视频信息字典的健值和值。

如果生成下载对象ydl后,调用ydl的方法函数extract_info()抽取信息时,参数download设为false:

result = ydl.extract_info(
                           videoPage, 
                           download=False,    # 不下载只是抽取信息
                         )

因为只提取视频信息不下载视频,所以如果前面的代码改为:

……

def my_hook(d):
    if d['status'] == 'finished':            # 如果视频进程完成
        print('\n下载完毕后再输出视频信息:')
        for key, value in d.items():
            print("{}: {}".format(key, value))

ydl_opts = {                  # 定义下载选项
            'outtmpl': destPath+'%(title)s.%(ext)s',
            'format': 'best',
            'progress_hooks': [my_hook],     # my_hook是钩子函数
           }

ydl = youtube_dl.YoutubeDL(ydl_opts)         # 生成下载对象

result = ydl.extract_info( 
                           videoPage,        # 视频链接
                           download=False,   # 不下载只是抽取信息
                         )

if 'entries' in result:

    downloadVideos = result['entries']         

    for video in downloadVideos:                      

        print("标题:{}\n ".format(video['title']))
else:
    downloadVideo = result
    print('一枝独秀:{}'.format(downloadVideo['title']))

运行结果:

图23.6 下载进程没启动,参数'progress_hooks指定的钩子函数没运行

my_hook()没有被调用,因为下载进程根本没有被启动,跟下载进程关联的钩子函数自然没有机会被运行。