|
0
|
1 |
#!/usr/bin/python
|
|
|
2 |
# coding=utf8
|
|
|
3 |
|
|
|
4 |
from optparse import OptionParser
|
|
|
5 |
from subprocess import *
|
|
|
6 |
from re import *
|
|
|
7 |
from shutil import *
|
|
|
8 |
import os # os.open koliduje s built-in open
|
|
|
9 |
global predchozi_index
|
|
|
10 |
|
|
|
11 |
def strt(time):
|
|
|
12 |
secs=int(time)
|
|
|
13 |
fract=time-secs
|
|
|
14 |
hrs=str(100+secs//3600)[-2:]
|
|
|
15 |
min=str(100+(secs%3600)//60)[-2:]
|
|
|
16 |
sec=str(100+secs%60)[-2:]
|
|
|
17 |
fra=str(1000+1000*fract)[1:4]
|
|
|
18 |
return hrs+":"+min+":"+sec+":"+fra
|
|
|
19 |
|
|
|
20 |
def dect(time):
|
|
|
21 |
s=split(":", time)
|
|
|
22 |
return int(s[0])*3600+int(s[1])*60+int(s[2])+float(s[3])/1000
|
|
|
23 |
|
|
|
24 |
def deb(line):
|
|
|
25 |
if 'DEB' in os.environ:
|
|
|
26 |
try:
|
|
|
27 |
if int(os.environ['DEB'])>0:
|
|
|
28 |
for x in line: print x,
|
|
|
29 |
print
|
|
|
30 |
except: return
|
|
|
31 |
|
|
|
32 |
class jazyk: # titulky jednoho jazyka
|
|
|
33 |
def __init__(self, idx):
|
|
|
34 |
self.idx=idx # pořadí jazyka z indexu
|
|
|
35 |
self.id=idxi.line.split(',')[0].split(': ')[1]
|
|
|
36 |
self.head=idxi.line # header jazyka
|
|
|
37 |
self.index=[index(), index()] # dílčí indexy pro jazyk v jednotlivých dílech
|
|
|
38 |
self.image=["", ""] # dílčí images pro jazyk v jednotlivých dílech
|
|
|
39 |
def nacti(self):
|
|
|
40 |
deb(("jazyk", self.id))
|
|
|
41 |
line=idxi.next()
|
|
|
42 |
while line and not match(r"^timestamp:", line): line=idxi.next() # dojeď na začátek záznamů s timestampy
|
|
|
43 |
if not line: return
|
|
|
44 |
self.index[dil].index_lines()
|
|
|
45 |
print "konec dílu jazyka", self.id
|
|
|
46 |
deb(("délka indexu", len(self.index[dil].time_pos)))
|
|
|
47 |
|
|
|
48 |
class index: # dílčí index jazyka za jeden díl
|
|
|
49 |
def __init__(self):
|
|
|
50 |
self.time_pos=[]
|
|
|
51 |
self.image=""
|
|
|
52 |
self.img_beg=0
|
|
|
53 |
self.img_end=0
|
|
|
54 |
self.img_len=0
|
|
|
55 |
self.img_del=0
|
|
|
56 |
def index_lines(self):
|
|
|
57 |
global predchozi_index
|
|
|
58 |
zacatek=True
|
|
|
59 |
line=idxi.line
|
|
|
60 |
while line and match(r"^timestamp:", line):
|
|
|
61 |
timestamp=search(r"^timestamp:\s(\d\d:\d\d:\d\d:\d\d\d)", line).group(1)
|
|
|
62 |
position=eval("0x"+search(r"filepos:\s([a-z0-9]+)", line).group(1))
|
|
|
63 |
if zacatek:
|
|
|
64 |
if predchozi_index and predchozi_index.img_len==0:
|
|
|
65 |
deb(("načítá se image k předchozímu indexu",))
|
|
|
66 |
predchozi_index.getimage(position)
|
|
|
67 |
predchozi_index=self
|
|
|
68 |
self.img_beg=position
|
|
|
69 |
zacatek=False
|
|
|
70 |
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
|
|
|
71 |
self.time_pos.append((timestamp, position))
|
|
|
72 |
line=idxi.next()
|
|
|
73 |
if line and match(r"^timestamp:", line):
|
|
|
74 |
deb(("konec zkráceného image",))
|
|
|
75 |
self.getimage(position)
|
|
|
76 |
if not line:
|
|
|
77 |
deb(("konec image na konci file",))
|
|
|
78 |
self.getimage(None)
|
|
|
79 |
if line:
|
|
|
80 |
deb(("konec dílu image",))
|
|
|
81 |
while line and match(r"^timestamp:", line): # projedeme ignorovanou část zařízutého 1.dílu
|
|
|
82 |
line=idxi.next()
|
|
|
83 |
#if timePosList.size()>0: img_beg=time_posList.getFirst().position
|
|
|
84 |
def getimage(self, position): # načti díl image k právě načtenému dílu indexu
|
|
|
85 |
if position: self.img_len=position-self.img_beg
|
|
|
86 |
else: self.img_len=img_sizes[dil+1]-self.img_beg
|
|
|
87 |
deb(("čte se ", self.img_len, "na offsetu", self.img_beg))
|
|
|
88 |
self.image=imgi.read(self.img_len)
|
|
|
89 |
deb(("precteno", self.img_len, "z", imgi_fn))
|
|
|
90 |
|
|
|
91 |
class index_file:
|
|
|
92 |
def __init__(self, fn):
|
|
|
93 |
self.line=None
|
|
|
94 |
self.inf=open(fn, "r")
|
|
|
95 |
def next(self):
|
|
|
96 |
try: self.line=self.inf.next()
|
|
|
97 |
except StopIteration: self.line=None
|
|
|
98 |
return self.line
|
|
|
99 |
def close(self): self.inf.close()
|
|
|
100 |
|
|
|
101 |
usage = "usage: %prog <output_base> <1.part>.vob <2.part>.vob <1.part>.avi"
|
|
|
102 |
parser = OptionParser(usage=usage)
|
|
|
103 |
options, args = parser.parse_args()
|
|
|
104 |
if len(args)<4:
|
|
|
105 |
print ">>> Povinné jsou 4 argumenty.\n"
|
|
|
106 |
parser.print_help()
|
|
|
107 |
exit(1)
|
|
|
108 |
try: p=Popen(["mplayer", "-v", "-endpos", "0", "-vo", "null", "-ao", "null", args[3]], stdout=PIPE, stderr=STDOUT).communicate()
|
|
|
109 |
except: print "Nelze otevřít první část filmu."; exit(1)
|
|
|
110 |
try: offset2dilu=float(search(r"ID_LENGTH=([\d.]+)", p[0]).group(1))
|
|
|
111 |
except: print "Nelze zjistit časovou délku první části filmu."; exit(1)
|
|
|
112 |
off_set=strt(offset2dilu)
|
|
|
113 |
print "Odstup druhé části:", off_set
|
|
|
114 |
|
|
|
115 |
N=(args[0], args[1], args[2])
|
|
|
116 |
|
|
|
117 |
try: p=os.stat(N[0]+".vob.ifo")
|
|
|
118 |
except:
|
|
|
119 |
try: copy2(N[1]+".ifo", N[0]+".vob.ifo")
|
|
|
120 |
except: print "Problém s vytvořením", N[0]+".vob.ifo"; exit(1)
|
|
|
121 |
|
|
|
122 |
img_sizes={}
|
|
|
123 |
for i in (1, 2):
|
|
|
124 |
try: img_sizes[i]=os.stat(N[i]+".sub").st_size
|
|
|
125 |
except: print "Chybí", N[i]+".sub"; exit(1)
|
|
|
126 |
if img_sizes[i]%2048: print "Velikost", N[i]+".sub", "není násobkem 2048."; exit(1)
|
|
|
127 |
|
|
|
128 |
idxi=None
|
|
|
129 |
line=None
|
|
|
130 |
idxo=open(N[0]+".vob.idx", "w")
|
|
|
131 |
jazyky=dict()
|
|
|
132 |
|
|
|
133 |
for dil in (0, 1): # zpracování jednotlivých dílů na vstupu
|
|
|
134 |
print "dil", str(dil+1)
|
|
|
135 |
predchozi_index=None
|
|
|
136 |
if idxi: idxi.close()
|
|
|
137 |
idxi=index_file(N[dil+1]+".idx")
|
|
|
138 |
#idxi=open(N[dil+1]+".idx","r")
|
|
|
139 |
line=idxi.next()
|
|
|
140 |
imgi_fn=N[dil+1]+".sub"
|
|
|
141 |
imgi=open(imgi_fn, "rb")
|
|
|
142 |
while line: # načtení dílčích indexů pro jednotlivé jazyky
|
|
|
143 |
while line and not match(r"^id:\s", line):
|
|
|
144 |
if dil==0: idxo.write(line) # v prvním díle se zapíšou do výstupu úvodní řádky indexu
|
|
|
145 |
line=idxi.next()
|
|
|
146 |
if line:
|
|
|
147 |
#jid=line.split(',')[0].split(': ')[1]
|
|
|
148 |
jid=int(line.split('index: ')[1])
|
|
|
149 |
deb(("nalezen jazyk", jid, line))
|
|
|
150 |
if not jid in jazyky: jazyky[jid]=jazyk(jid)
|
|
|
151 |
jazyky[jid].nacti()
|
|
|
152 |
line=idxi.next()
|
|
|
153 |
|
|
|
154 |
deb(("počet načtených jazyků:", len(jazyky)))
|
|
|
155 |
imgo=open(N[0]+".vob.sub", "wb")
|
|
|
156 |
offset=0; jid=0
|
|
|
157 |
#for jid in jazyky.keys(): # sestavení výstupu
|
|
|
158 |
while jid in jazyky:
|
|
|
159 |
print "zápis jazyka", jazyky[jid].id
|
|
|
160 |
#idxo.write("id: "+jid+", index: "+str(poradi_jazyka)+"\n")
|
|
|
161 |
idxo.write(jazyky[jid].head)
|
|
|
162 |
for dil in (0, 1):
|
|
|
163 |
index=jazyky[jid].index[dil]
|
|
|
164 |
for tp in index.time_pos:
|
|
|
165 |
time = strt(dect(tp[0])+dil*offset2dilu)
|
|
|
166 |
position = ("00000000"+(hex(tp[1]-index.img_beg+offset))[2:])[-9:]
|
|
|
167 |
idxo.write("timestamp: "+time+", filepos: "+position+"\n")
|
|
|
168 |
imgo.write(index.image); offset+=len(index.image)
|
|
|
169 |
jid+=1
|
|
|
170 |
|
|
|
171 |
idxo.close()
|
|
|
172 |
imgo.close()
|