python脚本调用youtube-dl实现视频下载

作者: 鲁智深 分类: Python 发布时间: 2018-08-03 02:29

youtube-dl是一个命令行程序,用于从YouTube.com和更多网站下载视频。它需要Python解释器,版本2.6,2.7或3.2+,并且支持Unix,Windows或Mac OS X中运行。而且它提供了自定义添加视频解释并发布到github上,这意味着可以对其进行修改,重新分发。

ubuntu系统安装youtube-dl

1
sudo pip install youtube-dl

更新包

1
sudo -H pip install --upgrade youtube-dl

或者

1
pip install --upgrade youtube-dl

youtube-dl在大多数网站上都可以正常工作。但是,如果您想转换视频/音频,视频音频合成,则需要avconv或ffmpeg

1
2
3
4
5
6
7
8
# 添加软件源
$ sudo add-apt-repository ppa:jonathonf/ffmpeg-3

# 更新并安装
$ sudo apt update && sudo apt install ffmpeg libav-tools x264 x265

# 卸载官方源的2.8版本
$ sudo apt autoremove

先来一段简单的python脚本代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from os import rename
import youtube_dl

def download(youtube_url):
    # 定义某些下载参数
    ydl_opts = {
        # outtmpl 格式化下载后的文件名,避免默认文件名太长无法保存
        'outtmpl': '%(id)s%(ext)s'
    }

    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        ydl.download([youtube_url])

if __name__ == '__main__':
    download('https://www.youtube.com/watch?v=VUOAszEiR8I')

代码执行youtube网站视频页链接,交给dowload下载,字典 ydl_opts 自定义了一些下载参数。

重命名视频文件

当你运行代码后,发现下载的视频文件命名不是你想要的样子,这里了 youtube-dl 提供了一个钩子函数进行自定义功能,代码是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class GetItem(object):

    def rename_hook(self,d):
        # 重命名下载的视频名称的钩子
        if d['status'] == 'finished':
            file_name = 'video/{}.mp4'.format(int(time.time()))
            rename(d['filename'], file_name)
            print('下载完成{}'.format(file_name))

    def download(self,youtube_url):
        # 定义某些下载参数
        ydl_opts = {
            'progress_hooks': [self.rename_hook],
            # 格式化下载后的文件名,避免默认文件名太长无法保存
            'outtmpl': '%(id)s%(ext)s',
        }
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            # 下载给定的URL列表
            result = ydl.download([youtube_url])

if __name__ == '__main__':
    getItem =  GetItem()
    getItem.download('https://www.youtube.com/watch?v=VUOAszEiR8I')

代码 d[‘status’] == ‘finished’执行,说明了当视频下载完成后,执行重命名文件名

自定义下载格式

在定义下载下载参数时可以写入format:”格式” 来控制下载的格式,youtube-dl给到了以下这些默认的格式

best:选择具有视频和音频的单个文件所代表的最佳质量格式。

worst:选择具有视频和音频的单个文件所代表的最差质量格式。

bestvideo:选择最佳质量的仅视频格式(例如DASH视频)。可能无法使用。

worstvideo:选择质量最差的纯视频格式。可能无法使用。

bestaudio:选择质量最佳的音频格式。可能无法使用。

worstaudio:选择质量最差的音频格式。可能无法使用。

我们也可以通过视频原有的格式来下载

在终端输入 : youtube-dl -F 视频地址

shell 命令查看参数

shell 命令查看参数

可以看到有h5 ,1,h3 三种格式,所以代码可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class GetItem(object):

    def rename_hook(self,d):
        # 重命名下载的视频名称的钩子
        if d['status'] == 'finished':
            file_name = 'video/{}.mp4'.format(int(time.time()))
            rename(d['filename'], file_name)
            print('下载完成{}'.format(file_name))

    def download(self,youtube_url):
        # 定义某些下载参数
        ydl_opts = {
            # 我指定了要下载 “1” 这个格式,也可以填写 best/worst/worstaudio 等等
            'format' : '1'
            'progress_hooks': [self.rename_hook],
            # 格式化下载后的文件名,避免默认文件名太长无法保存
            'outtmpl': '%(id)s%(ext)s',
        }
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            # 下载给定的URL列表
            result = ydl.download([youtube_url])

if __name__ == '__main__':
    getItem =  GetItem()
    getItem.download('https://www.youtube.com/watch?v=VUOAszEiR8I')

日志打印

如果要打印youtube-dl的输出logs,请设置一个logger对象。 同自定义格式一样,配置参数’logger’: MyLogger(),如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class MyLogger(object):
    def debug(self, msg):
        pass

    def warning(self, msg):
        pass

    def error(self, msg):
        print(msg)

class GetItem(object):

    def rename_hook(self,d):
        # 重命名下载的视频名称的钩子
        if d['status'] == 'finished':
            file_name = 'video/{}.mp4'.format(int(time.time()))
            rename(d['filename'], file_name)
            print('下载完成{}'.format(file_name))

    def download(self,youtube_url):
        # 定义某些下载参数
        ydl_opts = {
            # 我指定了要下载 “1” 这个格式,也可以填写 best/worst/worstaudio 等等
            'format' : '1'
            'progress_hooks': [self.rename_hook],
            # 格式化下载后的文件名,避免默认文件名太长无法保存
            'outtmpl': '%(id)s%(ext)s',
            # 打印日志
            'logger': MyLogger()
        }
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            # 下载给定的URL列表
            result = ydl.download([youtube_url])

if __name__ == '__main__':
    getItem =  GetItem()
    getItem.download('https://www.youtube.com/watch?v=VUOAszEiR8I')

提取视频的json信息打印

现在有一个需求是:不需要下载视频,我想要得到当前页视频网站的数据,可以用 extract_info 不用 download 去下载

1
2
3
4
5
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
   # extract_info 提取信息
   result = ydl.extract_info(youtube_url, download=False)

print(result)

合并音频+视频

可以先用youtube-dl -F “视频地址”查看format信息,在选择对应的格式代号如(’format’: ‘134+m4a’,)合成,但是合成视频音频是必须先安装ffmpeg,文章开头已经介绍过,不然会报错如下:

WARNING: You have requested multiple formats but ffmpeg or avconv are not installed. The formats won’t be merged.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import youtube_dl

def download(url):

    ydl_opts = {
        'format': '134+m4a',
        'outtmpl': '%(id)s%(ext)s'
    }

    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        result = ydl.extract_info(url, download=True)

if __name__ == '__main__':
    download('https://www.youtube.com/watch?v=-5r9oswhnY4')

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注