脚本一:Youtube影片获取 (Continued...)
3) 合并音视频
上文中,我们成功把Youtube上1080p的视频和128kbps的音频下载了下来,文件名分别是v1080p.webm和audio.mp4,接下来的任务就是用python把他们合成一个有画面有声音的高清影片。这里就需要使用一个跨平台的高性能音视频处理工具FFmpeg,它有非常强大的功能包括视频采集功能、视频格式转换、视频抓图、给视频加水印,加字幕等。FFmpeg包括其原创强大的libavcodec库都是开源的,提供基于命令行的可执行文件进行使用,同时也提供库功能供程序内部使用。更加详细的信息可以访问主页:https://ffmpeg.org/ 。由于其功能之强大,除了合并视频,后面还会有不少使用它的机会。首先我们先确保环境里安装了FFmpeg:
安装FFmpeg
$ ffmpeg -version
ffmpeg version N-107626-g1368b5a725-tessus Copyright (c) 2000-2022 the FFmpeg developers ...
如没有打印出版本信息,那我们需要先进行安装,各个操作系统的安装包,可执行文件和源码都可以在官网下载到:
https://ffmpeg.org/download.html
Ubuntu,Debian的用户可以直接使用apt-get下载安装:
$ sudo apt-get install ffmpeg
MacOS用户可以在https://evermeet.cx/ffmpeg/中直接下载bin文件,解压后得到ffmpeg和ffprobe两个文件,保存到合适位置比如~/opt/ffmpeg/bin/。建议同时配置系统默认路径,具体做法就是打开~/.bash_profile文件:
vim ~/.bash_profile
在该文件的最后添加一句:
export PATH="/Users/你的用户名/opt/ffmpeg/bin:$PATH"
其他操作系统的用户请参考官网下载安装,这里不详述了。
合并影片
回到合并影片,刚刚说到FFmpeg提供系统执行和程序调用两种方式,但尝试下来程序调用功能还是比较有限,所以我们使用系统执行的方式,好在Python可以很方便地调用OS来执行外部应用软件。为了测试功能,我们先直接在命令行中执行一句ffmpeg指令合并v1080p.webm和audio.mp4两个文件,并生成一个叫做"v1080p+audio.mp4"的文件:
$ ffmpeg -y -i v1080p.webm -i audio.mp4 -shortest v1080p+audio.mp4
接下来会有很多的打印,来显示视频处理的过程,具体打印内容我们可以忽略,只要耐心等待一段时间(取决于计算机处理性能),执行完成后,就可以在同目录下找到“v1080p+audio.mp4”文件,播放,你会发现音视频合并完成!
命令行执行成功后,我们就可以把它集成到我们的Python代码里,让合并功能自动执行,代码也是非常简单:
import os
os.system("ffmpeg -y -i v1080p.webm -i audio.mp4 -shortest v1080p+audio.mp4")
由于我们并不能确定Youtube分辨率最高的影片究竟有没有包含acode即音轨,因此在搬运实战中可以在代码中对该stream的字典里查询acode是否存在,或对所有找到的最高分辨率影片一律都合并audio stream,由于即使stream里有acode,它和audio stream的声音也是一样的,所以合并并不会影响声音播放。
另外,真正实战中对于ffmpeg指令中的文件名也可以用字符串拼装来灵活处理输入输出文件,如:
fmpeg_command = "ffmpeg -y -i %s -i %s -shortest %s" % (video_input, audio_input, file_output)
os.system(ffmpeg_command)
顺便提一句,掌握了油管的下载,有兴趣的话也是可以建一个小站,专门提供油管视频的下载服务,以后可能我会出一期搭建这种小站的文章,具体就如这种:
下一篇,我们将示范如何进行Youtube频道相关的操作。
进入下一篇:《躺着就能涨粉?Python自动化短视频搬运(三)|频道监测》
返回上一篇:《躺着就能涨粉?Python自动化短视频搬运(一)|下载影片》
本篇和上篇合并用到的代码
import os
from pytube import YouTube
def download_complete_handler(stream, file_path):
print ("File: " + stream.title + "downloaded completed in " + file_path)
video = YouTube("https://www.youtube.com/watch?v=WZbKAFP1090",
on_complete_callback=download_complete_handler)
print("Video_title = " + video.title)
print("Video_author = " + video.author)
print("Video_length = " + str(video.length))
current_res = 0
stream_highest_res = video.streams[0]
for everystream in video.streams.filter(type="video"):
if int(everystream.resolution[:-1]) > 1080:
continue
if int(everystream.resolution[:-1]) > current_res:
current_res = int(everystream.resolution[:-1])
stream_highest_res = everystream
print("Highest stream: ", stream_highest_res)
stream_highest_res.download(filename='v1080p.webm')
stream_audio = video.streams.filter(type="audio", abr="128kbps")[0]
print(stream_audio)
stream_audio.download(filename='audio.mp4')
os.system("ffmpeg -y -i v1080p.webm -i audio.mp4 -shortest v1080p+audio.mp4")
merge_video.py