Now copies a file when it is in the final format
Now creates the DVD structure with DVDAuthor Moved the XML generating code to its own file
This commit is contained in:
parent
1373141ecb
commit
54a2dd0b03
5 changed files with 568 additions and 419 deletions
463
src/devede/dvdauthor_converter.py
Normal file
463
src/devede/dvdauthor_converter.py
Normal file
|
|
@ -0,0 +1,463 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
#
|
||||||
|
# This file is part of DeVeDe-NG
|
||||||
|
#
|
||||||
|
# DeVeDe-NG is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# DeVeDe-NG is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
import os
|
||||||
|
import devede.configuration_data
|
||||||
|
import devede.executor
|
||||||
|
|
||||||
|
class dvdauthor_converter(devede.executor.executor):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
devede.executor.executor.__init__(self)
|
||||||
|
self.config = devede.configuration_data.configuration.get_config()
|
||||||
|
|
||||||
|
def create_dvd_project (self, path, name, file_movies, menu_entries, start_with_menu):
|
||||||
|
|
||||||
|
xml_file = self.create_dvdauthor_xml(path, file_movies, menu_entries, start_with_menu)
|
||||||
|
|
||||||
|
movie_path = os.path.join(path,name)
|
||||||
|
try:
|
||||||
|
os.makedirs(movie_path)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
self.command_var=[]
|
||||||
|
self.command_var.append("dvdauthor")
|
||||||
|
self.command_var.append("-o")
|
||||||
|
self.command_var.append(movie_path)
|
||||||
|
self.command_var.append("-x")
|
||||||
|
self.command_var.append(xml_file)
|
||||||
|
self.use_pulse_mode = True
|
||||||
|
self.text = _("Creating DVD structure")
|
||||||
|
|
||||||
|
|
||||||
|
def process_stdout(self,data):
|
||||||
|
return
|
||||||
|
|
||||||
|
def process_stderr(self,data):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def expand_xml(self,text):
|
||||||
|
|
||||||
|
text=text.replace('&','&')
|
||||||
|
text=text.replace('<','<')
|
||||||
|
text=text.replace('>','>')
|
||||||
|
text=text.replace('"','"')
|
||||||
|
text=text.replace("'",''')
|
||||||
|
return text
|
||||||
|
|
||||||
|
def create_dvdauthor_xml(self,movie_folder, file_movies, menu_entries, start_with_menu):
|
||||||
|
|
||||||
|
xmlpath = os.path.join(movie_folder,"xml_data")
|
||||||
|
xml_file_path = os.path.join(xmlpath,"dvdauthor.xml")
|
||||||
|
datapath = os.path.join(movie_folder,"dvd_tree")
|
||||||
|
try:
|
||||||
|
os.makedirs(xmlpath)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
os.makedirs(datapath)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if (len(file_movies) == 1) and (menu_entries == None):
|
||||||
|
onlyone = True
|
||||||
|
else:
|
||||||
|
onlyone = False
|
||||||
|
|
||||||
|
if (menu_entries == None):
|
||||||
|
elements_per_menu = 1000
|
||||||
|
else:
|
||||||
|
elements_per_menu = len(menu_entries[0]["chapters"])
|
||||||
|
|
||||||
|
xml_file=open(xml_file_path,"w")
|
||||||
|
xml_file.write('<dvdauthor dest="'+datapath+'">\n')
|
||||||
|
|
||||||
|
if onlyone:
|
||||||
|
xml_file.write('\t<vmgm />\n')
|
||||||
|
else:
|
||||||
|
xml_file.write('\t<vmgm>\n')
|
||||||
|
|
||||||
|
# MENU
|
||||||
|
|
||||||
|
# in the FPC we do a jump to the first menu in the first titleset if we wanted MENU
|
||||||
|
# or we jump to the second titleset if we didn't want MENU at startup
|
||||||
|
|
||||||
|
xml_file.write('\t\t<fpc>\n')
|
||||||
|
xml_file.write('\t\t\tg0=100;\n')
|
||||||
|
if (menu_entries != None) and (start_with_menu):
|
||||||
|
xml_file.write('\t\t\tg1=0;\n')
|
||||||
|
else:
|
||||||
|
xml_file.write('\t\t\tg1=100;\n')
|
||||||
|
xml_file.write('\t\t\tg2=1024;\n')
|
||||||
|
xml_file.write('\t\t\tjump menu 1;\n')
|
||||||
|
xml_file.write('\t\t</fpc>\n')
|
||||||
|
|
||||||
|
|
||||||
|
# in the VMGM menu we create a code to jump to the title specified in G0
|
||||||
|
# but if the title is 100, we jump to the menus. There we show the menu number
|
||||||
|
# contained in G1
|
||||||
|
|
||||||
|
xml_file.write("\t\t<menus>\n")
|
||||||
|
|
||||||
|
xml_file.write('\t\t\t<video format="')
|
||||||
|
if self.config.PAL:
|
||||||
|
xml_file.write("pal")
|
||||||
|
else:
|
||||||
|
xml_file.write("ntsc")
|
||||||
|
xml_file.write('" aspect="4:3"> </video>\n')
|
||||||
|
|
||||||
|
xml_file.write('\t\t\t<pgc>\n')
|
||||||
|
xml_file.write('\t\t\t\t<pre>\n')
|
||||||
|
|
||||||
|
counter=1
|
||||||
|
for element in file_movies:
|
||||||
|
xml_file.write('\t\t\t\t\tif (g0 eq '+str(counter)+') {\n')
|
||||||
|
xml_file.write('\t\t\t\t\t\tjump titleset '+str(1+counter)+' menu;\n')
|
||||||
|
xml_file.write('\t\t\t\t\t}\n')
|
||||||
|
counter+=1
|
||||||
|
xml_file.write('\t\t\t\t\tif (g0 eq 100) {\n')
|
||||||
|
xml_file.write('\t\t\t\t\t\tg2=1024;\n')
|
||||||
|
xml_file.write('\t\t\t\t\t\tjump titleset 1 menu;\n')
|
||||||
|
xml_file.write('\t\t\t\t\t}\n')
|
||||||
|
xml_file.write('\t\t\t\t</pre>\n')
|
||||||
|
# fake video (one black picture with one second of sound) to ensure 100% compatibility
|
||||||
|
xml_file.write('\t\t\t\t<vob file="')
|
||||||
|
|
||||||
|
if self.config.PAL:
|
||||||
|
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_pal.mpg"))))
|
||||||
|
else:
|
||||||
|
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_ntsc.mpg"))))
|
||||||
|
|
||||||
|
xml_file.write('"></vob>\n')
|
||||||
|
xml_file.write('\t\t\t</pgc>\n')
|
||||||
|
xml_file.write('\t\t</menus>\n')
|
||||||
|
xml_file.write("\t</vmgm>\n")
|
||||||
|
|
||||||
|
xml_file.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
# the first titleset contains all the menus. G1 allows us to jump to the desired menu
|
||||||
|
|
||||||
|
xml_file.write('\t<titleset>\n')
|
||||||
|
xml_file.write('\t\t<menus>\n')
|
||||||
|
xml_file.write('\t\t\t<video format="')
|
||||||
|
if self.config.PAL:
|
||||||
|
xml_file.write("pal")
|
||||||
|
else:
|
||||||
|
xml_file.write("ntsc")
|
||||||
|
xml_file.write('" aspect="4:3"> </video>\n')
|
||||||
|
|
||||||
|
first_entry = True
|
||||||
|
menu_number = 0
|
||||||
|
|
||||||
|
counter = 1
|
||||||
|
title_list = []
|
||||||
|
for element in file_movies:
|
||||||
|
if element.show_in_menu:
|
||||||
|
title_list.append(counter)
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
if (menu_entries != None):
|
||||||
|
nmenues = len(menu_entries)
|
||||||
|
button_counter = 0
|
||||||
|
for menu_page in menu_entries:
|
||||||
|
xml_file.write('\t\t\t<pgc>\n')
|
||||||
|
xml_file.write('\t\t\t\t<pre>\n')
|
||||||
|
# first we recover the currently selected button
|
||||||
|
xml_file.write('\t\t\t\t\ts8=g2;\n')
|
||||||
|
|
||||||
|
if first_entry: # here we add some code to jump to each menu
|
||||||
|
for menu2 in range(nmenues-1):
|
||||||
|
xml_file.write('\t\t\t\t\tif (g1 eq '+str(menu2+1)+') {\n')
|
||||||
|
xml_file.write('\t\t\t\t\t\tjump menu '+str(menu2+2)+';\n')
|
||||||
|
xml_file.write('\t\t\t\t\t}\n')
|
||||||
|
|
||||||
|
# this code is to fix a bug in some players
|
||||||
|
xml_file.write('\t\t\t\t\tif (g1 eq 100) {\n')
|
||||||
|
xml_file.write('\t\t\t\t\t\tjump title 1;\n') #menu '+str(self.nmenues+1)+';\n')
|
||||||
|
xml_file.write('\t\t\t\t\t}\n')
|
||||||
|
first_entry = False
|
||||||
|
|
||||||
|
xml_file.write('\t\t\t\t</pre>\n')
|
||||||
|
xml_file.write('\t\t\t\t<vob file="')
|
||||||
|
|
||||||
|
xml_file.write(self.expand_xml(menu_page["filename"]))
|
||||||
|
xml_file.write('"></vob>\n')
|
||||||
|
|
||||||
|
for nbutton in menu_page["chapters"]:
|
||||||
|
xml_file.write('\t\t\t\t<button name="'+nbutton+'"> g0='+str(title_list[button_counter])+'; jump vmgm menu; </button>\n')
|
||||||
|
button_counter+=1
|
||||||
|
|
||||||
|
if (menu_page["left"] != None):
|
||||||
|
xml_file.write('\t\t\t\t<button name="'+menu_page["left"]+'p"> g1=')
|
||||||
|
xml_file.write(str(menu_number-1))
|
||||||
|
xml_file.write('; g2=1024; jump menu ')
|
||||||
|
xml_file.write(str(menu_number))
|
||||||
|
xml_file.write('; </button>\n')
|
||||||
|
|
||||||
|
if (menu_page["right"] != None):
|
||||||
|
xml_file.write('\t\t\t\t<button name="'+menu_page["right"]+'n"> g1=')
|
||||||
|
xml_file.write(str(menu_number+1))
|
||||||
|
xml_file.write('; g2=1024; jump menu ')
|
||||||
|
xml_file.write(str(menu_number+2))
|
||||||
|
xml_file.write('; </button>\n')
|
||||||
|
|
||||||
|
xml_file.write('\t\t\t\t<post>\n')
|
||||||
|
xml_file.write('\t\t\t\t\tg2=s8;\n')
|
||||||
|
xml_file.write('\t\t\t\t\tg1='+str(menu_number)+';\n')
|
||||||
|
xml_file.write('\t\t\t\t\tjump menu '+str(menu_number+1)+';\n')
|
||||||
|
xml_file.write('\t\t\t\t</post>\n')
|
||||||
|
xml_file.write('\t\t\t</pgc>\n')
|
||||||
|
menu_number += 1
|
||||||
|
|
||||||
|
xml_file.write('\t\t</menus>\n')
|
||||||
|
else:
|
||||||
|
xml_file.write('\t\t\t<pgc>\n')
|
||||||
|
xml_file.write('\t\t\t\t<pre>\n')
|
||||||
|
# first we recover the currently selected button
|
||||||
|
xml_file.write('\t\t\t\t\ts8=g2;\n')
|
||||||
|
|
||||||
|
# this code is to fix a bug in some players
|
||||||
|
xml_file.write('\t\t\t\t\tif (g1 eq 100) {\n')
|
||||||
|
xml_file.write('\t\t\t\t\t\tjump title 1;\n') #menu '+str(self.nmenues+1)+';\n')
|
||||||
|
xml_file.write('\t\t\t\t\t}\n')
|
||||||
|
|
||||||
|
xml_file.write('\t\t\t\t</pre>\n')
|
||||||
|
xml_file.write('\t\t\t\t<vob file="')
|
||||||
|
if self.config.PAL:
|
||||||
|
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_pal.mpg")))+'"')
|
||||||
|
else:
|
||||||
|
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_ntsc.mpg")))+'"')
|
||||||
|
xml_file.write('"></vob>\n')
|
||||||
|
|
||||||
|
xml_file.write('\t\t\t\t<post>\n')
|
||||||
|
xml_file.write('\t\t\t\t\tg2=s8;\n')
|
||||||
|
xml_file.write('\t\t\t\t\tg1=0;\n')
|
||||||
|
xml_file.write('\t\t\t\t\tjump menu 1;\n')
|
||||||
|
xml_file.write('\t\t\t\t</post>\n')
|
||||||
|
xml_file.write('\t\t\t</pgc>\n')
|
||||||
|
|
||||||
|
xml_file.write('\t\t</menus>\n')
|
||||||
|
|
||||||
|
xml_file.write('\t\t<titles>\n')
|
||||||
|
xml_file.write('\t\t\t<video format="')
|
||||||
|
if self.config.PAL:
|
||||||
|
xml_file.write("pal")
|
||||||
|
else:
|
||||||
|
xml_file.write("ntsc")
|
||||||
|
xml_file.write('" aspect="4:3"> </video>\n')
|
||||||
|
xml_file.write('\t\t\t<pgc>\n')
|
||||||
|
xml_file.write('\t\t\t\t<vob file="')
|
||||||
|
if self.config.PAL:
|
||||||
|
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_pal.mpg"))))
|
||||||
|
else:
|
||||||
|
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_ntsc.mpg"))))
|
||||||
|
xml_file.write('"></vob>\n')
|
||||||
|
xml_file.write('\t\t\t\t<post>\n')
|
||||||
|
xml_file.write('\t\t\t\t\tg0=1;\n')
|
||||||
|
xml_file.write('\t\t\t\t\tg1=0;\n')
|
||||||
|
xml_file.write('\t\t\t\t\tg2=1024;\n')
|
||||||
|
xml_file.write('\t\t\t\t\tcall vmgm menu entry title;\n')
|
||||||
|
xml_file.write('\t\t\t\t</post>\n')
|
||||||
|
xml_file.write('\t\t\t</pgc>\n')
|
||||||
|
xml_file.write('\t\t</titles>\n')
|
||||||
|
xml_file.write("\t</titleset>\n")
|
||||||
|
|
||||||
|
xml_file.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
# Now, create the titleset for each video
|
||||||
|
|
||||||
|
total_t=len(file_movies)
|
||||||
|
titleset=1
|
||||||
|
titles=0
|
||||||
|
counter=0
|
||||||
|
for element in file_movies:
|
||||||
|
files=0
|
||||||
|
action=element.actions
|
||||||
|
|
||||||
|
xml_file.write("\n")
|
||||||
|
|
||||||
|
if element.is_mpeg_ps:
|
||||||
|
|
||||||
|
# if it's already an MPEG-2 compliant file, we use the original values
|
||||||
|
if element.original_fps == 25:
|
||||||
|
pal_ntsc="pal"
|
||||||
|
ispal=True
|
||||||
|
else:
|
||||||
|
pal_ntsc="ntsc"
|
||||||
|
ispal=False
|
||||||
|
|
||||||
|
if element.original_aspect_ratio > 1.6:
|
||||||
|
faspect='16:9'
|
||||||
|
fwide=True
|
||||||
|
else:
|
||||||
|
faspect='4:3'
|
||||||
|
fwide=False
|
||||||
|
|
||||||
|
else:
|
||||||
|
# but if we are converting it, we use the desired values
|
||||||
|
if element.format_pal:
|
||||||
|
pal_ntsc="pal"
|
||||||
|
ispal=True
|
||||||
|
else:
|
||||||
|
pal_ntsc="ntsc"
|
||||||
|
ispal=False
|
||||||
|
|
||||||
|
if element.aspect_ratio_final > 1.6:
|
||||||
|
faspect='16:9'
|
||||||
|
fwide=True
|
||||||
|
else:
|
||||||
|
faspect='4:3'
|
||||||
|
fwide=False
|
||||||
|
|
||||||
|
xml_file.write("\t<titleset>\n")
|
||||||
|
|
||||||
|
if not onlyone:
|
||||||
|
xml_file.write("\t\t<menus>\n")
|
||||||
|
xml_file.write('\t\t\t<video format="'+pal_ntsc+'" aspect="'+faspect+'"')
|
||||||
|
if fwide:
|
||||||
|
xml_file.write(' widescreen="nopanscan"')
|
||||||
|
xml_file.write('> </video>\n')
|
||||||
|
|
||||||
|
xml_file.write("\t\t\t<pgc>\n")
|
||||||
|
xml_file.write("\t\t\t\t<pre>\n")
|
||||||
|
xml_file.write('\t\t\t\t\tif (g0 eq 100) {\n')
|
||||||
|
xml_file.write('\t\t\t\t\t\tjump vmgm menu entry title;\n')
|
||||||
|
xml_file.write('\t\t\t\t\t}\n')
|
||||||
|
xml_file.write('\t\t\t\t\tg0=100;\n')
|
||||||
|
xml_file.write('\t\t\t\t\tg1='+str(int(titles/elements_per_menu))+';\n')
|
||||||
|
xml_file.write('\t\t\t\t\tjump title 1;\n')
|
||||||
|
xml_file.write('\t\t\t\t</pre>\n')
|
||||||
|
# fake video to ensure compatibility
|
||||||
|
xml_file.write('\t\t\t\t<vob file="')
|
||||||
|
if ispal:
|
||||||
|
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_pal"))))
|
||||||
|
else:
|
||||||
|
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_ntsc"))))
|
||||||
|
if fwide:
|
||||||
|
xml_file.write("_wide")
|
||||||
|
xml_file.write('.mpg"></vob>\n')
|
||||||
|
xml_file.write("\t\t\t</pgc>\n")
|
||||||
|
xml_file.write("\t\t</menus>\n")
|
||||||
|
|
||||||
|
xml_file.write("\t\t<titles>\n")
|
||||||
|
xml_file.write('\t\t\t<video format="'+pal_ntsc+'" aspect="'+faspect+'"')
|
||||||
|
if fwide:
|
||||||
|
xml_file.write(' widescreen="nopanscan"')
|
||||||
|
xml_file.write('> </video>\n')
|
||||||
|
|
||||||
|
# subtitles part
|
||||||
|
# for element3 in element2["sub_list"]:
|
||||||
|
# xml_file.write('\t\t\t<subpicture lang="'+self.expand_xml(str(element3["sub_language"][:2].lower()))+'" />\n')
|
||||||
|
xml_file.write('\t\t\t<pgc>\n')
|
||||||
|
|
||||||
|
# if (element2["force_subs"]) and (len(element2["sub_list"])!=0):
|
||||||
|
# xml_file.write('\t\t\t\t<pre>\n')
|
||||||
|
# xml_file.write('\t\t\t\t\tsubtitle=64;\n')
|
||||||
|
# xml_file.write('\t\t\t\t</pre>\n')
|
||||||
|
|
||||||
|
xml_file.write('\t\t\t\t<vob file="'+self.expand_xml(element.converted_filename)+'" ')
|
||||||
|
xml_file.write('chapters="0')
|
||||||
|
if (element.original_length > 5):
|
||||||
|
if (element.divide_in_chapters): # add chapters
|
||||||
|
toadd = element.chapter_size
|
||||||
|
seconds = toadd*60
|
||||||
|
while seconds < (element.original_length - 4):
|
||||||
|
thetime = self.return_time(seconds,False)
|
||||||
|
xml_file.write(","+thetime)
|
||||||
|
seconds += (toadd*60)
|
||||||
|
xml_file.write(',' + self.return_time((element.original_length -2 ),False))
|
||||||
|
xml_file.write('" />\n')
|
||||||
|
|
||||||
|
if not onlyone:
|
||||||
|
xml_file.write('\t\t\t\t<post>\n')
|
||||||
|
files+=1
|
||||||
|
xml_file.write('\t\t\t\t\tg1='+str(int(titles/elements_per_menu))+';\n')
|
||||||
|
if (action=="action_stop"):
|
||||||
|
xml_file.write('\t\t\t\t\tg0=100;\n')
|
||||||
|
xml_file.write('\t\t\t\t\tcall vmgm menu entry title;\n')
|
||||||
|
else:
|
||||||
|
xml_file.write('\t\t\t\t\tg0=')
|
||||||
|
if action=="action_play_previous":
|
||||||
|
if titles == 0:
|
||||||
|
prev_t = total_t - 1
|
||||||
|
else:
|
||||||
|
prev_t = titles - 1
|
||||||
|
xml_file.write(str(title_list[prev_t]))
|
||||||
|
elif action=="action_play_again":
|
||||||
|
xml_file.write(str(title_list[titles]))
|
||||||
|
elif action=="action_play_next":
|
||||||
|
if titles==total_t-1:
|
||||||
|
next_t=0
|
||||||
|
else:
|
||||||
|
next_t=titles+1
|
||||||
|
xml_file.write(str(title_list[next_t]))
|
||||||
|
elif action=="action_play_last":
|
||||||
|
xml_file.write(str(title_list[total_t-1]))
|
||||||
|
else:
|
||||||
|
xml_file.write('1') # first
|
||||||
|
|
||||||
|
xml_file.write(';\n')
|
||||||
|
xml_file.write('\t\t\t\t\tcall vmgm menu entry title;\n')
|
||||||
|
xml_file.write('\t\t\t\t</post>\n')
|
||||||
|
xml_file.write("\t\t\t</pgc>\n")
|
||||||
|
xml_file.write("\t\t</titles>\n")
|
||||||
|
xml_file.write("\t</titleset>\n")
|
||||||
|
counter+=1
|
||||||
|
titles+=1
|
||||||
|
|
||||||
|
xml_file.write("</dvdauthor>")
|
||||||
|
|
||||||
|
xml_file.close()
|
||||||
|
|
||||||
|
return xml_file_path
|
||||||
|
|
||||||
|
def return_time(self,seconds,empty):
|
||||||
|
|
||||||
|
""" cuts a time in seconds into seconds, minutes and hours """
|
||||||
|
|
||||||
|
seconds2=int(seconds)
|
||||||
|
|
||||||
|
hours=str(int(seconds2/3600))
|
||||||
|
if empty:
|
||||||
|
if len(hours)==1:
|
||||||
|
hours="0"+hours
|
||||||
|
else:
|
||||||
|
if hours=="0":
|
||||||
|
hours=""
|
||||||
|
if hours!="":
|
||||||
|
hours+=":"
|
||||||
|
|
||||||
|
minutes=str(int((seconds2/60)%60))
|
||||||
|
if empty or (hours!=""):
|
||||||
|
if len(minutes)==1:
|
||||||
|
minutes="0"+minutes
|
||||||
|
elif (minutes=="0") and (hours==""):
|
||||||
|
minutes=""
|
||||||
|
if minutes!="":
|
||||||
|
minutes+=":"
|
||||||
|
|
||||||
|
secs=str(int(seconds2%60))
|
||||||
|
if (len(secs)==1) and (minutes!=""):
|
||||||
|
secs="0"+secs
|
||||||
|
|
||||||
|
return hours+minutes+secs
|
||||||
|
|
@ -46,6 +46,10 @@ class executor(GObject.GObject):
|
||||||
self.childs = []
|
self.childs = []
|
||||||
self.progress_bar = None
|
self.progress_bar = None
|
||||||
self.killed = False
|
self.killed = False
|
||||||
|
self.pulse_mode = False
|
||||||
|
self.use_pulse_mode = False
|
||||||
|
self.pulse_text = None
|
||||||
|
|
||||||
|
|
||||||
def add_dependency(self, dep):
|
def add_dependency(self, dep):
|
||||||
|
|
||||||
|
|
@ -89,6 +93,8 @@ class executor(GObject.GObject):
|
||||||
self.progress_bar[1].set_fraction(0.0)
|
self.progress_bar[1].set_fraction(0.0)
|
||||||
self.progress_bar[0].show_all()
|
self.progress_bar[0].show_all()
|
||||||
self.launch_process(self.command_var)
|
self.launch_process(self.command_var)
|
||||||
|
if self.use_pulse_mode != self.pulse_mode:
|
||||||
|
self.set_pulse_mode(self.use_pulse_mode)
|
||||||
|
|
||||||
def remove_ansi(self,line):
|
def remove_ansi(self,line):
|
||||||
|
|
||||||
|
|
@ -123,6 +129,8 @@ class executor(GObject.GObject):
|
||||||
for e in command:
|
for e in command:
|
||||||
self.launch_command += (" "+e)
|
self.launch_command += (" "+e)
|
||||||
self.launch_command += "\n"
|
self.launch_command += "\n"
|
||||||
|
self.config.append_log(self.text)
|
||||||
|
self.config.append_log(self.launch_command)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if (self.stdin_file != None):
|
if (self.stdin_file != None):
|
||||||
|
|
@ -164,6 +172,31 @@ class executor(GObject.GObject):
|
||||||
return (stdout_r, stderr_r)
|
return (stdout_r, stderr_r)
|
||||||
|
|
||||||
|
|
||||||
|
def set_pulse_mode(self,pulse_mode):
|
||||||
|
|
||||||
|
if pulse_mode == self.pulse_mode:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.pulse_mode = pulse_mode
|
||||||
|
|
||||||
|
if pulse_mode:
|
||||||
|
self.timer_pulse = GLib.timeout_add(250, self.run_pulse)
|
||||||
|
else:
|
||||||
|
GLib.source_remove(self.timer_pulse)
|
||||||
|
|
||||||
|
def run_pulse(self,v = None):
|
||||||
|
|
||||||
|
if self.progress_bar == None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.pulse_text == None:
|
||||||
|
self.progress_bar[1].set_text("")
|
||||||
|
else:
|
||||||
|
self.progress_bar[1].set_text(self.pulse_text)
|
||||||
|
self.progress_bar[1].pulse()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def read_stdout_to_file(self,source,condition):
|
def read_stdout_to_file(self,source,condition):
|
||||||
|
|
||||||
if (condition != GLib.IO_IN):
|
if (condition != GLib.IO_IN):
|
||||||
|
|
@ -259,11 +292,11 @@ class executor(GObject.GObject):
|
||||||
else:
|
else:
|
||||||
retval = -1
|
retval = -1
|
||||||
|
|
||||||
|
self.set_pulse_mode(False)
|
||||||
|
|
||||||
if self.killed:
|
if self.killed:
|
||||||
retval = 0
|
retval = 0
|
||||||
else:
|
else:
|
||||||
self.config.append_log(self.text)
|
|
||||||
self.config.append_log(self.launch_command)
|
|
||||||
self.config.append_log(self.stdout_data)
|
self.config.append_log(self.stdout_data)
|
||||||
self.config.append_log(self.stderr_data)
|
self.config.append_log(self.stderr_data)
|
||||||
|
|
||||||
|
|
|
||||||
45
src/devede/file_copy.py
Normal file
45
src/devede/file_copy.py
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
#
|
||||||
|
# This file is part of DeVeDe-NG
|
||||||
|
#
|
||||||
|
# DeVeDe-NG is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# DeVeDe-NG is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
import os
|
||||||
|
import devede.configuration_data
|
||||||
|
import devede.executor
|
||||||
|
|
||||||
|
class file_copy(devede.executor.executor):
|
||||||
|
|
||||||
|
def __init__(self,input_path, output_path):
|
||||||
|
|
||||||
|
devede.executor.executor.__init__(self)
|
||||||
|
self.config = devede.configuration_data.configuration.get_config()
|
||||||
|
|
||||||
|
self.text = _("Copying file %(X)s") % {"X": os.path.basename(input_path)}
|
||||||
|
|
||||||
|
self.command_var=[]
|
||||||
|
self.command_var.append("cp")
|
||||||
|
self.command_var.append(input_path)
|
||||||
|
self.command_var.append(output_path)
|
||||||
|
self.use_pulse_mode = True
|
||||||
|
|
||||||
|
def process_stdout(self,data):
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def process_stderr(self,data):
|
||||||
|
|
||||||
|
return
|
||||||
|
|
@ -23,6 +23,7 @@ import devede.interface_manager
|
||||||
import devede.converter
|
import devede.converter
|
||||||
import devede.ask_subtitles
|
import devede.ask_subtitles
|
||||||
import devede.preview
|
import devede.preview
|
||||||
|
import devede.file_copy
|
||||||
|
|
||||||
class file_movie(devede.interface_manager.interface_manager):
|
class file_movie(devede.interface_manager.interface_manager):
|
||||||
|
|
||||||
|
|
@ -462,6 +463,9 @@ class file_movie(devede.interface_manager.interface_manager):
|
||||||
def do_conversion(self, output_path, duration = 0):
|
def do_conversion(self, output_path, duration = 0):
|
||||||
|
|
||||||
self.converted_filename = output_path
|
self.converted_filename = output_path
|
||||||
|
if self.is_mpeg_ps:
|
||||||
|
converter = devede.file_copy.file_copy(self.file_name,output_path)
|
||||||
|
else:
|
||||||
self.set_final_size_aspect()
|
self.set_final_size_aspect()
|
||||||
cv = devede.converter.converter.get_converter()
|
cv = devede.converter.converter.get_converter()
|
||||||
disc_converter = cv.get_disc_converter()
|
disc_converter = cv.get_disc_converter()
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import devede.dvd_menu
|
||||||
import devede.create_disk_window
|
import devede.create_disk_window
|
||||||
import devede.runner
|
import devede.runner
|
||||||
import devede.settings
|
import devede.settings
|
||||||
|
import devede.dvdauthor_converter
|
||||||
|
|
||||||
class devede_project:
|
class devede_project:
|
||||||
|
|
||||||
|
|
@ -263,10 +264,14 @@ class devede_project:
|
||||||
|
|
||||||
run_window = devede.runner.runner()
|
run_window = devede.runner.runner()
|
||||||
file_movies = self.get_all_files()
|
file_movies = self.get_all_files()
|
||||||
|
|
||||||
|
final_dependencies = []
|
||||||
|
|
||||||
if (self.wcreate_menu.get_active()):
|
if (self.wcreate_menu.get_active()):
|
||||||
processes,menu_entries = self.menu.create_dvd_menus(file_movies, data.path)
|
processes,menu_entries = self.menu.create_dvd_menus(file_movies, data.path)
|
||||||
for p in processes:
|
for p in processes:
|
||||||
run_window.add_process(p)
|
run_window.add_process(p)
|
||||||
|
final_dependencies.append(p)
|
||||||
else:
|
else:
|
||||||
menu_entries = None
|
menu_entries = None
|
||||||
|
|
||||||
|
|
@ -279,426 +284,25 @@ class devede_project:
|
||||||
for movie in file_movies:
|
for movie in file_movies:
|
||||||
p = movie.do_conversion(os.path.join(movie_folder,"movie_"+str(counter)+".mpg"))
|
p = movie.do_conversion(os.path.join(movie_folder,"movie_"+str(counter)+".mpg"))
|
||||||
run_window.add_process(p)
|
run_window.add_process(p)
|
||||||
|
final_dependencies.append(p)
|
||||||
counter += 1
|
counter += 1
|
||||||
|
|
||||||
|
if (self.disc_type == "dvd"):
|
||||||
if (self.menu.at_startup == "menu_show_at_startup"):
|
if (self.menu.at_startup == "menu_show_at_startup"):
|
||||||
start_with_menu = True
|
start_with_menu = True
|
||||||
else:
|
else:
|
||||||
start_with_menu = False
|
start_with_menu = False
|
||||||
|
dvdauthor = devede.dvdauthor_converter.dvdauthor_converter()
|
||||||
if (self.disc_type == "dvd"):
|
dvdauthor.create_dvd_project(data.path, data.name, file_movies, menu_entries, start_with_menu)
|
||||||
self.create_dvdauthor_xml(data.path,file_movies,menu_entries, start_with_menu)
|
# dvdauthor must wait until all the files have been converted
|
||||||
|
for element in final_dependencies:
|
||||||
|
dvdauthor.add_dependency(element)
|
||||||
|
run_window.add_process(dvdauthor)
|
||||||
|
|
||||||
run_window.connect("done",self.disc_done)
|
run_window.connect("done",self.disc_done)
|
||||||
self.wmain_window.hide()
|
self.wmain_window.hide()
|
||||||
run_window.run()
|
run_window.run()
|
||||||
|
|
||||||
def expand_xml(self,text):
|
|
||||||
|
|
||||||
text=text.replace('&','&')
|
|
||||||
text=text.replace('<','<')
|
|
||||||
text=text.replace('>','>')
|
|
||||||
text=text.replace('"','"')
|
|
||||||
text=text.replace("'",''')
|
|
||||||
return text
|
|
||||||
|
|
||||||
def create_dvdauthor_xml(self,movie_folder, file_movies, menu_entries, start_with_menu):
|
|
||||||
|
|
||||||
xmlpath = os.path.join(movie_folder,"xml_data")
|
|
||||||
datapath = os.path.join(movie_folder,"dvd_tree")
|
|
||||||
try:
|
|
||||||
os.makedirs(xmlpath)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
os.makedirs(datapath)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if (len(file_movies) == 1) and (menu_entries == None):
|
|
||||||
onlyone = True
|
|
||||||
else:
|
|
||||||
onlyone = False
|
|
||||||
|
|
||||||
if (menu_entries == None):
|
|
||||||
elements_per_menu = 1000
|
|
||||||
else:
|
|
||||||
elements_per_menu = len(menu_entries[0]["chapters"])
|
|
||||||
|
|
||||||
xml_file=open(os.path.join(xmlpath,"dvdauthor.xml"),"w")
|
|
||||||
xml_file.write('<dvdauthor dest="'+datapath+'">\n')
|
|
||||||
|
|
||||||
if onlyone:
|
|
||||||
xml_file.write('\t<vmgm />\n')
|
|
||||||
else:
|
|
||||||
xml_file.write('\t<vmgm>\n')
|
|
||||||
|
|
||||||
# MENU
|
|
||||||
|
|
||||||
# in the FPC we do a jump to the first menu in the first titleset if we wanted MENU
|
|
||||||
# or we jump to the second titleset if we didn't want MENU at startup
|
|
||||||
|
|
||||||
xml_file.write('\t\t<fpc>\n')
|
|
||||||
xml_file.write('\t\t\tg0=100;\n')
|
|
||||||
if (menu_entries != None) and (start_with_menu):
|
|
||||||
xml_file.write('\t\t\tg1=0;\n')
|
|
||||||
else:
|
|
||||||
xml_file.write('\t\t\tg1=100;\n')
|
|
||||||
xml_file.write('\t\t\tg2=1024;\n')
|
|
||||||
xml_file.write('\t\t\tjump menu 1;\n')
|
|
||||||
xml_file.write('\t\t</fpc>\n')
|
|
||||||
|
|
||||||
|
|
||||||
# in the VMGM menu we create a code to jump to the title specified in G0
|
|
||||||
# but if the title is 100, we jump to the menus. There we show the menu number
|
|
||||||
# contained in G1
|
|
||||||
|
|
||||||
xml_file.write("\t\t<menus>\n")
|
|
||||||
|
|
||||||
xml_file.write('\t\t\t<video format="')
|
|
||||||
if self.config.PAL:
|
|
||||||
xml_file.write("pal")
|
|
||||||
else:
|
|
||||||
xml_file.write("ntsc")
|
|
||||||
xml_file.write('" aspect="4:3"> </video>\n')
|
|
||||||
|
|
||||||
xml_file.write('\t\t\t<pgc>\n')
|
|
||||||
xml_file.write('\t\t\t\t<pre>\n')
|
|
||||||
|
|
||||||
counter=1
|
|
||||||
for element in file_movies:
|
|
||||||
xml_file.write('\t\t\t\t\tif (g0 eq '+str(counter)+') {\n')
|
|
||||||
xml_file.write('\t\t\t\t\t\tjump titleset '+str(1+counter)+' menu;\n')
|
|
||||||
xml_file.write('\t\t\t\t\t}\n')
|
|
||||||
counter+=1
|
|
||||||
xml_file.write('\t\t\t\t\tif (g0 eq 100) {\n')
|
|
||||||
xml_file.write('\t\t\t\t\t\tg2=1024;\n')
|
|
||||||
xml_file.write('\t\t\t\t\t\tjump titleset 1 menu;\n')
|
|
||||||
xml_file.write('\t\t\t\t\t}\n')
|
|
||||||
xml_file.write('\t\t\t\t</pre>\n')
|
|
||||||
# fake video (one black picture with one second of sound) to ensure 100% compatibility
|
|
||||||
xml_file.write('\t\t\t\t<vob file="')
|
|
||||||
|
|
||||||
if self.config.PAL:
|
|
||||||
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_pal.mpg"))))
|
|
||||||
else:
|
|
||||||
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_ntsc.mpg"))))
|
|
||||||
|
|
||||||
xml_file.write('"></vob>\n')
|
|
||||||
xml_file.write('\t\t\t</pgc>\n')
|
|
||||||
xml_file.write('\t\t</menus>\n')
|
|
||||||
xml_file.write("\t</vmgm>\n")
|
|
||||||
|
|
||||||
xml_file.write("\n")
|
|
||||||
|
|
||||||
|
|
||||||
# the first titleset contains all the menus. G1 allows us to jump to the desired menu
|
|
||||||
|
|
||||||
xml_file.write('\t<titleset>\n')
|
|
||||||
xml_file.write('\t\t<menus>\n')
|
|
||||||
xml_file.write('\t\t\t<video format="')
|
|
||||||
if self.config.PAL:
|
|
||||||
xml_file.write("pal")
|
|
||||||
else:
|
|
||||||
xml_file.write("ntsc")
|
|
||||||
xml_file.write('" aspect="4:3"> </video>\n')
|
|
||||||
|
|
||||||
first_entry = True
|
|
||||||
menu_number = 0
|
|
||||||
|
|
||||||
counter = 1
|
|
||||||
title_list = []
|
|
||||||
for element in file_movies:
|
|
||||||
if element.show_in_menu:
|
|
||||||
title_list.append(counter)
|
|
||||||
counter += 1
|
|
||||||
|
|
||||||
if (menu_entries != None):
|
|
||||||
nmenues = len(menu_entries)
|
|
||||||
button_counter = 0
|
|
||||||
for menu_page in menu_entries:
|
|
||||||
xml_file.write('\t\t\t<pgc>\n')
|
|
||||||
xml_file.write('\t\t\t\t<pre>\n')
|
|
||||||
# first we recover the currently selected button
|
|
||||||
xml_file.write('\t\t\t\t\ts8=g2;\n')
|
|
||||||
|
|
||||||
if first_entry: # here we add some code to jump to each menu
|
|
||||||
for menu2 in range(nmenues-1):
|
|
||||||
xml_file.write('\t\t\t\t\tif (g1 eq '+str(menu2+1)+') {\n')
|
|
||||||
xml_file.write('\t\t\t\t\t\tjump menu '+str(menu2+2)+';\n')
|
|
||||||
xml_file.write('\t\t\t\t\t}\n')
|
|
||||||
|
|
||||||
# this code is to fix a bug in some players
|
|
||||||
xml_file.write('\t\t\t\t\tif (g1 eq 100) {\n')
|
|
||||||
xml_file.write('\t\t\t\t\t\tjump title 1;\n') #menu '+str(self.nmenues+1)+';\n')
|
|
||||||
xml_file.write('\t\t\t\t\t}\n')
|
|
||||||
first_entry = False
|
|
||||||
|
|
||||||
xml_file.write('\t\t\t\t</pre>\n')
|
|
||||||
xml_file.write('\t\t\t\t<vob file="')
|
|
||||||
|
|
||||||
xml_file.write(self.expand_xml(menu_page["filename"]))
|
|
||||||
xml_file.write('></vob>\n')
|
|
||||||
|
|
||||||
for nbutton in menu_page["chapters"]:
|
|
||||||
xml_file.write('\t\t\t\t<button name="'+nbutton+'"> g0='+str(title_list[button_counter])+'; jump vmgm menu; </button>\n')
|
|
||||||
button_counter+=1
|
|
||||||
|
|
||||||
if (menu_page["left"] != None):
|
|
||||||
xml_file.write('\t\t\t\t<button name="'+menu_page["left"]+'p"> g1=')
|
|
||||||
xml_file.write(str(menu_number-1))
|
|
||||||
xml_file.write('; g2=1024; jump menu ')
|
|
||||||
xml_file.write(str(menu_number))
|
|
||||||
xml_file.write('; </button>\n')
|
|
||||||
|
|
||||||
if (menu_page["right"] != None):
|
|
||||||
xml_file.write('\t\t\t\t<button name="'+menu_page["right"]+'n"> g1=')
|
|
||||||
xml_file.write(str(menu_number+1))
|
|
||||||
xml_file.write('; g2=1024; jump menu ')
|
|
||||||
xml_file.write(str(menu_number+2))
|
|
||||||
xml_file.write('; </button>\n')
|
|
||||||
|
|
||||||
xml_file.write('\t\t\t\t<post>\n')
|
|
||||||
xml_file.write('\t\t\t\t\tg2=s8;\n')
|
|
||||||
xml_file.write('\t\t\t\t\tg1='+str(menu_number)+';\n')
|
|
||||||
xml_file.write('\t\t\t\t\tjump menu '+str(menu_number+1)+';\n')
|
|
||||||
xml_file.write('\t\t\t\t</post>\n')
|
|
||||||
xml_file.write('\t\t\t</pgc>\n')
|
|
||||||
menu_number += 1
|
|
||||||
|
|
||||||
xml_file.write('\t\t</menus>\n')
|
|
||||||
else:
|
|
||||||
xml_file.write('\t\t\t<pgc>\n')
|
|
||||||
xml_file.write('\t\t\t\t<pre>\n')
|
|
||||||
# first we recover the currently selected button
|
|
||||||
xml_file.write('\t\t\t\t\ts8=g2;\n')
|
|
||||||
|
|
||||||
# this code is to fix a bug in some players
|
|
||||||
xml_file.write('\t\t\t\t\tif (g1 eq 100) {\n')
|
|
||||||
xml_file.write('\t\t\t\t\t\tjump title 1;\n') #menu '+str(self.nmenues+1)+';\n')
|
|
||||||
xml_file.write('\t\t\t\t\t}\n')
|
|
||||||
|
|
||||||
xml_file.write('\t\t\t\t</pre>\n')
|
|
||||||
xml_file.write('\t\t\t\t<vob file="')
|
|
||||||
if self.config.PAL:
|
|
||||||
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_pal.mpg")))+'"')
|
|
||||||
else:
|
|
||||||
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_ntsc.mpg")))+'"')
|
|
||||||
xml_file.write('></vob>\n')
|
|
||||||
|
|
||||||
xml_file.write('\t\t\t\t<post>\n')
|
|
||||||
xml_file.write('\t\t\t\t\tg2=s8;\n')
|
|
||||||
xml_file.write('\t\t\t\t\tg1=0;\n')
|
|
||||||
xml_file.write('\t\t\t\t\tjump menu 1;\n')
|
|
||||||
xml_file.write('\t\t\t\t</post>\n')
|
|
||||||
xml_file.write('\t\t\t</pgc>\n')
|
|
||||||
|
|
||||||
xml_file.write('\t\t</menus>\n')
|
|
||||||
|
|
||||||
xml_file.write('\t\t<titles>\n')
|
|
||||||
xml_file.write('\t\t\t<video format="')
|
|
||||||
if self.config.PAL:
|
|
||||||
xml_file.write("pal")
|
|
||||||
else:
|
|
||||||
xml_file.write("ntsc")
|
|
||||||
xml_file.write('" aspect="4:3"> </video>\n')
|
|
||||||
xml_file.write('\t\t\t<pgc>\n')
|
|
||||||
xml_file.write('\t\t\t\t<vob file="')
|
|
||||||
if self.config.PAL:
|
|
||||||
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_pal.mpg"))))
|
|
||||||
else:
|
|
||||||
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_ntsc.mpg"))))
|
|
||||||
xml_file.write('"></vob>\n')
|
|
||||||
xml_file.write('\t\t\t\t<post>\n')
|
|
||||||
xml_file.write('\t\t\t\t\tg0=1;\n')
|
|
||||||
xml_file.write('\t\t\t\t\tg1=0;\n')
|
|
||||||
xml_file.write('\t\t\t\t\tg2=1024;\n')
|
|
||||||
xml_file.write('\t\t\t\t\tcall vmgm menu entry title;\n')
|
|
||||||
xml_file.write('\t\t\t\t</post>\n')
|
|
||||||
xml_file.write('\t\t\t</pgc>\n')
|
|
||||||
xml_file.write('\t\t</titles>\n')
|
|
||||||
xml_file.write("\t</titleset>\n")
|
|
||||||
|
|
||||||
xml_file.write("\n")
|
|
||||||
|
|
||||||
|
|
||||||
# Now, create the titleset for each video
|
|
||||||
|
|
||||||
total_t=len(file_movies)
|
|
||||||
titleset=1
|
|
||||||
titles=0
|
|
||||||
counter=0
|
|
||||||
for element in file_movies:
|
|
||||||
files=0
|
|
||||||
action=element.actions
|
|
||||||
|
|
||||||
xml_file.write("\n")
|
|
||||||
|
|
||||||
if element.is_mpeg_ps:
|
|
||||||
|
|
||||||
# if it's already an MPEG-2 compliant file, we use the original values
|
|
||||||
if element.original_fps == 25:
|
|
||||||
pal_ntsc="pal"
|
|
||||||
ispal=True
|
|
||||||
else:
|
|
||||||
pal_ntsc="ntsc"
|
|
||||||
ispal=False
|
|
||||||
|
|
||||||
if element.original_aspect_ratio > 1.6:
|
|
||||||
faspect='16:9'
|
|
||||||
fwide=True
|
|
||||||
else:
|
|
||||||
faspect='4:3'
|
|
||||||
fwide=False
|
|
||||||
|
|
||||||
else:
|
|
||||||
# but if we are converting it, we use the desired values
|
|
||||||
if element.format_pal:
|
|
||||||
pal_ntsc="pal"
|
|
||||||
ispal=True
|
|
||||||
else:
|
|
||||||
pal_ntsc="ntsc"
|
|
||||||
ispal=False
|
|
||||||
|
|
||||||
if element.aspect_ratio_final > 1.6:
|
|
||||||
faspect='16:9'
|
|
||||||
fwide=True
|
|
||||||
else:
|
|
||||||
faspect='4:3'
|
|
||||||
fwide=False
|
|
||||||
|
|
||||||
xml_file.write("\t<titleset>\n")
|
|
||||||
|
|
||||||
if not onlyone:
|
|
||||||
xml_file.write("\t\t<menus>\n")
|
|
||||||
xml_file.write('\t\t\t<video format="'+pal_ntsc+'" aspect="'+faspect+'"')
|
|
||||||
if fwide:
|
|
||||||
xml_file.write(' widescreen="nopanscan"')
|
|
||||||
xml_file.write('> </video>\n')
|
|
||||||
|
|
||||||
xml_file.write("\t\t\t<pgc>\n")
|
|
||||||
xml_file.write("\t\t\t\t<pre>\n")
|
|
||||||
xml_file.write('\t\t\t\t\tif (g0 eq 100) {\n')
|
|
||||||
xml_file.write('\t\t\t\t\t\tjump vmgm menu entry title;\n')
|
|
||||||
xml_file.write('\t\t\t\t\t}\n')
|
|
||||||
xml_file.write('\t\t\t\t\tg0=100;\n')
|
|
||||||
xml_file.write('\t\t\t\t\tg1='+str(int(titles/elements_per_menu))+';\n')
|
|
||||||
xml_file.write('\t\t\t\t\tjump title 1;\n')
|
|
||||||
xml_file.write('\t\t\t\t</pre>\n')
|
|
||||||
# fake video to ensure compatibility
|
|
||||||
xml_file.write('\t\t\t\t<vob file="')
|
|
||||||
if ispal:
|
|
||||||
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_pal"))))
|
|
||||||
else:
|
|
||||||
xml_file.write(self.expand_xml(str(os.path.join(self.config.other_path,"base_ntsc"))))
|
|
||||||
if fwide:
|
|
||||||
xml_file.write("_wide")
|
|
||||||
xml_file.write('.mpg"></vob>\n')
|
|
||||||
xml_file.write("\t\t\t</pgc>\n")
|
|
||||||
xml_file.write("\t\t</menus>\n")
|
|
||||||
|
|
||||||
xml_file.write("\t\t<titles>\n")
|
|
||||||
xml_file.write('\t\t\t<video format="'+pal_ntsc+'" aspect="'+faspect+'"')
|
|
||||||
if fwide:
|
|
||||||
xml_file.write(' widescreen="nopanscan"')
|
|
||||||
xml_file.write('> </video>\n')
|
|
||||||
|
|
||||||
# subtitles part
|
|
||||||
# for element3 in element2["sub_list"]:
|
|
||||||
# xml_file.write('\t\t\t<subpicture lang="'+self.expand_xml(str(element3["sub_language"][:2].lower()))+'" />\n')
|
|
||||||
xml_file.write('\t\t\t<pgc>\n')
|
|
||||||
|
|
||||||
# if (element2["force_subs"]) and (len(element2["sub_list"])!=0):
|
|
||||||
# xml_file.write('\t\t\t\t<pre>\n')
|
|
||||||
# xml_file.write('\t\t\t\t\tsubtitle=64;\n')
|
|
||||||
# xml_file.write('\t\t\t\t</pre>\n')
|
|
||||||
|
|
||||||
xml_file.write('\t\t\t\t<vob file="'+self.expand_xml(element.converted_filename)+'" ')
|
|
||||||
xml_file.write('chapters="0')
|
|
||||||
if (element.original_length > 5):
|
|
||||||
if (element.divide_in_chapters): # add chapters
|
|
||||||
toadd = element.chapter_size
|
|
||||||
seconds = toadd*60
|
|
||||||
while seconds < (element.original_length - 4):
|
|
||||||
thetime = self.return_time(seconds,False)
|
|
||||||
xml_file.write(","+thetime)
|
|
||||||
seconds += (toadd*60)
|
|
||||||
xml_file.write(',' + self.return_time((element.original_length -2 ),False))
|
|
||||||
xml_file.write('" />\n')
|
|
||||||
|
|
||||||
if not onlyone:
|
|
||||||
xml_file.write('\t\t\t\t<post>\n')
|
|
||||||
files+=1
|
|
||||||
xml_file.write('\t\t\t\t\tg1='+str(int(titles/elements_per_menu))+';\n')
|
|
||||||
if (action=="action_stop"):
|
|
||||||
xml_file.write('\t\t\t\t\tg0=100;\n')
|
|
||||||
xml_file.write('\t\t\t\t\tcall vmgm menu entry title;\n')
|
|
||||||
else:
|
|
||||||
xml_file.write('\t\t\t\t\tg0=')
|
|
||||||
if action=="action_play_previous":
|
|
||||||
if titles == 0:
|
|
||||||
prev_t = total_t - 1
|
|
||||||
else:
|
|
||||||
prev_t = titles - 1
|
|
||||||
xml_file.write(str(title_list[prev_t]))
|
|
||||||
elif action=="action_play_again":
|
|
||||||
xml_file.write(str(title_list[titles]))
|
|
||||||
elif action=="action_play_next":
|
|
||||||
if titles==total_t-1:
|
|
||||||
next_t=0
|
|
||||||
else:
|
|
||||||
next_t=titles+1
|
|
||||||
xml_file.write(str(title_list[next_t]))
|
|
||||||
elif action=="action_play_last":
|
|
||||||
xml_file.write(str(title_list[total_t-1]))
|
|
||||||
else:
|
|
||||||
xml_file.write('1') # first
|
|
||||||
|
|
||||||
xml_file.write(';\n')
|
|
||||||
xml_file.write('\t\t\t\t\tcall vmgm menu entry title;\n')
|
|
||||||
xml_file.write('\t\t\t\t</post>\n')
|
|
||||||
xml_file.write("\t\t\t</pgc>\n")
|
|
||||||
xml_file.write("\t\t</titles>\n")
|
|
||||||
xml_file.write("\t</titleset>\n")
|
|
||||||
counter+=1
|
|
||||||
titles+=1
|
|
||||||
|
|
||||||
xml_file.write("</dvdauthor>")
|
|
||||||
|
|
||||||
xml_file.close()
|
|
||||||
|
|
||||||
|
|
||||||
def return_time(self,seconds,empty):
|
|
||||||
|
|
||||||
""" cuts a time in seconds into seconds, minutes and hours """
|
|
||||||
|
|
||||||
seconds2=int(seconds)
|
|
||||||
|
|
||||||
hours=str(int(seconds2/3600))
|
|
||||||
if empty:
|
|
||||||
if len(hours)==1:
|
|
||||||
hours="0"+hours
|
|
||||||
else:
|
|
||||||
if hours=="0":
|
|
||||||
hours=""
|
|
||||||
if hours!="":
|
|
||||||
hours+=":"
|
|
||||||
|
|
||||||
minutes=str(int((seconds2/60)%60))
|
|
||||||
if empty or (hours!=""):
|
|
||||||
if len(minutes)==1:
|
|
||||||
minutes="0"+minutes
|
|
||||||
elif (minutes=="0") and (hours==""):
|
|
||||||
minutes=""
|
|
||||||
if minutes!="":
|
|
||||||
minutes+=":"
|
|
||||||
|
|
||||||
secs=str(int(seconds2%60))
|
|
||||||
if (len(secs)==1) and (minutes!=""):
|
|
||||||
secs="0"+secs
|
|
||||||
|
|
||||||
return hours+minutes+secs
|
|
||||||
|
|
||||||
|
|
||||||
def disc_done(self,object,value):
|
def disc_done(self,object,value):
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue