優酷客戶端下載的[超清]清晰度視頻會被保存為kux格式。其實這個格式就是一堆分段的flv。
頭上應該還有索引之類的,懶得分析了其實是分析不出來
因為木有索引,我們只能自己判斷flv段何時開始,何時結束;因為flv文件頭特徵不明顯其實是想裝b,我們需要分析flv的格式。
在參考這篇博客之後,寫了個腳本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
def grab(infile, outfile, buff_size = 0x200000, debug = True): #flv format http://wuyuans.com/2012/08/flv-format/ _in = open(infile, 'rb') _in.seek(0xe40000) # 第一個flv似乎總是在這個位置開始 _out = None idx = 0xe40000 # 當前偏移量 cnt = 1 _ = '\x00' * 11 # setup while _: if _ == '\x00' * 11: if _out: # 不是第一次 _out.close() _out = None idx = math.ceil(idx / 0x40000) * 0x40000 # flv的起始位置是0x40000對齊的 _in.seek(idx) _h = _in.read(9 + 4) # 頭 9b,前一個tag 4b if _h.strip('\x00') != '' and _h[:3] == 'FLV': # 看開頭是不是FLV _out = open(outfile[:-4] + '_%d.flv' % cnt, 'wb') print('New flv(%dp) @0x%08X%s' % (cnt, idx, ' ' * 20)) _out.write(_h) idx += 9 + 4 cnt += 1 else: tagtype, length = struct.unpack('b3s7x', _) # 我們只關心tag類型(其實也可以不用關係)和數據長度 length = _byte2ui24(length) # 3位元組轉uint24 if debug: print('TAG:%6s 0x%06X @0x%08X-0x%08X%s' % (TAG_TYPE[tagtype], length, idx, idx + length + 4, '\b' * 42), end = '') idx += length + 4 _ = _in.read(length + 4) #data, pre tag size _out.write(_) #next tag _ = _in.read(11) if _out: _out.write(_) idx += 11 _in.close() #_out.close()# out is already closed return cnt - 1 |
拖出了所有flv之後,我們用mkvmerge來合體
完整腳本在gist上可以找到
解包之後很有快感啊