# HG changeset patch # User hh # Date 1574332305 -3600 # Node ID fc80602b39cedba6df3cfe78b84e58fb07d859d3 -- diff -r 000000000000 -r fc80602b39ce spojeni_vob-titulku.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spojeni_vob-titulku.py Thu Nov 21 11:31:45 2019 +0100 @@ -0,0 +1,172 @@ +#!/usr/bin/python +# coding=utf8 + +from optparse import OptionParser +from subprocess import * +from re import * +from shutil import * +import os # os.open koliduje s built-in open +global predchozi_index + +def strt(time): + secs=int(time) + fract=time-secs + hrs=str(100+secs//3600)[-2:] + min=str(100+(secs%3600)//60)[-2:] + sec=str(100+secs%60)[-2:] + fra=str(1000+1000*fract)[1:4] + return hrs+":"+min+":"+sec+":"+fra + +def dect(time): + s=split(":", time) + return int(s[0])*3600+int(s[1])*60+int(s[2])+float(s[3])/1000 + +def deb(line): + if 'DEB' in os.environ: + try: + if int(os.environ['DEB'])>0: + for x in line: print x, + print + except: return + +class jazyk: # titulky jednoho jazyka + def __init__(self, idx): + self.idx=idx # pořadí jazyka z indexu + self.id=idxi.line.split(',')[0].split(': ')[1] + self.head=idxi.line # header jazyka + self.index=[index(), index()] # dílčí indexy pro jazyk v jednotlivých dílech + self.image=["", ""] # dílčí images pro jazyk v jednotlivých dílech + def nacti(self): + deb(("jazyk", self.id)) + line=idxi.next() + while line and not match(r"^timestamp:", line): line=idxi.next() # dojeď na začátek záznamů s timestampy + if not line: return + self.index[dil].index_lines() + print "konec dílu jazyka", self.id + deb(("délka indexu", len(self.index[dil].time_pos))) + +class index: # dílčí index jazyka za jeden díl + def __init__(self): + self.time_pos=[] + self.image="" + self.img_beg=0 + self.img_end=0 + self.img_len=0 + self.img_del=0 + def index_lines(self): + global predchozi_index + zacatek=True + line=idxi.line + while line and match(r"^timestamp:", line): + timestamp=search(r"^timestamp:\s(\d\d:\d\d:\d\d:\d\d\d)", line).group(1) + position=eval("0x"+search(r"filepos:\s([a-z0-9]+)", line).group(1)) + if zacatek: + if predchozi_index and predchozi_index.img_len==0: + deb(("načítá se image k předchozímu indexu",)) + predchozi_index.getimage(position) + predchozi_index=self + self.img_beg=position + zacatek=False + if dil==0 and timestamp>off_set: break # výchozí díly filmu se mohou překrývat, a proto se případně 1.díl zařezává a s ním i jeho titulky + self.time_pos.append((timestamp, position)) + line=idxi.next() + if line and match(r"^timestamp:", line): + deb(("konec zkráceného image",)) + self.getimage(position) + if not line: + deb(("konec image na konci file",)) + self.getimage(None) + if line: + deb(("konec dílu image",)) + while line and match(r"^timestamp:", line): # projedeme ignorovanou část zařízutého 1.dílu + line=idxi.next() + #if timePosList.size()>0: img_beg=time_posList.getFirst().position + def getimage(self, position): # načti díl image k právě načtenému dílu indexu + if position: self.img_len=position-self.img_beg + else: self.img_len=img_sizes[dil+1]-self.img_beg + deb(("čte se ", self.img_len, "na offsetu", self.img_beg)) + self.image=imgi.read(self.img_len) + deb(("precteno", self.img_len, "z", imgi_fn)) + +class index_file: + def __init__(self, fn): + self.line=None + self.inf=open(fn, "r") + def next(self): + try: self.line=self.inf.next() + except StopIteration: self.line=None + return self.line + def close(self): self.inf.close() + +usage = "usage: %prog <1.part>.vob <2.part>.vob <1.part>.avi" +parser = OptionParser(usage=usage) +options, args = parser.parse_args() +if len(args)<4: + print ">>> Povinné jsou 4 argumenty.\n" + parser.print_help() + exit(1) +try: p=Popen(["mplayer", "-v", "-endpos", "0", "-vo", "null", "-ao", "null", args[3]], stdout=PIPE, stderr=STDOUT).communicate() +except: print "Nelze otevřít první část filmu."; exit(1) +try: offset2dilu=float(search(r"ID_LENGTH=([\d.]+)", p[0]).group(1)) +except: print "Nelze zjistit časovou délku první části filmu."; exit(1) +off_set=strt(offset2dilu) +print "Odstup druhé části:", off_set + +N=(args[0], args[1], args[2]) + +try: p=os.stat(N[0]+".vob.ifo") +except: + try: copy2(N[1]+".ifo", N[0]+".vob.ifo") + except: print "Problém s vytvořením", N[0]+".vob.ifo"; exit(1) + +img_sizes={} +for i in (1, 2): + try: img_sizes[i]=os.stat(N[i]+".sub").st_size + except: print "Chybí", N[i]+".sub"; exit(1) + if img_sizes[i]%2048: print "Velikost", N[i]+".sub", "není násobkem 2048."; exit(1) + +idxi=None +line=None +idxo=open(N[0]+".vob.idx", "w") +jazyky=dict() + +for dil in (0, 1): # zpracování jednotlivých dílů na vstupu + print "dil", str(dil+1) + predchozi_index=None + if idxi: idxi.close() + idxi=index_file(N[dil+1]+".idx") + #idxi=open(N[dil+1]+".idx","r") + line=idxi.next() + imgi_fn=N[dil+1]+".sub" + imgi=open(imgi_fn, "rb") + while line: # načtení dílčích indexů pro jednotlivé jazyky + while line and not match(r"^id:\s", line): + if dil==0: idxo.write(line) # v prvním díle se zapíšou do výstupu úvodní řádky indexu + line=idxi.next() + if line: + #jid=line.split(',')[0].split(': ')[1] + jid=int(line.split('index: ')[1]) + deb(("nalezen jazyk", jid, line)) + if not jid in jazyky: jazyky[jid]=jazyk(jid) + jazyky[jid].nacti() + line=idxi.next() + +deb(("počet načtených jazyků:", len(jazyky))) +imgo=open(N[0]+".vob.sub", "wb") +offset=0; jid=0 +#for jid in jazyky.keys(): # sestavení výstupu +while jid in jazyky: + print "zápis jazyka", jazyky[jid].id + #idxo.write("id: "+jid+", index: "+str(poradi_jazyka)+"\n") + idxo.write(jazyky[jid].head) + for dil in (0, 1): + index=jazyky[jid].index[dil] + for tp in index.time_pos: + time = strt(dect(tp[0])+dil*offset2dilu) + position = ("00000000"+(hex(tp[1]-index.img_beg+offset))[2:])[-9:] + idxo.write("timestamp: "+time+", filepos: "+position+"\n") + imgo.write(index.image); offset+=len(index.image) + jid+=1 + +idxo.close() +imgo.close()