目录
前言
视频id
视频设定一个视频id
定义为
xxxxxxx/video/xxx
# video 后面的内容定义为视频id
ffmpeg
b站的视频,下载下来,其中音频和视频是分开的,你也可以用pr之类的,把二者合并,我选择用这个ffmaeg
这个主要是要下载-------FFmpeg
可以和python的第三方库结合使用,也可以直接用命令行
我选择的是用命令行
其他
其他都是第三方库,pip一下就可以了
正文
pyqt5代码
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class bili(QDialog):
def __init__(self):
super().__init__()
self.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
self.label_2 = None
self.qe = None
self.label = None
self.ok = None
self.loser = None
self.initui()
def initui(self):
self.resize(754, 389)
icon = QIcon()
icon.addPixmap(QPixmap("../../图片/图片/6.jpg"), QIcon.Normal, QIcon.Off)
self.setWindowIcon(icon)
self.ok = QPushButton(self)
self.ok.setText("确定")
self.ok.clicked.connect(self.get_sp)
self.ok.setGeometry(250, 190, 93, 28)
self.qe = QLineEdit(self)
self.qe.setGeometry(340, 120, 231, 21)
self.label = QLabel(self)
self.label.setGeometry(330, 50, 72, 41)
self.label.setTextFormat(Qt.RichText)
self.label_2 = QLabel(self)
self.label_2.setGeometry(270, 120, 72, 15)
self.loser = QPushButton(self)
self.loser.setText("取消")
self.loser.clicked.connect(self.lose)
self.loser.setGeometry(370, 190, 93, 28)
self.setWindowTitle("bilibili")
self.label.setText("<html><head/><body><p align=\"center\"><span style=\" font-size:18pt; font-weight:600; color:#3108ff;\">b站</span></p></body></html>")
self.label_2.setText("输入id:")
def get_sp(self):
text=self.qe.text()
if text:
from b_sp import Bili
# 如果输入了视频id
Bili(text).start()
else:
QMessageBox.information(self, '消息', '视频id不能为空', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
def lose(self):
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle(QStyleFactory.create('Fusion'))
a = bili()
a.show()
sys.exit(app.exec_())
结果
页面简单,没有什么多说的
feapder页ffmpeg页面
import feapder
from feapder.setting import DEFAULT_USERAGENT
import re
import json
import jsonpath
import subprocess
import os
sp_path='xxxx'
# 主要是对视频和音频的合并
class ps:
def __init__(self):
self.cmd=None
def run(self):
subprocess.call(self.cmd,shell=True)
def video_add_audio(self,mp3_file,mp4_file):
outfile_name = mp4_file.split('.')[0] + '-new.mp4'
cmd = f'ffmpeg -i {mp4_file} -i {mp3_file} -acodec copy -vcodec copy {outfile_name}'
self.cmd = cmd
return self
class Bili(feapder.AirSpider):
def __init__(self,sp_id:str):
super().__init__()
self.mp3_path = None
self.mp4_path = None
self.sp_id=sp_id
def start_requests(self):
yield feapder.Request(f'https://www.bilibili.com/video/{self.sp_id}',download_midware=self.download_midware)
def download_midware(self, request):
request.headers={
'user-agent':DEFAULT_USERAGENT,
'Referer': 'https://www.bilibili.com/',
}
return request
def parse(self, request, response):
text=response.text
self.title=self.sp_id.split('/')[0]
# 标题决定采用视频的id里面的内容作为标题,因为标题会用不正确的符号,干扰后续的操作
play_info=re.findall('<script>window.__playinfo__=(.*?)</script>',text)[0]
json_data=json.loads(play_info)
audio=jsonpath.jsonpath(json_data,'$..audio[0].backup_url[0]')[0]
video=jsonpath.jsonpath(json_data,'$..video[0].backup_url[0]')[0]
yield feapder.Request(audio,callback=self.mp3_save_sp)
yield feapder.Request(video,callback=self.mp4_save_sp)
def mp3_save_sp(self,request,response):
self.mp3_path=sp_path+self.title+'.mp3'
with open(self.mp3_path,'wb') as f:
f.write(response.content)
def mp4_save_sp(self, request, response):
self.mp4_path = sp_path + self.title + '.mp4'
with open(self.mp4_path,'wb') as f:
f.write(response.content)
self.union()
def union(self):
add=ps()
add.video_add_audio(self.mp3_path,self.mp4_path).run()
os.remove(self.mp3_path)
os.remove(self.mp4_path)
最后
实际操作可自己尝试
(0.0)(0.0)(0.0)