下载准备
想要下载阿B的视频,可以使用一个现有的python库you-get,使用pip即可下载安装:
pip install you-get
然后,通过命令行就可以使用,并下载一个阿B视频了。
you-get 阿B视频地址
使用PYTHON下载
那么,如何通过python代码,来完成视频的下载呢?只需要这样做:
from you_get.common import any_download
url = "你要下载的阿B视频地址"
output_dir = "保存地址"
any_download(url=url, output_dir=output_dir, merge=True, info_only=False)
注意:可能存在一种可能,你使用的播放器支持的格式比较少,因此下载的视频无法播放,这种情况下,如果不想升级你的设备或者播放器,只需要简单的转换一下视频格式即可,比如说ffmpeg -i 输入视频名 -c:v libx264 -c:a aac 输出视频名
视频合并
当下载视频的时候,我们可能会观察到这样一个状况:下载的视频和音频是分开的,分成了两个文件,一个文件中只有视频,而另外一个文件中,只有音频
为什么会这样呢?因为,大多视频网站的视频流本身就是分开的,这样做有一些好处
-
视频和音频分开存储,可以更灵活地处理不同的网络状况,例如在网络条件不好的情况下,只给画面降低质量,不影响声音
-
允许某些用户只下载视频,或者只下载音频,例如一些视频可以选择无画面只播放音频
-
对于视频的剪辑和加工来说,分离的视频和音频更容易编辑和处理
因此,默认情况下,我们确实会下载到分离的音频和视频,但是,这可能给我们的视频下载造成了一些困扰:可是我只想看一个完整的视频啊,现在是两个文件,我该怎么办呢?
确实,我们已经在python的代码中,指定了merge=True
,但是,只是这样,还不足以保证视频可以合并,因为,我们的系统中,还必须有支持合并视频的工具,例如:ffmpeg
,只有在包含了这样的视频处理工具以后,才能够做到自动的合并音频和视频。
例如,我们可以这样使用命令(这里假设我们下载到了分离的视频和音频):
ffmpeg -i '视频名[00].mp4' -i '视频名[01].mp4' -c:v copy -c:a aac -strict experimental '视频名.mp4'
可以看到,这样,我们就轻松,将视频和音频合并成了一个视频文件。当然,如果你不喜欢使用ffmpeg,自然也有很多其他的视频合并工具可以选择,你可以随意的使用你喜欢用的视频合并工具,来得到一个完整的视频。
下载高质量视频
在刚刚的使用过程中,我们观察到,默认情况下,下载的视频只有480p,这肯定不能让人满意,有没有办法可以下载到更高清的视频呢?答案是可以,但是我们需要登录以后,得到登录cookie,然后使用这段cookie,下载更高清的视频。
一般来说,首先,需要通过网站登录自己的bilibili账号,然后从浏览器中获取到其中的cookies。不过需要注意的是,在you-get的使用中,并不直接使用cookies的字符串,而是需要使用Netscape HTTP Cookie File这样的格式。这通常需要通过一些浏览器插件获取
之后,导出cookie以后,起名叫做cookies.txt,然后使用命令:
you-get -c cookies.txt 视频地址
就可以做到高清视频的下载了,如果你需要查看有哪些不同的视频种类可以选择,可以使用
you-get -i -c cookies.txt 视频地址
此时,可以看到多种可以选择的格式,然后根据提示,就可以选择心仪的视频格式进行下载了
仿阿B唧唧视频下载
创建一个视频下载任务
import subprocess
import uuid
from celery import Celery
celery = Celery('tasks', broker='redis://localhost:6379/0', backend='redis://localhost:6379/1')
celery.conf.broker_connection_retry_on_startup = True
@celery.task
def bilibili_download(url):
file_name = str(uuid.uuid4())
command = [
"you-get",
"-o", "./videos",
"-O", file_name,
"--no-caption",
url
]
result = subprocess.run(command, capture_output=True, text=True)
return file_name
创建web应用
from flask import Flask, request, render_template, jsonify, send_file, abort
from urllib.parse import urlparse
from tasks import bilibili_download, celery
from celery.result import AsyncResult
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/submit", methods=["POST"])
def submit():
url = request.form["url"]
parsed_url = urlparse(url)
if not parsed_url.netloc.endswith("bilibili.com"):
return abort(400, description="不允许的下载源")
result = bilibili_download.delay(url)
task_id = result.id
return jsonify({"task_id": task_id, "message": "请等待...下载正在进行中"})
@app.route("/status")
def check_status():
task_id = request.args.get("task_id")
result = AsyncResult(task_id, app=celery)
if result.status == "SUCCESS":
return jsonify({"status": "completed", "message": "下载完成,可以下载了"})
elif result.status == "PENDING":
return jsonify({"status": "pending", "message": "请等待...下载正在进行中"})
else:
return jsonify({"status": "failed", "message": "抱歉,下载失败"})
@app.route("/download", methods=["GET"])
def download():
task_id = request.args.get("task_id")
path = AsyncResult(task_id, app=celery).get()
file_path = f"./videos/{path}.mp4"
return send_file(file_path, as_attachment=True)
提供index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>仿bilibili唧唧</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<style>
body {
font-family: Arial, sans-serif;
padding: 20px;
background-color: #f4f4f4;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
margin: 0;
}
form {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
width: 90%;
max-width: 500px;
}
label {
display: block;
margin-bottom: 10px;
color: #333;
}
input[type="text"] {
width: calc(100% - 22px);
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
margin-bottom: 20px;
}
button {
background-color: #00a1d6;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
width: 100%;
font-size: 16px;
}
button:hover {
background-color: #008cb3;
}
#downloadLink {
margin-top: 20px;
display: none;
background: #4CAF50;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 5px;
}
@media (max-width: 600px) {
form {
width: 100%;
box-shadow: none;
}
}
</style>
<script>
function submitForm() {
var url = document.getElementById('url').value;
$.post('/submit', {url: url}, function(data) {
alert(data.message);
pollStatus(data.task_id);
});
}
function pollStatus(task_id) {
$.get('/status', {task_id: task_id}, function(data) {
if (data.status === 'completed') {
var downloadLink = document.getElementById('downloadLink');
downloadLink.style.display = 'block';
downloadLink.href = '/download?task_id=' + task_id;
} else {
setTimeout(function() { pollStatus(task_id); }, 5000);
}
});
}
</script>
</head>
<body>
<form onsubmit="event.preventDefault(); submitForm();">
<label for="url">下载地址(只允许使用标准的bilibili视频地址):</label>
<input type="text" id="url" name="url">
<button type="submit">提交</button>
</form>
<div>
<a id="downloadLink" href="#">点击下载文件</a>
</div>
</body>
</html>
这样,我们输入一个地址,就可以开始视频下载了
本文章的使用方法及仅供学习和交流使用,下载视频应该在24小时内及时删除。
如因恶意使用或侵犯版权而产生的任何法律责任,均与本文章的作者无关。