用AutoHotkey解决B站客户端缓存视频m4s合并成mp4提示解析失败
Posted 火冷
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用AutoHotkey解决B站客户端缓存视频m4s合并成mp4提示解析失败相关的知识,希望对你有一定的参考价值。
一直用
you-get
下载B站视频,这两天发现视频的质量很低,于是又折腾了下
- 在线播放有
1080P
,而you-get -i url
返回的最高清晰度就是480P
- 听朋友安利用
哔哩下载姬(DownKyi)
,试了也是只有480P
的清晰度
看来B站作了限制了,于是下载了官方客户端,可以缓存视频,
发现是两个m4s
格式的文件,经网上查看,一个是视频,一个是音频,
用ffmpeg -i f1 -i f2 -c copy out.mp4
想合并文件并转为mp4
,提示xxx.m4s: Invalid data found when processing input
,看来是B站对这个文件也做了处理。
继续找视频,在B站客户端缓存视频解码与打开方法_哔哩哔哩知道了要修改的地方(主要是这个)。
于是又用AutoHotkey
折腾了文件二进制的处理。
附上 AutoHotkey v2-beta 代码
m4sDir("c:\\Users\\Administrator\\Desktop\\811376303")
;传入文件夹即可
m4sDir(dir)
SplitPath(dir, &dn)
if (dn ~= "^\\d9$") ;缓存文件夹是9个数字
fnn := A_Now
arrFp := []
loop files, dir . "\\*.m4s", "F" ;B站缓存
arrFp.push((fnn . string(A_Index)).fnn2fp("m4s"))
um_m4s_modify(A_LoopFileFullPath, arrFp[-1])
;解析 .videoInfo 文件,获取文件名
title := json.parse(fileread(".videoInfo".fn2fp(dir), "utf-8"))["title"]
;用ffmpeg合并文件
RunWait(format(\'ffmpeg.exe -i 1 -i "2" -c copy "3"\',arrFp[1],arrFp[2],title.fnn2fp("mp4",dir)))
;删除两个临时文件
arrFp.map((fp)=>FileDelete(fp))
return 1
;核心:对m4s文件进行二进制处理
um_m4s_modify(fp, fp1:="")
o := fileread(fp, "raw")
o.mid(1,9) ;删除前面9个字符
o.deleteByStr("avc1", 10, 30) ;删除指定字符串
numput("char", 32, o, 3) ;修改第4个字符为空格
if (FileExist(fp1))
FileDelete(fp1)
FileAppend(o, fp1)
defprop := .DefineProp.bind(buffer.prototype)
proto := _Buffer.prototype
for k in proto.OwnProps()
if (k != "__Class")
defprop(k, proto.GetOwnPropDesc(k))
class _Buffer
static fromFile(fp) => fileread(fp, "raw")
;删除 i开始l个字符
;o := ClipboardAll(o.ptr + 9, o.size-9)
mid(i, l)
dllcall("RtlMoveMemory", "ptr",this.ptr+i-1, "ptr",this.ptr+i+l-1, "uptr",this.size-l)
this.size -= l
;从 start 处开始匹配字符串 limit为限制查找长度
index(str, start:=0, limit:=0)
;字符串转成 asc 码
arr := []
loop parse, str
arr.push(ord(A_LoopField))
i := start
while (i < this.size)
if (limit && i-start > limit)
return 0
if (numget(this, i, "char") == arr[1]) ;匹配第一个字符
OutputDebug(format("i#1 2:3 match first=4", A_LineFile,A_LineNumber,A_ThisFunc,i))
res := i
;确认后续内容是否完整匹配
i++
loop(arr.length-1)
if (numget(this, i, "char") != arr[A_Index+1]) ;有一个不匹配,则退出
res := 0
break
i++
if (res)
OutputDebug(format("i#1 2:3 res=4", A_LineFile,A_LineNumber,A_ThisFunc,res))
return res
else
i++
;删除第一个找到的字符串
deleteByStr(str, start:=0, limit:=0)
i := this.index(str, start, limit)
if (i)
this.mid(i+1, strlen(str))
return i
以上是关于用AutoHotkey解决B站客户端缓存视频m4s合并成mp4提示解析失败的主要内容,如果未能解决你的问题,请参考以下文章