原文来自febwave的博客:http://www.cnblogs.com/febwave/

        偶然看到张国荣的《东邪西毒》.发现居然没看过.然后看到有评论说.很难看懂之类的.所以就打算下载来看下.当时用的是手机.就用百度视频离线了.打算回家后导出到电脑上看看的.但回家后导出来才发现根本没办法合并啊.一堆毫无规律的BDV分段文件.百度一番后.总算找到解决办法了.

        以下是作者原文:

    -------------------------------------------------------------------------------

    百度影音的bdv格式又有变化。

    此次存在2种bdv格式。

    格式1:每个文件夹内就一个bdv文件,文件合并后改名avi即可。

    格式2:每个文件夹内一个bdv文件作为索引,其他附加guid的文件作为数据。

    例如:

    #EXTM3U
    #EXT-X-TARGETDURATION:30
    #EXT-X-MEDIA-SEQUENCE:0
    #EXTINF:10,

     

    所以python脚本有改。

    该脚本修正了单个文件在批处理过程名称。

    # -*- coding: UTF-8 -*-
     
    import os
    import io
    import codecs
    import string
    import shutil
    import moviefmt
     
     
    def coroutine(func):
        def start(*args,**kwargs):
            g = func(*args,**kwargs)
            g.next()
            return g
        return start
     
    @coroutine
    def enum_movie_file(target):   
        selectedFolder = (yield)
        for fileitem in os.listdir(selectedFolder):              
            targetFO = os.path.join(selectedFolder,fileitem)       
            if(os.path.isfile(targetFO) == True):
                continue;        
            target.send(targetFO)         
     
     
    @coroutine
    def read_movie_file(funcDisp,target):
        while(True):
            filmFolder = (yield)
            for fileitem in os.listdir(filmFolder):         
                targetfile = os.path.join(filmFolder,fileitem) 
                if(os.path.isfile(targetfile) == False):
                    continue;
                filebasename , fext = os.path.splitext(fileitem);                
                if(funcDisp.has_key(string.lower(fext))):
                    pfn = funcDisp[string.lower(fext)];
                    outputs = filmFolder,filebasename, pfn(targetfile);
                    target.send(outputs)
                    break
                 
    def getWindowsText(orgText):   
        try:
            return orgText.encode('gbk')  
        except Exception as exc:     
            print("%s" % exc);    
            return orgText
                 
                 
    @coroutine
    def create_report(outputfile):
        objTar = codecs.open(outputfile,"w+")        
        while(1):
            filmFolder,filebasename,(extname,piece_list) = (yield)
            if(extname == None) : 
                break;
     
     
            objTar.write('cd \"%s\"\r\n' % filmFolder)      
             
            if(len(piece_list) >1):
                objTar.write('copy /b ')      
            else:
                objTar.write('copy ')      
     
            if(len(piece_list) == 1):
                objTar.write('\"%s \"' %(getWindowsText(piece_list[0])))
            else:            
                bFirst = True
                for line in piece_list:
                    if(bFirst == False):                    
                        objTar.write('+\"%s\"' %(getWindowsText(line)))  
                    else:                    
                        objTar.write('\"%s\"' %(getWindowsText(line)))
                        bFirst = False
                     
     
            objTar.write('  ..\\"%s\".%s\r\n' %(filebasename,extname))              
     
            objTar.write('cd ..\r\n')
     
        objTar.close()               
     
     
     
    if __name__ == '__main__':   
        funcDisp = dict()
        funcDisp['.bdv_0000']= moviefmt.read_bdv_file;
        funcDisp['.rmvb_0000']= moviefmt.read_rmvb_file;
        funcDisp['.mkv_0000']= moviefmt.read_mkv_file;
        funcDisp['.bdv']= moviefmt.read_bdv_index;    
           
        funcDisp['.mp4_0000']= moviefmt.read_mp4_file;             
        funcDisp['']= moviefmt.read_mkv_2_file;    
        try:
            rmf = enum_movie_file(read_movie_file(funcDisp,create_report('film.bat')))
            rmf.send(os.getcwd())
            rmf.close()
     
        except Exception as exc:     
            print("%s" % exc);    
        print("done");

    该脚本增加单个文件read_bdv_index_V3和bdv新格式支持read_bdv_index_V4。

    # -*- coding: UTF-8 -*-
     
    import os
    import io
    import sys
    import string
    import shutil
    import codecs
     
     
    def read_bdv_index_V1(objFile):
        piece_list= list()  
        for line in objFile:
            if(line[0:4] != 'file'):
                continue;
            strings = string.split(line,'/')
            tarfile = strings[len(strings)-1]        
            tempText = string.strip(tarfile)
            piece_list.append(tempText)
        return "avi",piece_list
     
     
    def read_bdv_index_V2(objFile):
        piece_list= list()  
        for line in objFile:       
            nPos = line.count('bdv')
            if( nPos <=0):
                continue;      
            tarfile = line[0:len(line)-2]     
            piece_list.append(tarfile)    
        return "mpeg",piece_list
     
    def read_bdv_index_V3(objFile):
        piece_list= list()          
        oneFile= os.path.basename(objFile)    
        piece_list.append(oneFile)
        return "avi",piece_list
     
     
    def read_bdv_index_V4(objFile):
        piece_list= list()  
        #skip #EXT-X-MEDIA-SEQUENCE
        objFile.readline();
        for line in objFile:
            if(line.startswith('#')==True):
                continue;        
            piece_list.append(line.replace('\r\n',''))
        return "avi",piece_list
     
         
    def count_file_item(objFile,extText):
        cItem = 0;
        folderName = os.path.dirname(objFile)
        for fileitem in os.listdir(folderName):   
            filebasename , fext = os.path.splitext(fileitem);   
            if(fext == extText):
                cItem = cItem +1
        return cItem  
     
    def read_bdv_index(filename): 
        piece_list= list()   
        ext_type = None
        # total file count
        cItem = count_file_item(filename,".bdv")
        if(cItem == 1):
            ext_type,piece_list = read_bdv_index_V3(filename)
        else:
            objFile = codecs.open(filename,'r','utf-8')    
            topline = objFile.readline();
            bdv_ver = topline.replace("\r\n","")
            if(bdv_ver == '#EXTM3U'):
                v3Text = objFile.readline();
                if(v3Text.startswith('#EXT-X-TARGETDURATION') == False):
                    ext_type,piece_list = read_bdv_index_V2(objFile)
                else:
                    ext_type,piece_list = read_bdv_index_V4(objFile)
            else:
                ext_type,piece_list  = read_bdv_index_V1(objFile)
         
            objFile.close()       
             
             
        return  (ext_type ,piece_list)        
     
     
        
     
    def read_bdv_file(filename):
        piece_list= list()
        piece_list.append('*.bdv_*')
        return  ('avi',piece_list)
     
    def read_rmvb_file(filename):
        piece_list= list()
        piece_list.append('*.rmvb_*')
        return  ('rmvb',piece_list)
     
    def read_mkv_file(filename):
        piece_list= list()    
        piece_list.append('*.mkv_*')
        return  ('mkv',piece_list)
     
    def read_mp4_file(filename):
        piece_list= list()    
        piece_list.append('*.mp4_*')
        return  ('mp4',piece_list)
     
    def read_mkv_2_file(filename):
        piece_list= list()    
        piece_list.append('video_*')
        return  ('mkv',piece_list)

    -------------------------------------------------------------------------------

        之前也是看不明白上面的代码怎么用.一番折腾后.总算成功了.如果有看不懂的朋友.可以下载我弄好的压缩文件.解压出来后.把离线的那一大堆BDV分段文件放到"yield"文件夹里面.然后再运行"mergefilm.py".(我电脑装的是2.6版本的Python.用IDLE打开后.再按F5就可以运行脚本了.)完成后就可以看到已经合并完成的文件了.但前提是电脑上必须先装上"Python".才可以运行脚本.



    2015-09-07

        今天去作者博客看了下.他已经更新了.在此顺便贴一下.方便各位来访者.

        以下是作者原文:

    -------------------------------------------------------------------------------

    合并百度影音的离线数据 with python 2.3 格式更新

    很久没有更新了。

    这次新增支持四种格式的解析。

    filelist

    slicelist

    download.cfg

    third_party_download.cfg

    还是2个文件。替换之前版本即可。

    初步测试正常,但时间轴不对。

    # -*- coding: UTF-8 -*-
     
    import os
    import io
    import codecs
    import string
    import shutil
    import moviefmt
    import traceback
     
    def coroutine(func):
        def start(*args,**kwargs):
            g = func(*args,**kwargs)
            g.next()
            return g
        return start
     
    @coroutine
    def enum_movie_file(target):  
        selectedFolder = (yield)
        for fileitem in os.listdir(selectedFolder):             
            targetFO = os.path.join(selectedFolder,fileitem)      
            if(os.path.isfile(targetFO) == True):
                continue;       
            target.send(targetFO)        
     
     
    @coroutine
    def read_movie_file(funcDisp,target):
        while(True):
            filmFolder = (yield)
            for fileitem in os.listdir(filmFolder):        
                targetfile = os.path.join(filmFolder,fileitem)
                if(os.path.isfile(targetfile) == False):
                    continue;          
                filebasename , fext = os.path.splitext(fileitem);               
                if(filebasename[0] == "."):
                    continue           
                if(funcDisp.has_key(string.lower(fext))):
                    pfn = funcDisp[string.lower(fext)];
                    (targetFmt,targetObjects,filmFolderEx,filebasenameEx) = pfn(targetfile)
                    if(targetFmt is None):
                        continue;
                    outputs = filmFolder,filebasename, (targetFmt,targetObjects,filmFolderEx,filebasenameEx);
                  #  outputs = filmFolder,filebasename, pfn(targetfile);
                    target.send(outputs)
                    break
                 
    def getWindowsText(orgText):  
        try:
            return orgText.encode('gbk') 
        except Exception as exc:    
            print("%s" % exc);   
            return orgText
                 
                 
    @coroutine
    def create_report(outputfile):
        objTar = codecs.open(outputfile,"w+")       
        while(1):
            filmFolder,filebasename,(extname,piece_list,filmFolderEx,filebasenameEx) = (yield)
            if(extname == None) :
                break;
     
            objTar.write('cd \"%s\"\r\n' % (filmFolderEx if filmFolderEx else   filmFolder))     
             
             
            objTar.write('attrib  -h *.*\r\n ')     
             
            if(len(piece_list) >1):
                objTar.write('copy  /b ')     
            else:
                objTar.write('copy ')     
     
            if(len(piece_list) == 1):
                objTar.write('\"%s \"' %(getWindowsText(piece_list[0])))
            else:           
                bFirst = True
                for line in piece_list:
                    if(bFirst == False):                   
                        objTar.write('+\"%s\"' %(getWindowsText(line))) 
                    else:                   
                        objTar.write('\"%s\"' %(getWindowsText(line)))
                        bFirst = False
                     
             
            relpath = os.path.dirname(filmFolder)       
            currentPath = os.path.join(getWindowsText(relpath),getWindowsText(filebasenameEx if filebasenameEx else   filebasename))   
            objTar.write('  %s.%s\r\n' % (currentPath,extname))             
     
             
            objTar.write('cd %s\r\n' %(relpath))
                 
        objTar.close()              
     
     
     
    if __name__ == '__main__':  
        funcDisp = dict()
        funcDisp['.bdv_0000']= moviefmt.read_bdv_file;
        funcDisp['.rmvb_0000']= moviefmt.read_rmvb_file;
        funcDisp['.mkv_0000']= moviefmt.read_mkv_file;
        funcDisp['.bdv']= moviefmt.read_bdv_index;         
        funcDisp['.mp4_0000']= moviefmt.read_mp4_file;            
        funcDisp['']= moviefmt.read_mkv_2_file;   
         
        funcDisp['.filelist'] = moviefmt.read_filelist_index;
        funcDisp['.slicelist'] = moviefmt.read_slicelist_index;
        funcDisp['.cfg'] = moviefmt.read_cfg_index;
         
        try:
            rmf = enum_movie_file(read_movie_file(funcDisp,create_report('film.bat')))
            rmf.send(os.getcwd())
            rmf.close()
        except StopIteration:
            pass
        except Exception as exc:    
            print("%s" % exc);   
            info = traceback.format_exc()
            print(info)                      
        print("done");
    # -*- coding: UTF-8 -*-
     
    import os
    import io
    import sys
    import string
    import shutil
    import codecs
    import glob
    import re
     
    def read_bdv_index_V1(objFile):
        piece_list= list() 
        for line in objFile:
            if(line[0:4] != 'file'):
                continue;
            strings = string.split(line,'/')
            tarfile = strings[len(strings)-1]       
            tempText = string.strip(tarfile)
            piece_list.append(tempText)
        return "avi",piece_list,None,None
     
     
    def read_bdv_index_V2(objFile):
        piece_list= list() 
        for line in objFile:      
            nPos = line.count('bdv')
            if( nPos <=0):
                continue;     
            tarfile = line[0:len(line)-2]    
            piece_list.append(tarfile)   
        return "mpeg",piece_list,None,None
     
    def read_bdv_index_V3(objFile):
        piece_list= list()         
        oneFile= os.path.basename(objFile)   
        piece_list.append(oneFile)
        return "avi",piece_list,None,None
     
     
    def read_bdv_index_V4(objFile):
        piece_list= list() 
        #skip #EXT-X-MEDIA-SEQUENCE
        objFile.readline();
        for line in objFile:
            if(line.startswith('#')==True):
                continue;       
            piece_list.append(line.replace('\r\n',''))
        return "avi",piece_list,None,None
     
         
    def count_file_item(objFile,extText):
        cItem = 0;
        folderName = os.path.dirname(objFile)
        for fileitem in os.listdir(folderName):  
            filebasename , fext = os.path.splitext(fileitem);  
            if(fext == extText):
                cItem = cItem +1
        return cItem 
     
    def read_bdv_index(filename):
        piece_list= list()  
        ext_type = None
        filmFolderEx = None
        filebasenameEx = None
        # total file count
        cItem = count_file_item(filename,".bdv")
        if(cItem == 1):
            ext_type,piece_list,filmFolderEx,filebasenameEx = read_bdv_index_V3(filename)
        else:
            objFile = codecs.open(filename,'r','utf-8')   
            topline = objFile.readline();
            bdv_ver = topline.replace("\r\n","")
            if(bdv_ver == '#EXTM3U'):
                v3Text = objFile.readline();
                if(v3Text.startswith('#EXT-X-TARGETDURATION') == False):
                    ext_type,piece_list = read_bdv_index_V2(objFile)
                else:
                    ext_type,piece_list = read_bdv_index_V4(objFile)
            else:
                ext_type,piece_list  = read_bdv_index_V1(objFile)
         
            objFile.close()      
             
             
        return  (ext_type ,piece_list,filmFolderEx,filebasenameEx)       
     
     
     
     
    def read_bdv_file(filename):
        piece_list= list()
        piece_list.append('*.bdv_*')
        return  ('avi',piece_list,None,None)
     
    def read_rmvb_file(filename):
        piece_list= list()
        piece_list.append('*.rmvb_*')
        return  ('rmvb',piece_list,None,None)
     
    def read_mkv_file(filename):
        piece_list= list()   
        piece_list.append('*.mkv_*')
        return  ('mkv',piece_list,None,None)
     
    def read_mp4_file(filename):
        piece_list= list()   
        piece_list.append('*.mp4_*')
        return  ('mp4',piece_list,None,None)
     
    def read_mkv_2_file(filename):
        piece_list= list()   
        piece_list.append('video_*')
        return  ('mkv',piece_list,None,None)
     
     
    def read_filelist_index(filename):
        filmFolderEx = None
        filebasenameEx = None
        objFile = codecs.open(filename,'r','utf-8')   
        topline = objFile.readline();
        bdv_ver = topline.replace("\r\n","")
        if(bdv_ver == '#EXTM3U'):
            v3Text = objFile.readline();
            if(v3Text.startswith('#EXT-X-TARGETDURATION') == False):
                ext_type,piece_list,filmFolderEx,filebasenameEx = read_bdv_index_V2(objFile)
            else:
                ext_type,piece_list,filmFolderEx,filebasenameEx = read_bdv_index_V4(objFile)            
        else:
            ext_type,piece_list,filmFolderEx,filebasenameEx  = read_bdv_index_V1(objFile)
             
        objFile.close()      
        return  ("mp4" ,piece_list,filmFolderEx,filebasenameEx)                
     
    def read_slicelist_index(filename):
        piece_list= list()   
        objFile = codecs.open(filename,'r','utf-8')   
        topline = objFile.readline();
        bdv_ver = topline.replace("\r\n","")
        if(bdv_ver == '#BD-SECTION'):   
            while(True):
                currentLine = objFile.readline();
                if(currentLine is None or len(currentLine) ==0):
                    break
                piece_list.append(currentLine.replace("\r\n",""))
        objFile.close()       
        return  ('mp4',piece_list,None,None)
     
    def read_cfg_index(filename):
        piece_list= list()   
        simpleFileName =  os.path.basename(filename)
        if(simpleFileName == 'download.cfg'):
            simpleFolderName = os.path.dirname(filename)
            chkLst =glob.glob(os.path.join(simpleFolderName, '*.filelist'));
            if(chkLst is not None and len(chkLst) >0):
                return (None,None,None,None)
            chkLst =glob.glob(os.path.join(simpleFolderName, '*.bdv'));
            piece_list.append(chkLst[0]);
            return  ('avi',piece_list)
         
        if(simpleFileName != 'third_party_download.cfg'):
            raise Exception('unknown format file : %s' %(filename))
     
        reObj = re.compile('(?P<var_key>\S+):(?P<var_value>\S+)',re.IGNORECASE)
        lineDict = dict()
    #    [orgLines.append(orgLine.replace("\r\n","") ) for orgLine in codecs.open(filename,'r','utf-8')]
        for orgLine in codecs.open(filename,'r','utf-8'):
            orgLine = orgLine.replace("\r\n","")       
            results = reObj.findall(orgLine)
            if(len(results) > 0):
                lineDict[results[0][0]] =results[0][1]
                 
                                  
        resID = lineDict["resource"]  
        vid = lineDict[ '%s_vid'%(resID)]
        targetName = lineDict["video_name"]
        simpleFolderName = os.path.dirname(filename)
        upLevelFolderName = os.path.dirname(simpleFolderName)
        targetFolder = os.path.join(upLevelFolderName,vid)
        targetFolder = os.path.join(targetFolder,vid)
         
        chkLst =glob.glob(os.path.join(targetFolder, '*.%s*' %(resID)));
        targetFile = chkLst[0]  
         
          #skip #EXT-X-MEDIA-SEQUENCE   
        for line in codecs.open(targetFile,'r','utf-8'):
            if(line.startswith('#')==True):
                continue;       
            line = os.path.basename(line.replace('\r\n',''))
            line = os.path.basename(line.replace('\r',''))
            line = os.path.basename(line.replace('\n',''))
            piece_list.append(line )
         
        return  ('avi',piece_list,targetFolder,targetName)


    2015-10-29

        已上传最新2.3版本.各位请下载bdv 2.3.zip

        下载地址:

    此处内容已隐藏,评论或者即可查看