栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

用浏览器下载B 站视频 - 并用脚本 + ffmpeg 合并文件

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

用浏览器下载B 站视频 - 并用脚本 + ffmpeg 合并文件

这篇文章介绍了用浏览器扩展下载B 站视频的一种方法:使用Firefox 浏览器的ant 扩展程序分别下载视频和音频文件,然后用个python 脚本拿ffmpeg 批量合并下载的文件。其中下载部分chrome 应该也有相应的扩展程序能用,或许还有能直接下载,不用多费功夫合并的呢。

you-get 偶尔不好使,浏览器下载相对普适一些。

浏览器扩展

在Firefox 扩展商店里找到Ant Video Downloader,Ant 视频下载器,貌似这个扩展chrome 也有。其他多数视频网站用这个也能下载。
装上扩展,然后按提示装上扩展的本地帮助程序,一个exe。类似的下载器好像都有这种需求。

下载视频

装好Ant 扩展后点开一个视频,应该会自动检测到,点击扩展的图标后会看到一堆文件,要下载的是这两个m4s 文件。其中较大的是视频部分,另一个是音频。如果清晰度选了自动的话有可能会嗅探到更多视频文件,总之默认选1080P 就好了。
可以在扩展设置里调整文件的下载路径。最快的到达方式是新建个标签页,点扩展按钮,再点右下角的三横线。
下载完之后来到下载目录,不出意外应该可以看到两个同名的mp4 文件,所以其中一个被自动加了(1) 后缀。用不着分辨两个里面哪个是视频哪个是音频。

用ffmpeg 合并文件

ffmpeg 合并文件的命令参考这篇如何把手机上的B站视频导入电脑观看:使用 FFmpeg(bilibili视频m4s合成mp4)。可以加一个-hide_banner 选项让ffmpeg 的输出稍微清爽一点。

ffmpeg -hide_banner -i video.mp4 -i audio.mp4 -codec copy out.mp4

当然手动敲命令太烦了,还得改文件名,一次多下载几个视频的话简直不能活。所以总之先下载装好ffmpeg,加进PATH。这里可以使用scoop 或者chocolatey 安装。

脚本

我的本地环境是Python 3.9,没试过其他版本,就不介绍怎么准备环境了,除了ffmpeg 以外没有别的依赖。批量转换文件的操作写成了一个函数merge_bili_mp4,方便用。这个脚本假设每个视频有且只有两个文件,每个文件名都是ant 下载的原始状态,其中一个带有(1) 后缀,其他情况都会报错。
发现有时候还会下载到m4s 后缀的文件,所以又改了一下代码。

import os
import re
from collections import Counter
from pathlib import Path
from typing import Union

def merge_bili_mp4(parent_dir: Union[str, Path]):
    count = 0
    os.chdir(str(parent_dir))
    l = filter(lambda f: f.startswith('bili') and f.endswith('mp4') or f.endswith('m4s'), os.listdir())
    p = r'( (d))'
    lm = map(lambda f: re.sub(p, '', f), l)
    c = Counter(lm)
    for k in c:
        print(f'-> working on: {k}.')
        if c[k] != 2:
            print(f'!> file components count is not 2, skip.')
            continue
        out_name = k[15:-4]
        k_name = k[:-4]
        k_ext = k[-4:]
        os.system(f'ffmpeg -hide_banner -i "{k}" -i "{k_name} (1){k_ext}" -codec copy "{out_name}.mp4"')
        count += 1
    print(f'-> all count: {count}')

具体的原理就不细说了,也没什么值得说的,用视频下载路径当参数调用函数就行。过程中不会删除或者修改文件,所以很安全~

使用脚本

推荐把脚本存到一个.py 文件,然后放到PYTHON_HOME 里面,之后就可以方便的当模块import, 然后调用函数,比如在ptpython 里当命令用。
第一行是从我的模块文件rock_hammer 里把函数import 进来。ffmpeg 会输出一大串,无所谓,没有标红的就没问题,最后一行输出的-> all count: 是转换过的视频数量,可以看一下和期望视频数量是否相符。
然后回到下载目录,可以看到已经有输出文件了,文件名改了一下,把没用的网址前缀去掉了。
可以另外写个用来调用函数的脚本,把文件放到下载目录里,一双击就自动执行,如下。也可以直接把函数放到这脚本里,搞个一站式。

import os
from rock_hammer import merge_bili_mp4

HERE_PATH = os.path.dirname(__file__)
merge_bili_mp4(HERE_PATH)
os.system('pause')
附件 - 1

一站式的脚本文件,函数和执行部分合到一起了。把脚本文件放到下载目录之后双击运行。

merge_bili_mp4.py

import os
import re
from collections import Counter
from pathlib import Path
from typing import Union


def merge_bili_mp4(parent_dir: Union[str, Path]):
    count = 0
    os.chdir(str(parent_dir))
    l = filter(lambda f: f.startswith('bili') and f.endswith('mp4') or f.endswith('m4s'), os.listdir())
    p = r'( (d))'
    lm = map(lambda f: re.sub(p, '', f), l)
    c = Counter(lm)
    for k in c:
        print(f'-> working on: {k}.')
        if c[k] != 2:
            print(f'!> file components count is not 2, skip.')
            continue
        out_name = k[15:-4]
        k_name = k[:-4]
        k_ext = k[-4:]
        os.system(f'ffmpeg -hide_banner -i "{k}" -i "{k_name} (1){k_ext}" -codec copy "{out_name}.mp4"')
        count += 1
    print(f'-> all count: {count}')

if __name__ == '__main__':
    HERE_PATH = os.path.dirname(__file__)
    merge_bili_mp4(HERE_PATH)
    os.system('pause')
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/307557.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号