一、前言
有时候,我们想缓存下来b站上的一些视频,做一些剪辑什么的。
但是在电脑端,bilibili的网站没有提供视频缓存功能。而手机端的bilibili客户端可以缓存视频,但格式为m4s。
这就给我们提供一个思路:先在手机上哔哩哔哩客户端缓存好视频,再通过ES文件浏览器的ftp传输功能,将m4s文件传输给电脑,再将m4s转化为mp4格式。
二、实际操作
手机端利用现成的软件进行操作就行,电脑端使用我自己写的程序进行操作。
手机端需要的软件:哔哩哔哩客户端 , ES文件浏览器
电脑端需要的软件:自写的传输工具
操作流程图:
详细操作流程:
1.打开哔哩哔哩客户端,缓存好视频
2.打开ES文件浏览器,打开“从PC访问”功能,记下这个ftp地址
3.手机打开WiFi热点,电脑连接上WiFi热点,以保证处于同一个局域网内
4.从百度云盘下载我写的软件(提取码:y1sv),解压后,打开auto/文件夹,打开ftp_address.txt,输入ftp的地址,保存。
5.双击auto/下的auto.exe,程序会自动传输手机哔哩哔哩客户端的缓存视频,等待传输完成即可。
如果当中程序不动,可以在程序运行界面中按下回车键进行刷新。
6.传输好的视频,会自动保存到auto/video目录下
三、电脑端程序源码
电脑端程序通过python编写,文件传输用ftp,m4s转mp4用ffmpeg.exe(可在我分享的网盘中下载)。
在下载好ffmpeg.exe到这个脚本的同一目录下,然后电脑与手机热点wifi连接后,手机端开启ES文件浏览器的“从PC访问”功能,再运行该python脚本就能进行视频传输了。
不过考虑到有些电脑不一定安装有python环境,我使用pyinstaller将python脚本转化为exe执行文件,使得程序在没有python环境上的windows下也能运行。
import os
import sys
import time
import json
from ftplib import FTP
video_save_path = './video/' # 视频目录不能是中文
danmu_save_path = './弹幕/'
if not os.path.exists(danmu_save_path):
os.makedirs(danmu_save_path)
if not os.path.exists(video_save_path):
os.makedirs(video_save_path)
def FTP_Transport_Video(ftp_address):
# 登录FTP
address = ftp_address.split(':')[1][2:]
port = int(ftp_address.split(':')[-1][:4])
ftp = FTP()
ftp.connect(address, port)
ftp.login(user='', passwd='')
print(ftp.getwelcome())
data = []
ftp.cwd('Android/data/tv.danmaku.bili/download/')
ftp.dir(data.append)
print('检测到%d个缓存视频' % (len(data)))
for idx, line in enumerate(data):
second_dir = line.split(' ')[-1]
second_dir = './' + second_dir + '/1'
ftp.cwd(second_dir)
# 读取视频名称
file_handle = open('./entry.json', "wb")
ftp.retrbinary("RETR entry.json", file_handle.write, 1024)
file_handle.close()
entry_json = open('entry.json', encoding='utf-8')
data1 = json.load(entry_json)
title = data1['title']
print('正在传输第'+str(idx+1)+'个视频...')
print('\t视频名称:'+title)
# 保存弹幕
file_handle = open(danmu_save_path+title+'.xml', "wb")
ftp.retrbinary("RETR danmaku.xml", file_handle.write, 1024)
file_handle.close()
# 保存视频
video_path = video_save_path + title + '.mp4'
if os.path.exists('./video/temp.mp4'):
os.remove('./video/temp.mp4')
if os.path.exists(video_path):
print('\t视频已存在')
ftp.cwd('../../')
continue
file_handle = open('audio.m4s', "wb")
ftp.retrbinary("RETR 80/audio.m4s", file_handle.write, 2048)
file_handle.close()
file_handle = open('video.m4s', "wb")
ftp.retrbinary("RETR 80/video.m4s", file_handle.write, 2048)
file_handle.close()
command = 'ffmpeg.exe -i video.m4s -i audio.m4s -codec copy ./video/temp.mp4'
os.system('\t'+command)
os.rename('./video/temp.mp4', video_path)
print('第'+str(idx+1)+'个视频传输完成!')
ftp.cwd('../../')
print('所有视频传输完成')
ftp.quit()
if os.path.exists('./audio.m4s'):
os.remove('./audio.m4s')
if os.path.exists('./video.m4s'):
os.remove('./video.m4s')
#if os.path.exists('./entry.json'):
# os.remove('./entry.json')
if __name__ == '__main__':
if os.path.exists('./ftp_address.txt'):
with open('ftp_address.txt', 'r') as f:
ftp_address = f.readline()
print('正在连接:', ftp_address)
FTP_Transport_Video(ftp_address)
else:
print('未检测到ftp_address.txt')