原理: 下载视频轨道文件、和音频轨道文件,最后用ffmpeg进行视频轨和音轨的合成
目前下载工具可以在 win/linux/mac上运行。其实就是执行python
Linux/Mac OS X
在linux/Mac OS X系统中可能需要修改下文件权限
Linux
cd /path/to/BiliDown
chmod +x tools/linux/ffmpeg
Mac
cd /path/to/BiliDown
chmod +x tools/mac/ffmpeg
教程
pip install -r reqirements.txt
编辑 download.py 文件,在最后 url 中填上你需要下载的B站链接,
如果需要换 cookie, 在Cookies中填写你浏览器中的cookie内容
最后用python执行就行了
最终需要的视频会在当前目录下的 Output 中生成
代码:
[Python] 纯文本查看 复制代码#!/usr/bin/env python3
# -*- coding: utf8 -*-
import os
import sys
import re
import platform
import requests
import subprocess
requests.packages.urllib3.disable_warnings()
sess = requests.Session()
sess.headers.update({
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
})
def CMD(command):
p = subprocess.Popen(command, shell=True, universal_newlines=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, encoding='utf8')
stdout, stderr = p.communicate(timeout=10)
stdout = stdout.strip()
return stdout, stderr
def download_file(filename, url):
resp = sess.get(url, verify=False, stream=True)
with open(filename, 'wb') as f:
for chunk in resp.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
return filename
def delete_cache_file(path):
try:
os.remove(path)
except Exception as e:
print(e)
def get_video_and_audio_url_from_bilibili(url):
re_video_base_url = re.compile(r'"video":.*?,"baseUrl":"(.*?)"', re.I)
re_audio_base_url = re.compile(r'"audio":.*?,"baseUrl":"(.*?)"', re.I)
re_video_name = re.compile(r'', re.I)
sess.headers.update({'referer': url})
resp = sess.get(url, verify=False, timeout=(8, 8))
html = resp.text
_video_url = re_video_base_url.search(html)
_audio_url = re_audio_base_url.search(html)
_video_name = re_video_name.search(html)
video_url = _video_url.group(1) if _video_url else ''
audio_url = _audio_url.group(1) if _audio_url else ''
video_name = _video_name.group(1) if _video_name else ''
if not (audio_url and video_url):
print('请求失败')
sys.exit()
return video_url, audio_url, video_name
def create_cache_directory():
if not os.path.exists('BVcache'):
os.mkdir('BVcache')
if not os.path.exists('Output'):
os.mkdir('Output')
def get_bvid(url):
create_cache_directory()
return url.split('/')[4].split('?')[0]
def main(url):
bvid = get_bvid(url)
video_url, audio_url, video_name = get_video_and_audio_url_from_bilibili(url)
video_filename = f'BVcache/video_{bvid}.m4s'
audio_filename = f'BVcache/audio_{bvid}.m4s'
print(f'{video_name}: {bvid} 开始下载视频轨道数据...')
download_file(video_filename, video_url)
print(f'{video_name}: {bvid} 视频轨道下载完毕')
print(f'{video_name}: {bvid} 开始下载音频轨道数据...')
download_file(audio_filename, audio_url)
print(f'{video_name}: {bvid} 音频轨道下载完毕!')
system = (platform.platform()).lower()
if 'windows' in system:
ffmpeg_tool = r'.\tools\win\ffmpeg.exe'
elif 'macOS' in system:
ffmpeg_tool = './tools/mac/ffmpeg'
else:
ffmpeg_tool = './tools/linux/ffmpeg'
filename = video_name.replace(" ", "-") or bvid
ffmpeg_command = (
ffmpeg_tool + f' -i {video_filename} -i {audio_filename} -codec '
f'copy Output/{filename}.mp4'
)
# print(ffmpeg_command)
CMD(ffmpeg_command)
delete_cache_file(video_filename)
delete_cache_file(audio_filename)
print(f'{bvid} 视频mp4文件已经生成,请在当前运行路径中的"Output"文件夹中查看,'
f'生成的文件名称为: {filename}.mp4')
if __name__ == '__main__':
# url = 'https://www.bilibili.com/video/BV1yr4y1r7f6?spm_id_from=333.851.b_7265636f6d6d656e64.5'
url = "https://www.bilibili.com/bangumi/play/ep706667?spm_id_from=333.337.0.0"
url = "https://www.bilibili.com/video/BV1Px4y1G7Ua/?spm_id_from=333.1007.tianma.1-1-1.click&vd_source=cd66a46dd12ebbfbee468f99bda17ae2"
sess.headers.update({
# 'Cookies': ("Your Cookie")
})
main(url)
"""
运行环境: Linux、python
安装环境包:pip install requests
将上面的url修改为要下载的视频地址。
运行:python download.py
输出:视频mp4文件会存放到当前目录中的Output文件夹中
"""
最后:大佬们轻点骂
下载链接放上:https://quiryrain.lanzoue.com/iYkJD0knbpje 密码:52pj