Now creates the XML for dvd menues, and multiplex them with the MPEG file
Now allows to send a file to stdin in a process, and store stdout in another file
This commit is contained in:
parent
86f77faa3f
commit
e404f27e45
7 changed files with 204 additions and 24 deletions
|
|
@ -6,6 +6,7 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Creating...</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center</property>
|
||||
<property name="icon_name">devede.svg</property>
|
||||
<property name="deletable">False</property>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
from gi.repository import GLib
|
||||
import subprocess
|
||||
import os
|
||||
import devede.configuration_data
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ class create_disk_window:
|
|||
self.shutdown = wshutdown.get_active()
|
||||
wcreate_window.destroy()
|
||||
if (retval == 1):
|
||||
self.config.final_folder = self.path
|
||||
self.config.save_config()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -21,17 +21,17 @@ import os
|
|||
import devede.configuration_data
|
||||
import devede.interface_manager
|
||||
import devede.message
|
||||
import devede.mux_dvd_menu
|
||||
|
||||
class dvd_menu(devede.interface_manager.interface_manager):
|
||||
|
||||
def __init__(self,project):
|
||||
def __init__(self):
|
||||
|
||||
self.entry_vertical_margin = 2.0
|
||||
self.entry_separation = 2.0
|
||||
|
||||
devede.interface_manager.interface_manager.__init__(self)
|
||||
self.config = devede.configuration_data.configuration.get_config()
|
||||
self.project = project
|
||||
|
||||
self.default_background = os.path.join(self.config.pic_path,"backgrounds","default_bg.png")
|
||||
self.default_sound = os.path.join(self.config.pic_path,"silence.ogg")
|
||||
|
|
@ -101,10 +101,11 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
self.update_ui(self.builder)
|
||||
|
||||
|
||||
def show_configuration(self):
|
||||
def show_configuration(self, file_list):
|
||||
|
||||
self.builder = Gtk.Builder()
|
||||
self.builder.set_translation_domain(self.config.gettext_domain)
|
||||
self.file_list = file_list
|
||||
|
||||
self.refresh_static_data()
|
||||
|
||||
|
|
@ -270,14 +271,14 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
""" This method sets data that can't be changed from the dvd settings window.
|
||||
It must be called before painting a menu """
|
||||
|
||||
if self.project.pal:
|
||||
if self.config.PAL:
|
||||
self.y=576.0
|
||||
else:
|
||||
self.y=480.0
|
||||
|
||||
self.title_list = []
|
||||
counter = 0
|
||||
for element in self.project.get_all_files():
|
||||
for element in self.file_list:
|
||||
if element.show_in_menu:
|
||||
self.title_list.append( (element, counter) )
|
||||
counter += 1
|
||||
|
|
@ -289,6 +290,8 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
|
||||
def paint_menu(self,paint_background, paint_selected, paint_activated, page_number):
|
||||
|
||||
coordinates = []
|
||||
|
||||
if self.sf == None:
|
||||
self.sf=cairo.ImageSurface(cairo.FORMAT_ARGB32,720,int(self.y))
|
||||
self.cr=cairo.Context(self.sf)
|
||||
|
|
@ -316,9 +319,9 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
self.cr.restore()
|
||||
hmargin = self.title_horizontal * 720.0 / 100.0
|
||||
self.write_text(self.title_text, "title", 0 + hmargin, 720 + hmargin, self.title_vertical * self.y / 100.0, "center")
|
||||
else:
|
||||
self.cr.set_source_rgb(1.0,1.0,1.0)
|
||||
self.cr.paint()
|
||||
# else:
|
||||
# self.cr.set_source_rgb(1.0,1.0,1.0)
|
||||
# self.cr.paint()
|
||||
|
||||
top_margin_p = self.y * self.margin_top / 100.0
|
||||
bottom_margin_p = self.y * self.margin_bottom / 100.0
|
||||
|
|
@ -345,7 +348,9 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
xl = left_margin_p
|
||||
xr = 720.0 - right_margin_p
|
||||
y = top_margin_p + entry_height/2.0
|
||||
height = (self.cached_menu_size + self.entry_vertical_margin) / 2.0
|
||||
for entry in self.title_list[page_number*entries_per_page:(page_number+1)*entries_per_page]:
|
||||
coordinates.append([xl, y-height, xr, y+height, "entry"])
|
||||
text = entry[0].title_name
|
||||
if paint_background:
|
||||
self.paint_base(xl, xr, y, 0)
|
||||
|
|
@ -355,8 +360,10 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
if paint_activated:
|
||||
self.write_text(text, "menu_entry_activated", xl, xr, y, self.position_horizontal)
|
||||
y += entry_height
|
||||
|
||||
if paint_arrows:
|
||||
if page_number == 0:
|
||||
coordinates.append([xl, y-height, xr, y+height, "right"])
|
||||
if paint_background:
|
||||
self.paint_base(xl, xr, y, 0)
|
||||
self.paint_arrow(xl, xr, y, "menu_entry", False)
|
||||
|
|
@ -365,6 +372,7 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
if paint_activated:
|
||||
self.paint_arrow(xl, xr, y, "menu_entry_activated", False)
|
||||
elif page_number == (self.pages - 1):
|
||||
coordinates.append([xl, y-height, xr, y+height, "left"])
|
||||
if paint_background:
|
||||
self.paint_base(xl, xr, y, 0)
|
||||
self.paint_arrow(xl, xr, y, "menu_entry", True)
|
||||
|
|
@ -374,6 +382,8 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
self.paint_arrow(xl, xr, y, "menu_entry_activated", True)
|
||||
else:
|
||||
med = (xl + xr) / 2.0
|
||||
coordinates.append([xl, y-height, med, y+height, "left"])
|
||||
coordinates.append([med, y-height, xr, y+height, "right"])
|
||||
if paint_background:
|
||||
self.paint_base(xl, xr, y, 1)
|
||||
self.paint_base(xl, xr, y, 2)
|
||||
|
|
@ -385,6 +395,7 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
if paint_activated:
|
||||
self.paint_arrow(med, xr, y, "menu_entry_activated", False)
|
||||
self.paint_arrow(xl, med, y, "menu_entry_activated", True)
|
||||
return coordinates
|
||||
|
||||
def paint_base(self,xl, xr, y, type_b):
|
||||
|
||||
|
|
@ -435,8 +446,74 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
cr.set_source_surface(self.sf)
|
||||
cr.paint()
|
||||
|
||||
def create_dvd_menus(self,base_path):
|
||||
def create_menu_stream(self,path,n_page,coordinates):
|
||||
|
||||
""" Creates the menu XML file """
|
||||
|
||||
xml_file=open(os.path.join(path,"menu_"+str(n_page)+".xml"),"w")
|
||||
xml_file.write('<subpictures>\n\t<stream>\n\t\t<spu force="yes" start="00:00:00.00"')# transparent="000000"')
|
||||
xml_file.write(' image="'+os.path.join(path,"menu_"+str(n_page)+'_unselected_bg.png"'))
|
||||
xml_file.write(' highlight="'+os.path.join(path,"menu_"+str(n_page)+'_selected_bg.png"'))
|
||||
xml_file.write(' select="'+os.path.join(path,"menu_"+str(n_page)+'_active_bg.png"'))
|
||||
xml_file.write(' >\n')
|
||||
n_elements = 0
|
||||
has_next = False
|
||||
has_previous = False
|
||||
for e in coordinates:
|
||||
if (e[4] == "entry"):
|
||||
n_elements += 1
|
||||
continue
|
||||
if (e[4] == "right"):
|
||||
has_next = True
|
||||
continue
|
||||
if (e[4] == "left"):
|
||||
has_previous = True
|
||||
continue
|
||||
|
||||
counter = 0
|
||||
for element in coordinates:
|
||||
xl = int(element[0])
|
||||
yt = int(element[1])
|
||||
xr = int(element[2])
|
||||
yb = int(element[3])
|
||||
if (xl % 2) == 1:
|
||||
xl += 1
|
||||
if (yt % 2) == 1:
|
||||
yt += 1
|
||||
if (xr % 2) == 1:
|
||||
xr -= 1
|
||||
if (yb % 2) == 1:
|
||||
yb -= 1
|
||||
xml_file.write('\t\t\t<button name="boton'+str(n_page)+"x"+str(counter))
|
||||
xml_file.write('" x0="'+str(xl)+'" y0="'+str(yt)+'" x1="'+str(xr)+'" y1="'+str(yb)+'"')
|
||||
if counter > 0:
|
||||
xml_file.write(' up="boton'+str(n_page)+"x")
|
||||
if counter >= n_elements:
|
||||
xml_file.write(str(n_elements - 1))
|
||||
else:
|
||||
xml_file.write(str(counter-1))
|
||||
xml_file.write('"')
|
||||
|
||||
if (counter < (n_elements - 1)) or ((counter < n_elements) and (has_next or has_previous)):
|
||||
xml_file.write(' down="boton'+str(n_page)+"x")
|
||||
xml_file.write(str(counter+1))
|
||||
xml_file.write('"')
|
||||
if (element[4] == "left") and (has_next):
|
||||
xml_file.write(' right="boton'+str(n_page)+'x'+str(counter+1)+'"')
|
||||
if (element[4] == "right") and (has_previous):
|
||||
xml_file.write(' left="boton'+str(n_page)+'x'+str(counter-1)+'"')
|
||||
xml_file.write(' > </button>\n')
|
||||
counter += 1
|
||||
|
||||
xml_file.write("</spu>\n</stream>\n</subpictures>\n")
|
||||
xml_file.close()
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def create_dvd_menus(self, file_list, base_path):
|
||||
|
||||
self.file_list = file_list
|
||||
self.refresh_static_data()
|
||||
cv = devede.converter.converter()
|
||||
menu_folder = os.path.join(base_path,"menu")
|
||||
|
|
@ -450,7 +527,7 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
menu_converter = cv.get_menu_converter()
|
||||
while n_page < self.pages:
|
||||
self.sf = None
|
||||
self.paint_menu(True, False, False, n_page)
|
||||
coordinates = self.paint_menu(True, False, False, n_page)
|
||||
self.sf.write_to_png(os.path.join(menu_folder,"menu_"+str(n_page)+"_bg.png"))
|
||||
self.sf = None
|
||||
self.paint_menu(False, False, False, n_page)
|
||||
|
|
@ -461,9 +538,14 @@ class dvd_menu(devede.interface_manager.interface_manager):
|
|||
self.sf = None
|
||||
self.paint_menu(False, False, True, n_page)
|
||||
self.sf.write_to_png(os.path.join(menu_folder,"menu_"+str(n_page)+"_active_bg.png"))
|
||||
self.create_menu_stream(menu_folder, n_page, coordinates)
|
||||
converter = menu_converter()
|
||||
converter.create_mpg(n_page,self.background_music,self.sound_length,self.project.pal,menu_folder)
|
||||
converter.create_mpg(n_page,self.background_music,self.sound_length,self.config.PAL,menu_folder)
|
||||
# add this process without dependencies
|
||||
processes.append([converter, None])
|
||||
muxer = devede.mux_dvd_menu.mux_dvd_menu()
|
||||
muxer.create_mpg(n_page,menu_folder)
|
||||
# the muxer process depends of the converter process
|
||||
processes.append([muxer, [converter]])
|
||||
n_page += 1
|
||||
return processes
|
||||
|
|
@ -33,11 +33,14 @@ class executor(GObject.GObject):
|
|||
GObject.GObject.__init__(self)
|
||||
|
||||
self.config = devede.configuration_data.configuration.get_config()
|
||||
self.channel_stdin = None
|
||||
self.channel_stdout = None
|
||||
self.channel_stderr = None
|
||||
self.text = ""
|
||||
self.stdout_data = ""
|
||||
self.stderr_data = ""
|
||||
self.stdin_file = None
|
||||
self.stdout_file = None
|
||||
|
||||
def run(self, progress_bar):
|
||||
|
||||
|
|
@ -48,7 +51,7 @@ class executor(GObject.GObject):
|
|||
self.progress_bar[0].show_all()
|
||||
|
||||
def remove_ansi(self,line):
|
||||
|
||||
|
||||
output=""
|
||||
while True:
|
||||
pos=line.find("\033[") # try with double-byte ESC
|
||||
|
|
@ -59,10 +62,10 @@ class executor(GObject.GObject):
|
|||
if pos==-1: # no ANSI characters; we ended
|
||||
output+=line
|
||||
break
|
||||
|
||||
|
||||
output+=line[:pos]
|
||||
line=line[pos+jump:]
|
||||
|
||||
|
||||
while True:
|
||||
if len(line)==0:
|
||||
break
|
||||
|
|
@ -76,23 +79,60 @@ class executor(GObject.GObject):
|
|||
|
||||
def launch_process(self,command):
|
||||
|
||||
self.config.append_log("Launching:",False)
|
||||
self.launch_command = "Launching:"
|
||||
for e in command:
|
||||
self.config.append_log(e+" ")
|
||||
self.launch_command += (e+" ")
|
||||
|
||||
self.handle = subprocess.Popen(command,stdout = subprocess.PIPE, stderr = subprocess.PIPE)
|
||||
if (self.stdin_file != None):
|
||||
self.handle = subprocess.Popen(command,stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
|
||||
self.channel_stdin = GLib.IOChannel(self.handle.stdin.fileno())
|
||||
self.channel_stdin.add_watch(GLib.IO_OUT | GLib.IO_HUP, self.read_stdin_from_file)
|
||||
self.file_in = open(self.stdin_file,"rb")
|
||||
else:
|
||||
self.handle = subprocess.Popen(command,stdout = subprocess.PIPE, stderr = subprocess.PIPE)
|
||||
self.channel_stdout = GLib.IOChannel(self.handle.stdout.fileno())
|
||||
self.channel_stderr = GLib.IOChannel(self.handle.stderr.fileno())
|
||||
self.channel_stdout.add_watch(GLib.IO_IN | GLib.IO_HUP,self.read_stdout)
|
||||
if (self.stdout_file != None):
|
||||
self.channel_stdout.add_watch(GLib.IO_IN | GLib.IO_HUP,self.read_stdout_to_file)
|
||||
self.file_out = open(self.stdout_file,"wb")
|
||||
else:
|
||||
self.channel_stdout.add_watch(GLib.IO_IN | GLib.IO_HUP,self.read_stdout)
|
||||
self.channel_stderr.add_watch(GLib.IO_IN | GLib.IO_HUP,self.read_stderr)
|
||||
self.stdout_buf = ""
|
||||
self.stderr_buf = ""
|
||||
|
||||
|
||||
def read_stdout_to_file(self,source,condition):
|
||||
|
||||
if (condition != GLib.IO_IN):
|
||||
self.channel_stdout = None
|
||||
if ((self.channel_stderr == None) and (self.channel_stdin == None)):
|
||||
self.wait_end()
|
||||
return False
|
||||
else:
|
||||
line_data = self.handle.stdout.read1(4096)
|
||||
self.file_out.write(line_data)
|
||||
return True
|
||||
|
||||
def read_stdin_from_file(self,source,condition):
|
||||
|
||||
line_data = self.file_in.read1(4096)
|
||||
if (len(line_data) == 0):
|
||||
self.channel_stdin = None
|
||||
self.handle.stdin.close()
|
||||
if ((self.channel_stderr == None) and (self.channel_stdout == None)):
|
||||
self.wait_end()
|
||||
return False
|
||||
else:
|
||||
self.handle.stdin.write(line_data)
|
||||
return True
|
||||
|
||||
|
||||
def read_stdout(self,source,condition):
|
||||
|
||||
if (condition != GLib.IO_IN):
|
||||
self.channel_stdout = None
|
||||
if (self.channel_stderr == None):
|
||||
if ((self.channel_stderr == None) and (self.channel_stdin == None)):
|
||||
self.wait_end()
|
||||
return False
|
||||
else:
|
||||
|
|
@ -109,11 +149,12 @@ class executor(GObject.GObject):
|
|||
self.process_stdout(final_data)
|
||||
return True
|
||||
|
||||
|
||||
def read_stderr(self,source,condition):
|
||||
|
||||
if (condition != GLib.IO_IN):
|
||||
self.channel_stderr = None
|
||||
if (self.channel_stdout == None):
|
||||
if ((self.channel_stdout == None) and (self.channel_stdin == None)):
|
||||
self.wait_end()
|
||||
return False
|
||||
else:
|
||||
|
|
@ -142,6 +183,7 @@ class executor(GObject.GObject):
|
|||
def wait_end(self):
|
||||
|
||||
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.stderr_data)
|
||||
retval = self.handle.wait()
|
||||
|
|
|
|||
54
src/devede/mux_dvd_menu.py
Normal file
54
src/devede/mux_dvd_menu.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#!/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 mux_dvd_menu(devede.executor.executor):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
devede.executor.executor.__init__(self)
|
||||
self.config = devede.configuration_data.configuration.get_config()
|
||||
|
||||
def create_mpg(self,n_page,output_path):
|
||||
|
||||
self.n_page = n_page
|
||||
self.text = _("Mixing menu %(X)d") % {"X": self.n_page}
|
||||
|
||||
self.command_var=[]
|
||||
self.command_var.append("spumux")
|
||||
self.command_var.append(os.path.join(output_path,"menu_"+str(n_page)+".xml"))
|
||||
self.stdin_file = os.path.join(output_path,"menu_"+str(n_page)+".mpg")
|
||||
self.stdout_file = os.path.join(output_path,"menu_"+str(n_page)+"B.mpg")
|
||||
|
||||
|
||||
def process_stderr(self,data):
|
||||
|
||||
print("spumux: "+str(data))
|
||||
return
|
||||
|
||||
pos = data[0].find("time=")
|
||||
if (pos != -1):
|
||||
pos+=5
|
||||
pos2 = data[0].find(" ",pos)
|
||||
if (pos2 != -1):
|
||||
t = float(data[0][pos:pos2])
|
||||
self.progress_bar[1].set_fraction(t / self.sound_length)
|
||||
|
|
@ -33,7 +33,7 @@ class devede_project:
|
|||
self.config = devede.configuration_data.configuration.get_config()
|
||||
|
||||
self.disc_type = self.config.disc_type
|
||||
self.menu = devede.dvd_menu.dvd_menu(self)
|
||||
self.menu = devede.dvd_menu.dvd_menu()
|
||||
|
||||
self.current_title = None
|
||||
|
||||
|
|
@ -252,7 +252,7 @@ class devede_project:
|
|||
|
||||
def on_menu_options_clicked(self,b):
|
||||
|
||||
self.menu.show_configuration()
|
||||
self.menu.show_configuration(self.get_all_files())
|
||||
|
||||
def on_create_disc_clicked(self,b):
|
||||
|
||||
|
|
@ -262,6 +262,6 @@ class devede_project:
|
|||
|
||||
run_window = devede.runner.runner()
|
||||
|
||||
p = self.menu.create_dvd_menus(data.path)
|
||||
p = self.menu.create_dvd_menus(self.get_all_files(), data.path)
|
||||
run_window.add_processes(p)
|
||||
run_window.run()
|
||||
Loading…
Add table
Add a link
Reference in a new issue