From 754714caab85adbb6c80df522ab914fd5e898be7 Mon Sep 17 00:00:00 2001 From: Sergio Costas Date: Wed, 6 Aug 2014 00:38:19 +0200 Subject: [PATCH] Now asks when the user tries to overwrite a project file Added the ffmpeg compatibility file (forgot to do before) --- data/interface/wsave_project.ui | 1 - src/devede/ffmpeg_converter.py | 389 ++++++++++++++++++++++++++++++++ src/devede/project.py | 18 +- 3 files changed, 401 insertions(+), 7 deletions(-) create mode 100644 src/devede/ffmpeg_converter.py diff --git a/data/interface/wsave_project.ui b/data/interface/wsave_project.ui index 3d09cef..fd3c2b7 100644 --- a/data/interface/wsave_project.ui +++ b/data/interface/wsave_project.ui @@ -9,7 +9,6 @@ devede.svg normal save - True False diff --git a/src/devede/ffmpeg_converter.py b/src/devede/ffmpeg_converter.py new file mode 100644 index 0000000..5513256 --- /dev/null +++ b/src/devede/ffmpeg_converter.py @@ -0,0 +1,389 @@ +#!/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 + +import subprocess +import os +import devede.configuration_data +import devede.executor +import devede.mux_dvd_menu +import devede.ffmpeg_converter + +class ffmpeg_converter(devede.executor.executor): + + supports_analize = False + supports_play = False + supports_convert = True + supports_menu = True + supports_burn = False + display_name = "FFMPEG" + disc_types = [] + + @staticmethod + def check_is_installed(): + try: + handle = subprocess.Popen(["ffmpeg","-codecs"], stdout = subprocess.PIPE, stderr = subprocess.PIPE) + (stdout, stderr) = handle.communicate() + if 0==handle.wait(): + mp2 = False + mp3 = False + ac3 = False + mpeg1 = False + mpeg2 = False + divx = False + h264 = False + for line in stdout.decode("latin-1").split("\n"): + parts = line.strip().split(" ") + if len(parts) < 2: + continue + if len(parts[0]) != 6: + continue + capabilities = parts[0] + codec = parts[1] + + if capabilities[1] != 'E': + continue + + if (codec == "mpeg1video"): + mpeg1 = True + continue + if (codec == "mpeg2video"): + mpeg2 = True + continue + if (codec == "mp2"): + mp2 = True + continue + if (codec == "mp3"): + mp3 = True + continue + if (codec == "ac3"): + ac3 = True + continue + if (codec == "h264") or (codec == "H264"): + h264 = True + continue + if (codec == "mpeg4"): + divx = True + continue + + if (mpeg1 and mp2): + devede.ffmpeg_converter.ffmpeg_converter.disc_types.append("vcd") + if (mpeg2 and mp2): + devede.ffmpeg_converter.ffmpeg_converter.disc_types.append("svcd") + devede.ffmpeg_converter.ffmpeg_converter.disc_types.append("cvd") + if (mpeg2 and mp2 and ac3): + devede.ffmpeg_converter.ffmpeg_converter.disc_types.append("dvd") + if (divx and mp3): + devede.ffmpeg_converter.ffmpeg_converter.disc_types.append("divx") + if (h264 and mp3): + devede.ffmpeg_converter.ffmpeg_converter.disc_types.append("mkv") + + return True + else: + return False + except: + return False + + def __init__(self): + + devede.executor.executor.__init__(self) + self.config = devede.configuration_data.configuration.get_config() + + def convert_file(self,file_project,output_file,video_length): + + self.text = _("Converting %(X)s") % {"X" : file_project.title_name} + + if (video_length == 0): + self.final_length = file_project.original_length + else: + self.final_length = video_length + self.command_var=[] + self.command_var.append("ffmpeg") + self.command_var.append("-i") + self.command_var.append(file_project.file_name) + + if (file_project.volume!=100): + self.command_var.append("-vol") + self.command_var.append(str((256*file_project.volume)/100)) + + if (file_project.audio_delay != 0.0) and (file_project.copy_sound==False) and (file_project.no_reencode_audio_video==False): + self.command_var.append("-itsoffset") + self.command_var.append(str(file_project.audio_delay)) + + self.command_var.append("-i") + self.command_var.append(file_project.file_name) + self.command_var.append("-map") + self.command_var.append("1:0") + if (not file_project.copy_sound) and (not file_project.no_reencode_audio_video): + for l in range (file_project.audio_streams): + self.command_var.append("-map") + self.command_var.append("0"+":"+str(l+1)) + + if (file_project.no_reencode_audio_video==False): + cmd_line="" + + if file_project.deinterlace=="deinterlace_yadif": + cmd_line+="yadif" + + vflip=False + hflip=False + + if (file_project.rotation=="rotation_90"): + if (cmd_line!=""): + cmd_line+=",fifo," + cmd_line+="transpose=1" + elif (file_project.rotation=="rotation_270"): + if (cmd_line!=""): + cmd_line+=",fifo," + cmd_line+="transpose=2" + elif (file_project.rotation=="rotation_180"): + vflip=True + hflip=True + + if (file_project.mirror_vertical): + vflip=not vflip + if (file_project.mirror_horizontal): + hflip=not hflip + + if (vflip): + if (cmd_line!=""): + cmd_line+=",fifo," + cmd_line+="vflip" + if (hflip): + if (cmd_line!=""): + cmd_line+=",fifo," + cmd_line+="hflip" + + if (file_project.width_midle != file_project.original_width) or (file_project.height_midle != file_project.original_height): + if (cmd_line!=""): + cmd_line+=",fifo," + x = int((file_project.width_midle - file_project.original_width) /2) + y = int((file_project.height_midle - file_project.original_height) /2) + if (x > 0) or (y > 0): + cmd_line+="pad="+str(file_project.width_midle)+":"+str(file_project.height_midle)+":"+str(x)+":"+str(y)+":0x000000" + else: + cmd_line+="crop="+str(file_project.width_midle)+":"+str(file_project.height_midle)+":"+str(x)+":"+str(y) + + if (file_project.width_final != file_project.width_midle) or (file_project.height_final != file_project.height_midle): + if (cmd_line!=""): + cmd_line+=",fifo," + cmd_line+="scale="+str(file_project.width_final)+":"+str(file_project.height_final) + + if cmd_line!="": + self.command_var.append("-vf") + self.command_var.append(cmd_line) + + + self.command_var.append("-y") + + vcd=False + + if (self.config.disc_type == "divx"): + self.command_var.append("-vcodec") + self.command_var.append("mpeg4") + self.command_var.append("-acodec") + self.command_var.append("libmp3lame") + self.command_var.append("-f") + self.command_var.append("avi") + elif (self.config.disc_type == "mkv"): + self.command_var.append("-vcodec") + self.command_var.append("h264") + self.command_var.append("-acodec") + self.command_var.append("libmp3lame") + self.command_var.append("-f") + self.command_var.append("matroska") + else: + self.command_var.append("-target") + if (self.config.disc_type=="dvd"): + if not file_project.format_pal: + self.command_var.append("ntsc-dvd") + elif (file_project.original_fps==24): + self.command_var.append("film-dvd") + else: + self.command_var.append("pal-dvd") + if (not file_project.copy_sound): + self.command_var.append("-acodec") + self.command_var.append("ac3") + elif (self.config.disc_type=="vcd"): + vcd=True + if not file_project.format_pal: + self.command_var.append("ntsc-vcd") + else: + self.command_var.append("pal-vcd") + elif (self.config.disc_type=="svcd"): + if not file_project.format_pal: + self.command_var.append("ntsc-svcd") + else: + self.command_var.append("pal-svcd") + elif (self.config.disc_type=="cvd"): + if not file_project.format_pal: + self.command_var.append("ntsc-svcd") + else: + self.command_var.append("pal-svcd") + + if (not file_project.no_reencode_audio_video): + self.command_var.append("-sn") # no subtitles + + if file_project.copy_sound or file_project.no_reencode_audio_video: + self.command_var.append("-acodec") + self.command_var.append("copy") + + if file_project.no_reencode_audio_video: + self.command_var.append("-vcodec") + self.command_var.append("copy") + + if (vcd==False): + if not file_project.format_pal: + if (file_project.original_fps==24) and ((self.config.disc_type=="dvd")): + keyintv=15 + else: + keyintv=18 + else: + keyintv=15 + + if not file_project.gop12: + self.command_var.append("-g") + self.command_var.append(str(keyintv)) + + if (self.config.disc_type=="divx") or (self.config.disc_type=="mkv"): + self.command_var.append("-g") + self.command_var.append("300") + elif file_project.gop12 and (file_project.no_reencode_audio_video==False): + self.command_var.append("-g") + self.command_var.append("12") + + self.command_var.append("-bf") + self.command_var.append("2") + self.command_var.append("-strict") + self.command_var.append("1") + + if video_length != 0: + self.command_var.append("-t") + self.command_var.append(str(video_length)) + + self.command_var.append("-ac") + if (file_project.sound5_1) and ((self.config.disc_type=="dvd") or (self.config.disc_type=="divx") or (self.config.disc_type=="mkv")): + self.command_var.append("6") + else: + self.command_var.append("2") + + self.command_var.append("-aspect") + self.command_var.append(str(file_project.aspect_ratio_final)) + + if self.config.disc_type=="divx": + self.command_var.append("-vtag") + self.command_var.append("DX50") + + if (file_project.deinterlace == "deinterlace_ffmpeg") and (file_project.no_reencode_audio_video==False): + self.command_var.append("-deinterlace") + + if (file_project.no_reencode_audio_video==False) and (vcd==False): + self.command_var.append("-s") + self.command_var.append(str(file_project.width_final)+"x"+str(file_project.height_final)) + + self.command_var.append("-trellis") + self.command_var.append("1") + + self.command_var.append("-mbd") + self.command_var.append("2") + + if (vcd == False) and (file_project.no_reencode_audio_video == False): + self.command_var.append("-b:a") + self.command_var.append(str(file_project.audio_rate_final)+"k") + + self.command_var.append("-b:v") + self.command_var.append(str(file_project.video_rate_final)+"k") + + self.command_var.append(output_file) + + + + def create_menu_mpeg(self,n_page,background_music,sound_length,pal,video_rate, audio_rate,output_path): + + self.n_page = n_page + self.final_length = float(sound_length) + self.text = _("Creating menu %(X)d") % {"X": self.n_page} + + self.command_var=[] + self.command_var.append("ffmpeg") + + self.command_var.append("-loop") + self.command_var.append("1") + + self.command_var.append("-f") + self.command_var.append("image2") + self.command_var.append("-i") + self.command_var.append(os.path.join(output_path,"menu_"+str(n_page)+"_bg.png")) + self.command_var.append("-i") + self.command_var.append(background_music) + + self.command_var.append("-y") + self.command_var.append("-target") + if pal: + self.command_var.append("pal-dvd") + else: + self.command_var.append("ntsc-dvd") + self.command_var.append("-acodec") + self.command_var.append("mp2") + self.command_var.append("-s") + if pal: + self.command_var.append("720x576") + else: + self.command_var.append("720x480") + self.command_var.append("-g") + self.command_var.append("12") + self.command_var.append("-b:v") + self.command_var.append(str(video_rate)+"k") + self.command_var.append("-b:a") + self.command_var.append(str(audio_rate)+"k") + self.command_var.append("-aspect") + self.command_var.append("4:3") + + self.command_var.append("-t") + self.command_var.append(str(1+sound_length)) + + movie_path = os.path.join(output_path,"menu_"+str(n_page)+".mpg") + self.command_var.append(movie_path) + + muxer = devede.mux_dvd_menu.mux_dvd_menu() + final_path = muxer.create_mpg(n_page,output_path,movie_path) + # the muxer process depends of the converter process + muxer.add_dependency(self) + self.add_child_process(muxer) + + return (final_path) + + def process_stdout(self,data): + + return + + def process_stderr(self,data): + + pos = data[0].find("time=") + if (pos != -1): + pos+=5 + pos2 = data[0].find(" ",pos) + if (pos2 != -1): + parts = data[0][pos:pos2].split(":") + t = 0.0 + for e in parts: + t *= 60.0 + t += float(e) + t /= self.final_length + self.progress_bar[1].set_fraction(t) + self.progress_bar[1].set_text("%.1f%%" % (100.0 * t)) \ No newline at end of file diff --git a/src/devede/project.py b/src/devede/project.py index 3beb4ab..6615e82 100644 --- a/src/devede/project.py +++ b/src/devede/project.py @@ -547,11 +547,20 @@ class devede_project: def on_save_as_activate(self,b): - w = devede.opensave.opensave_window(True) - retval = w.run(self.project_file) - if retval != None: + while True: + w = devede.opensave.opensave_window(True) + retval = w.run(self.project_file) + if retval == None: + return + if not retval.endswith(".devedeng"): + retval += ".devedeng" + if os.path.isfile(retval): + w = devede.ask.ask_window() + if not w.run(_("The file already exists. Overwrite it?"), _("The file already exists")): + continue self.project_file = retval self.save_current_project() + return def on_load_activate(self,b): @@ -565,9 +574,6 @@ class devede_project: project = {} - if not self.project_file.endswith(".devedeng"): - self.project_file += ".devedeng" - project["PAL"] = self.wuse_pal.get_active() project["create_menu"] = self.wcreate_menu.get_active() project["disc_type"] = self.config.disc_type