用語(yǔ)音識(shí)別+python自動(dòng)發(fā)送彈幕,變成B站野生字幕君吧!

? ? 在B站觀看視頻的時(shí)候,有時(shí)候一些帶有旁白但沒(méi)有字幕的視頻,會(huì)有野生字幕君出現(xiàn),貼心的為視頻加上字幕,大大提高了視頻觀感。不過(guò)手工加字幕是一件很麻煩的事,需要人工卡時(shí)間和聽(tīng)譯打字。當(dāng)一個(gè)懶人程序媛想當(dāng)一個(gè)野生字幕君的時(shí)候,就衍生出了這篇文章……本文將介紹如何通過(guò)語(yǔ)音識(shí)別+python請(qǐng)求自動(dòng)發(fā)送B站彈幕。
1. 下載視頻
下載B站視頻的方法很多,比如這個(gè)B站、嗶哩嗶哩視頻解析下載在線工具或者chrome插件bilibili嗶哩嗶哩下載助手都可以。Anyway,能下載就行。
2. 將視頻轉(zhuǎn)換為音頻
這步是為了后面語(yǔ)音識(shí)別時(shí)比較省時(shí)。同樣,轉(zhuǎn)換軟件或者在線網(wǎng)站有很多,這里就不介紹了。Anyway,能轉(zhuǎn)換就行。
3. 語(yǔ)音識(shí)別
這里推薦一個(gè)很好用的在線平臺(tái)網(wǎng)易見(jiàn)外工作臺(tái),不僅免費(fèi),而且可以將音頻轉(zhuǎn)換為帶時(shí)間軸的文字,正好符合我們的需求。網(wǎng)易見(jiàn)外工作臺(tái)支持的項(xiàng)目也很多:

選擇新建項(xiàng)目-->語(yǔ)音轉(zhuǎn)寫(xiě)-->填寫(xiě)項(xiàng)目名稱(chēng)、上傳音頻、選擇語(yǔ)言、出稿類(lèi)型選擇字幕,然后提交就可以了。大約等待幾分鐘,就可以得到轉(zhuǎn)換后的結(jié)果。

這里以B站的演講《后浪》為例,打開(kāi)轉(zhuǎn)換后的結(jié)果,可以看到內(nèi)容和起始終止時(shí)間已經(jīng)被識(shí)別出來(lái)了。但有些地方識(shí)別的并不準(zhǔn),我們可以點(diǎn)擊下方播放音頻,然后逐行對(duì)時(shí)間和內(nèi)容進(jìn)行一些編輯調(diào)整。最后點(diǎn)擊導(dǎo)出,將下載一個(gè).srt格式的文件。

4. 使用python自動(dòng)發(fā)送B站彈幕
4.1. B站發(fā)送彈幕的報(bào)文分析
我們隨便在B站找一個(gè)視頻發(fā)送彈幕,然后打開(kāi)瀏覽器的開(kāi)發(fā)者模式(快捷鍵:F12)進(jìn)行抓包。報(bào)文的核心內(nèi)容如下:


可以看到,B站發(fā)送彈幕使用的是http post方法,數(shù)據(jù)格式為application/x-www-form-urlencoded。那么了解接口字段的含義就很重要,結(jié)合簡(jiǎn)單的理解+網(wǎng)上找的資料(感謝bilibili_api API列表這個(gè)項(xiàng)目對(duì)B站各個(gè)api字段的解釋?zhuān)@個(gè)項(xiàng)目后文也會(huì)用到),字段的含義如下:
type:含義暫不明,可以默認(rèn)為1
oid:分P視頻的編號(hào)
msg:彈幕內(nèi)容
bvid:視頻的BV號(hào)
progress:彈幕在視頻中出現(xiàn)的時(shí)間,單位是毫秒
color:彈幕的顏色,十進(jìn)制。我這里用的是橘色,對(duì)應(yīng)的十六進(jìn)制顏色碼是#FFAA02
fontsize:彈幕的大小。B站支持3種字號(hào)的彈幕,對(duì)應(yīng)關(guān)系是:18為小、25為標(biāo)準(zhǔn)、36為大,其他值不接受
pool:是否是字幕彈幕,1是0否
mode:彈幕模式,對(duì)應(yīng)關(guān)系是:1為滾動(dòng)彈幕、5為頂端彈幕、4為底端彈幕,其他值不接受
rnd:發(fā)送彈幕的系統(tǒng)時(shí)間,是一個(gè)時(shí)間戳
plat:所用平臺(tái),1可能代表PC端,可以默認(rèn)為1
csrf:用于防止跨域請(qǐng)求,與用戶(hù)個(gè)人有關(guān)
基于以上的抓包分析,我們就可以用python的Requests庫(kù)來(lái)構(gòu)造請(qǐng)求發(fā)送彈幕了。但是,神說(shuō)(雖然不知道是哪個(gè)神):Don't Reinvent The Wheel(不要重復(fù)發(fā)明輪子)。其實(shí)上文提到的bilibili_api項(xiàng)目已經(jīng)很好的封裝了B站的很多功能,包括發(fā)彈幕(可惜的是作者精力不足不再維護(hù)這個(gè)項(xiàng)目了QAQ),因此我們還是直接借用他的輪子來(lái)搞自己的事情吧!
bilibili_api項(xiàng)目發(fā)送彈幕的函數(shù)是send_danmaku,它需要page(int類(lèi)型)和danmaku(Danmaku類(lèi)型)兩個(gè)參數(shù)。page代表視頻的分p,danmaku是一個(gè)Danmaku類(lèi)型的彈幕變量。其中,Danmaku是項(xiàng)目封裝的彈幕基礎(chǔ)類(lèi),它的構(gòu)造參數(shù)如下:

可以看到,與報(bào)文參數(shù)不同的是,它的彈幕出現(xiàn)時(shí)間dm_time是一個(gè)浮點(diǎn)數(shù),單位是秒。因此下面我們需要將彈幕內(nèi)容和參數(shù)處理成接口要求的格式。
4.2. 處理srt文件的格式
打開(kāi)下載的.srt文件,文件的格式如下:

發(fā)送彈幕我們其實(shí)只需要開(kāi)始時(shí)間,那么我們把開(kāi)始時(shí)間轉(zhuǎn)換為秒為單位的float類(lèi)型。處理完成后返回一個(gè)元素為(dm_time, dm_text)的list。
Ok,talk is cheap,直接show the code吧:(B站的編輯器不支持代碼塊,標(biāo)紅的就是代碼,這個(gè)渣排版我也是吐了)
def process_srt_file():
? ? srt_file_path = "path_to_your_srt_file"
? ? danmaku_list = []
? ? dm_time, dm_text = None, None
? ? i = 0
? ? for line in open(srt_file_path, "r", encoding="utf-8"):
? ? ? ? line = line.strip()
? ? ? ? if i % 4 == 1:
? ? ? ? ? ? # 處理時(shí)間
? ? ? ? ? ? start_time = line.split("-->")[0]
? ? ? ? ? ? other_time, millisecond = start_time.split(",")
? ? ? ? ? ? hour, minute, second = other_time.split(":")
? ? ? ? ? ? dm_time = int(hour) * 3600 + int(minute) * 60 + int(second) + int(millisecond) / 1000
? ? ? ? elif i % 4 == 2:
? ? ? ? ? ? # 處理彈幕內(nèi)容
? ? ? ? ? ? dm_text = line
? ? ? ? ? ? danmaku_list.append((dm_time, dm_text))
? ? ? ? i += 1
? ? return danmaku_list
4.3. 愉快的自動(dòng)發(fā)送彈幕
先安裝bilibili_api包:
pip install bilibili_api
然后也直接上代碼吧:
from bilibili_api import video, Verify
from bilibili_api.video import Danmaku
import time
def auto_send_danmaku():
? ? danmaku_list = process_srt_file()
? ? sessdata = "your sessdata"? # 用戶(hù)的sessdata,獲取方法見(jiàn)下文
? ? csrf = "your csrf"? # 用戶(hù)的csrf,獲取方法見(jiàn)下文
? ? bvid = "BVxxxxxxxxxx"? # 視頻的bv號(hào)
? ? dm_color_pink = 16758465? # 彈幕的顏色,我用的騷粉色
? ? dm_mode = 4? # 彈幕類(lèi)型,字幕當(dāng)然用底端彈幕
? ? dm_font_size = 18? # 彈幕字號(hào),有節(jié)操的字幕菌還是用小字號(hào)吧
? ? # 設(shè)置驗(yàn)證
? ? verify = Verify(sessdata=sessdata, csrf=csrf)
? ? # 初始化VideoOperator類(lèi)
? ? my_video_operator = video.VideoOperate(bvid=bvid, verify=verify)
? ? for danmaku_content in danmaku_list:
? ? ? ? dm_time, dm_text = danmaku_content
? ? ? ? dm_text = "? " + dm_text + " ?"? # 兩邊加個(gè)小花花(你也可以不加)
? ? ? ? # 實(shí)例化一個(gè)彈幕類(lèi)
? ? ? ? danmaku = Danmaku(text=dm_text, dm_time=dm_time, color=dm_color_pink, mode=dm_mode, font_size=dm_font_size,
? ? ? ? ? ? ? ? ? ? ? ? ? is_sub=False)
? ? ? ? # 發(fā)送彈幕
? ? ? ? result = my_video_operator.send_danmaku(0, danmaku)
? ? ? ? print(result)
? ? ? ? print("發(fā)送成功:", danmaku.dm_time, danmaku.text)
? ? ? ? print("休眠15s中……")
? ? ? ? time.sleep(15)? # 發(fā)送彈幕頻率過(guò)快會(huì)被服務(wù)器禁止發(fā)送彈幕
* 其中,sessdata和csrf的獲取方法請(qǐng)直接參考項(xiàng)目作者的文章。
注意:B站現(xiàn)在設(shè)定的發(fā)送彈幕間隔時(shí)間至少為5s,但在實(shí)操中發(fā)現(xiàn)即使間隔10-15s,連續(xù)發(fā)彈幕仍有可能被暫停發(fā)送一段時(shí)間。因此大家可以根據(jù)程序執(zhí)行情況刪掉srt文件中已經(jīng)發(fā)送成功的部分,等待一段時(shí)間重啟程序即可。
5. 效果展示
下面是我用以上過(guò)程給視頻“來(lái)到這個(gè)世界的第二十三年”-by貓夏小卡 加上野生字幕的效果展示(悄悄安利這個(gè)可愛(ài)的漢服小姐姐(????)~):


B站現(xiàn)在已經(jīng)支持了投稿外掛字幕的功能,如果up主開(kāi)放了此功能,直接投稿外掛字幕要比野生字幕的效果更好。另外,如果想給BGM加上野生字幕,可以對(duì).lrc歌詞文件做格式處理,然后自動(dòng)發(fā)送即可,就交給感興趣的讀者自己擼碼吧:)~
希望大家愉快地享受成為一個(gè)野生字幕菌吧,以上。喜歡本文的朋友們請(qǐng)不吝點(diǎn)贊投幣收藏哦,多謝啦~
Reference:
bilibili_api項(xiàng)目:https://github.com/Passkou/bilibili_api,作者的B站空間是:@Passkou