首先我们需要下载ffmepg,并且配置环境变量
-
把下载下来的文件中的bin文件夹的路径添加到Path中
-
然后打开Anaconda Prompt,使用命令conda install ffmpeg安装ffmpeg
-
使用 ffmpeg -version查看下载到的ffmpeg
-
在python代码中,我们使用subprocess开启一个cmd线程,然后执行ffmpeg将音频和视频合成在一起的指令
COMMAND = f'ffmpeg -i {video_name}.mp4 -i {video_name}.mp3 -c:v copy -c:a aac -strict experimental {video_name}out.mp4 ' subprocess.Popen(COMMAND, shell=True)
-
然而,有时候却输出不了合成后的视频,经过研究之后发现,原来是B站视频中有的视频标题最后会使用空格符号,使得cmd命令无法正确执行,因此,我在这里使用正则表达式将爬取到的视频标题当中的所有标点符号替换为空,此时就可以正确的输出合并后的视频
# 使用正则表达式将标题当中的所有标点符号替换为空 title = re.sub('\W+', '', title).replace("_", '') # 使用正则表达式将标题当中的所有标点符号替换为空,防止执行ffmpeg合并视频和音频时输出视频失败 video_name = re.sub('\W+', '', video_name).replace("_", '')
-
爬取B站视频和音频并将视频和音频合并的源代码如下
import requests import re import json import pprint # 格式化输出 import subprocess import os # path = './videos' # # if not os.path.exists(path): # os.mkdir(path) def get_response(html_url): headers = { 'referer': 'https://www.bilibili.com/', # 防止反爬 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.73' } response = requests.get(url=html_url, headers=headers) return response def get_video_info(html_url): response = get_response(html_url) title = re.findall(r'<h1 title="(.*?)" class="video-title">', response.text)[0] html_data = re.findall(r'<script>window.__playinfo__=(.*?)</script>', response.text)[0] # 正则匹配式匹配出来的数据是列表 # 把字符串转为json数据 json_data = json.loads(html_data) # pprint.pprint(json_data) # 数据解析 audio_url = json_data['data']['dash']['audio'][0]['baseUrl'] video_url = json_data['data']['dash']['video'][0]['baseUrl'] video_info = [title, audio_url, video_url] return video_info def save(title, audio_url, video_url): # 保存数据 # 使用正则表达式将标题当中的所有标点符号替换为空 title = re.sub('\W+', '', title).replace("_", '') audio_content = get_response(audio_url).content video_content = get_response(video_url).content with open(title + '.mp3', mode='wb') as fp: fp.write(audio_content) with open(title + '.mp4', mode='wb') as fp: fp.write(video_content) print('视频内容保存完毕') def merge_data(video_name): '''数据的合并''' # 使用正则表达式将标题当中的所有标点符号替换为空,防止执行ffmpeg合并视频和音频时输出视频失败 video_name = re.sub('\W+', '', video_name).replace("_", '') print('视频合成开始:', video_name) COMMAND = f'ffmpeg -i {video_name}.mp4 -i {video_name}.mp3 -c:v copy -c:a aac -strict experimental {video_name}out.mp4 ' subprocess.Popen(COMMAND, shell=True) print('视频合成结束:', video_name) url = 'https://www.bilibili.com/video/BV1y541157e4' video_info = get_video_info(url) save(video_info[0], video_info[1], video_info[2]) merge_data(video_info[0])