本帖最后由 52pjmolian 于 2025-11-4 13:54 编辑
搞了一个简易B站音视频下载脚本,魔域掉钱版怎么样结合AI加以优化
附件为txt文件需要修改成.js进行安装
开发思路:解析HTML中音视频m4s地址,直接下载
注:下载后音视频是分开的,可以使用FFMPEG合并
参考:ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a copy -map 0:v:0 -map 1:a:0 output.mp4
直接通过油猴安装即可使用
!!!仅限个人使用!!!
[JavaScript] 纯文本查看 复制代码
// ==UserScript==
// @name
B站视频下载器(稳定版)
// @namespace
// @version
3.0
// @description 稳定下载B站音视频,提供本地合并指南
// @AuThor
You
// @match
https://www.bilibili.com/video/*
// @match
https://www.bilibili.com/bangumi/play/*
// @grant
none
// @run-at
document-end
// ==/UserScript==
(function() {
'use strict';
console.log('🚀 B站视频下载器启动 - 稳定版');
class BilibiliDownloader {
constructor() {
this.playInfo = null;
this.init();
}
init() {
this.createDownloadButton();
this.findPlayInfo();
this.addGlobalStyles();
}
// 添加全局样式
addGlobalStyles() {
const style = document.createElement('style');
style.textContent = `
.bilibili-downloader-btn {
position: fixed !important;
bottom: 20px !important;
right: 20px !important;
background: #00a1d6 !important;
color: white !important;
border: none !important;
border-radius: 20px !important;
padding: 10px 15px !important;
font-size: 14px !important;
font-weight: bold !important;
cursor: pointer !important;
z-index: 10000 !important;
box-shadow: 0 2px 10px rgba(0,0,0,0.3) !important;
transition: all 0.3s !important;
font-family: Arial, sans-serif !important;
}
.bilibili-downloader-btn:hover {
transform: scale(1.05) !important;
background: #0087b3 !important;
}
.bilibili-downloader-panel {
position: fixed !important;
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
background: rgba(0,0,0,0.95) !important;
color: white !important;
border: 2px solid #00a1d6 !important;
border-radius: 10px !important;
padding: 20px !important;
z-index: 10001 !important;
width: 500px !important;
max-width: 90vw !important;
max-height: 80vh !important;
overflow-y: auto !important;
box-shadow: 0 4px 20px rgba(0,0,0,0.5) !important;
font-family: Arial, sans-serif !important;
}
.bilibili-downloader-panel h3 {
color: #00a1d6 !important;
margin: 0 0 15px 0 !important;
text-align: center !important;
}
.bilibili-downloader-panel .close-btn {
position: absolute !important;
top: 10px !important;
right: 15px !important;
background: none !important;
border: none !important;
color: white !important;
font-size: 20px !important;
cursor: pointer !important;
width: 30px !important;
height: 30px !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
.bilibili-downloader-panel .close-btn:hover {
background: rgba(255,255,255,0.1) !important;
}
.bilibili-downloader-panel .section {
margin-bottom: 20px !important;
}
.bilibili-downloader-panel .section-title {
color: #ffa500 !important;
font-weight: bold !important;
margin-bottom: 10px !important;
font-size: 14px !important;
}
.bilibili-downloader-panel .file-item {
background: rgba(255,255,255,0.05) !important;
padding: 10px !important;
margin-bottom: 8px !important;
border-radius: 5px !important;
border-left: 3px solid #00a1d6 !important;
}
.bilibili-downloader-panel .file-info {
display: flex !important;
justify-content: space-between !important;
align-items: center !important;
margin-bottom: 5px !important;
}
.bilibili-downloader-panel .quality-badge {
background: #ffa500 !important;
color: black !important;
padding: 2px 6px !important;
border-radius: 3px !important;
font-size: 10px !important;
font-weight: bold !important;
}
.bilibili-downloader-panel .download-btn {
background: #27ae60 !important;
color: white !important;
border: none !important;
padding: 5px 10px !important;
border-radius: 3px !important;
cursor: pointer !important;
font-size: 12px !important;
}
.bilibili-downloader-panel .download-btn:hover {
background: #219653 !important;
}
.bilibili-downloader-panel .merge-guide {
background: rgba(255,255,255,0.1) !important;
padding: 15px !important;
border-radius: 5px !important;
margin-top: 20px !important;
font-size: 12px !important;
}
.bilibili-downloader-panel .code-block {
background: #1a1a1a !important;
color: #00ff00 !important;
padding: 10px !important;
border-radius: 3px !important;
font-family: 'Courier New', monospace !important;
font-size: 11px !important;
margin-top: 8px !important;
overflow-x: auto !important;
}
`;
document.head.appendChild(style);
}
// 创建下载按钮
createDownloadButton() {
const button = document.createElement('button');
button.className = 'bilibili-downloader-btn';
button.innerHTML = '📥 下载视频';
button.title = 'B站视频下载工具';
button.onclick = () => this.showDownloadPanel();
document.body.appendChild(button);
console.log('✅ 下载按钮创建成功');
}
// 显示下载面板
showDownloadPanel() {
// 移除旧面板
const oldPanel = document.getElementById('bilibili-downloader-panel');
if (oldPanel) oldPanel.remove();
if (!this.playInfo) {
this.showNotification('❌ 未找到视频数据,请刷新页面重试', 'error');
return;
}
const panel = document.createElement('div');
panel.id = 'bilibili-downloader-panel';
panel.className = 'bilibili-downloader-panel';
panel.innerHTML = this.generatePanelHTML();
document.body.appendChild(panel);
this.bindPanelEvents(panel);
console.log('✅ 下载面板创建成功');
}
// 生成面板HTML
generatePanelHTML() {
const videos = this.getVideos();
const audios = this.getAudios();
return `
<button class="close-btn">×</button>
<h3>🎬 B站视频下载器</h3>
<div class="section">
<div class="section-title">🎥 视频流 (${videos.length}个)</div>
${videos.length > 0 ? this.generateFileListHTML(videos, 'video') : '<div style="opacity:0.7;font-size:12px;">暂无视频数据</div>'}
</div>
<div class="section">
<div class="section-title">🔊 音频流 (${audios.length}个)</div>
${audios.length > 0 ? this.generateFileListHTML(audios, 'audio') : '<div style="opacity:0.7;font-size:12px;">暂无音频数据</div>'}
</div>
${videos.length > 0 && audios.length > 0 ? `
<div class="merge-guide">
<div style="color:#ffa500;font-weight:bold;margin-bottom:8px;">💡 本地合并指南</div>
<div style="margin-bottom:8px;">下载后使用FFmpeg合并音视频:</div>
<div class="code-block">
# Windows CMD<br>
ffmpeg -i video.mp4 -i audio.m4a -c copy output.mp4<br><br>
# Linux/Mac Terminal<br>
ffmpeg -i video.mp4 -i audio.m4a -c copy output.mp4<br><br>
# 批量合并脚本<br>
for %%i in (*.mp4) do ffmpeg -i "%%i" -i "%%~ni.m4a" -c copy "merged_%%i"
</div>
<div style="margin-top:8px;font-size:11px;opacity:0.8;">
📖 <a href="https://ffmpeg.org/download.html" target="_blank" style="color:#00a1d6;">下载FFmpeg</a>
</div>
</div>
` : ''}
<div style="text-align:center;margin-top:15px;font-size:11px;opacity:0.7;">
💪 稳定可靠 · 无需额外依赖
</div>
`;
}
// 生成文件列表HTML
generateFileListHTML(files, type) {
return files.map((file, index) => {
const quality = file.id || '未知';
const codecs = file.codecs || '未知编码';
const bandwidth = file.bandwidth ? ` (${Math.round(file.bandwidth/1000)}kbps)` : '';
const url = file.baseUrl || file.base_url || '';
return `
<div class="file-item">
<div class="file-info">
<div>
<span class="quality-badge">${quality}P</span>
<span style="font-size:12px;">${codecs}${bandwidth}</span>
</div>
<button class="download-btn" data-type="${type}" data-index="${index}">
下载
</button>
</div>
<div style="font-size:10px;opacity:0.7;word-break:break-all;">
${url.substring(0, 80)}...
</div>
</div>
`;
}).join('');
}
// 绑定面板事件
bindPanelEvents(panel) {
const downloadButtons = panel.querySelectorAll('.download-btn');
downloadButtons.forEach(btn => {
btn.onclick = (e) => {
const type = e.target.getAttribute('data-type');
const index = parseInt(e.target.getAttribute('data-index'));
this.downloadFile(type, index);
};
});
}
// 下载文件
downloadFile(type, index) {
const files = type === 'video' ? this.getVideos() : this.getAudios();
if (!files || !files[index]) {
this.showNotification('❌ 文件不存在', 'error');
return;
}
const file = files[index];
const url = file.baseUrl || file.base_url;
if (!url) {
this.showNotification('❌ 无效的URL', 'error');
return;
}
const extension = type === 'video' ? '.mp4' : '.m4a';
const filename = this.generateFilename(file, type, index, extension);
this.startDownload(url, filename);
this.showNotification(`✅ 开始下载: ${filename}`, 'success');
}
// 生成文件名
generateFilename(file, type, index, extension) {
// 获取视频标题
let title = 'bilibili_video';
try {
const titleElement = document.querySelector('h1.video-title, title');
if (titleElement) {
title = titleElement.textContent
.replace(/[<>:"/\\|?*]/g, '_')
.substring(0, 30)
.trim();
}
} catch (e) {
console.log('获取标题失败,使用默认名称');
}
return `${title}_${type}_${file.id || index}${extension}`;
}
// 开始下载
startDownload(url, filename) {
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
console.log(`⬇️ 下载: ${filename}`);
}
// 查找playinfo数据(增强版)
findPlayInfo() {
console.log('🔍 开始查找视频数据...');
let attempts = 0;
const maxAttempts = 8;
const search = () => {
attempts++;
console.log(`🔄 第${attempts}次查找...`);
// 方法1: 直接检查window对象
if (window.__playinfo__) {
console.log('✅ 从window.__playinfo__找到数据');
this.playInfo = window.__playinfo__;
this.onPlayInfoFound();
return;
}
// 方法2: 搜索所有script标签
const scripts = document.querySelectorAll('script');
console.log(`📊 扫描 ${scripts.length} 个script标签`);
for (let i = 0; i < scripts.length; i++) {
const script = scripts[i];
const content = script.textContent || script.innerHTML || '';
if (content.includes('window.__playinfo__')) {
console.log(`✅ 在第${i+1}个script标签中找到目标`);
const patterns = [
/window\.__playinfo__\s*=\s*({[\s\S]*?})\s*;/,
/<script>window\.__playinfo__\s*=\s*({[\s\S]*?})<\/script>/,
/window\.__playinfo__\s*=\s*({.*?})(?=window\.__|<\/script>|$)/
];
for (let j = 0; j < patterns.length; j++) {
const match = content.match(patterns[j]);
if (match) {
console.log(`🎯 使用模式${j+1}匹配成功`);
try {
this.playInfo = JSON.parse(match[1]);
console.log('✅ JSON解析成功');
this.onPlayInfoFound();
return;
} catch (error) {
console.error('❌ JSON解析错误,尝试修复...');
// 尝试修复JSON
try {
const fixed = this.fixJson(match[1]);
this.playInfo = JSON.parse(fixed);
console.log('🔧 修复后解析成功');
this.onPlayInfoFound();
return;
} catch (e2) {
console.error('❌ 修复后仍然解析失败');
continue;
}
}
}
}
}
}
// 如果没找到,准备重试
if (attempts < maxAttempts) {
const delay = attempts * 1000;
console.log(`⏳ 未找到数据,${delay}ms后重试...`);
setTimeout(search, delay);
} else {
console.log('❌ 达到最大重试次数,停止查找');
this.showNotification('⚠️ 未找到视频数据,部分视频可能需要登录', 'warning');
}
};
// 延迟启动,确保页面加载完成
setTimeout(search, 1000);
}
// 修复JSON格式
fixJson(jsonStr) {
return jsonStr
.replace(/'/g, '"') // 单引号转双引号
.replace(/([a-zA-Z_$][a-zA-Z0-9_$]*):/g, '"$1":') // 属性名加引号
.replace(/,\s*}/g, '}') // 移除尾随逗号
.replace(/,\s*]/g, ']') // 移除数组尾随逗号
.replace(/\/\/.*$/gm, '') // 移除单行注释
.replace(/\/\*[\s\S]*?\*\//g, ''); // 移除多行注释
}
// 找到数据后的处理
onPlayInfoFound() {
console.log('🎉 视频数据加载成功');
// 更新按钮状态
const button = document.querySelector('.bilibili-downloader-btn');
if (button) {
button.innerHTML = '✅ 就绪';
button.style.background = '#27ae60';
}
// 显示成功通知
this.showNotification('✅ 视频数据加载完成,可以下载了', 'success');
}
// 获取视频流
getVideos() {
if (!this.playInfo || !this.playInfo.data) return [];
return this.playInfo.data.dash?.video || [];
}
// 获取音频流
getAudios() {
if (!this.playInfo || !this.playInfo.data) return [];
return this.playInfo.data.dash?.audio || [];
}
// 显示通知
showNotification(message, type = 'info') {
const colors = {
info: '#3498db',
success: '#27ae60',
error: '#e74c3c',
warning: '#f39c12'
};
const notification = document.createElement('div');
notification.innerHTML = message;
notification.style.cssText = `
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background: ${colors[type]};
color: white;
padding: 10px 20px;
border-radius: 5px;
z-index: 10002;
font-family: Arial, sans-serif;
box-shadow: 0 2px 10px rgba(0,0,0,0.3);
max-width: 80vw;
text-align: center;
`;
document.body.appendChild(notification);
setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 3000);
}
}
// 启动下载器
setTimeout(() => {
console.log('🎯 启动B站视频下载器...');
window.bilibiliDownloader = new BilibiliDownloader();
}, 1000);
})();
3810239a-fdfd-43b2-ab85-81e8f27072dd.png
(376.36 KB, 下载次数: 11)
下载附件
2025-11-4 08:35 上传


B站视频下载器(稳定版)-3.0.user.txt
2025-11-4 13:54 上传
点击文件名下载附件
下载积分: 吾爱币 -1 CB
19.82 KB, 下载次数: 146, 下载积分: 吾爱币 -1 CB
附件
免费评分
参与人数 13吾爱币 +11
热心值 +13
理由

fate1949
+ 1
+ 1
热心回复!

cwwloveyu
+ 1
+ 1
我很赞同!

sdlions
+ 1
+ 1
谢谢@Thanks!

wa00000
+ 1
+ 1
感谢发布原创作品,吾爱破解论坛因你更精彩!

GoldenLumi
+ 1
+ 1
我很赞同!大神厉害,我个人用的bilibili evolved,下载不是很方便,抽空上 ...

ccchpig
+ 1
我很赞同!

astonlake
+ 1
+ 1
感谢发布原创作品,吾爱破解论坛因你更精彩!

Maniac319
+ 1
+ 1
谢谢@Thanks!

固相膜
+ 1
+ 1
感谢分享。窗口无法关闭。需关闭网页。

xlln
+ 1
+ 1
我很赞同!

hwh425
+ 1
谢谢@Thanks!

脑子进秋刀鱼
+ 1
+ 1
我很赞同!

yp17792351859
+ 1
+ 1
感谢发布原创作品,吾爱破解论坛因你更精彩!
查看全部评分