f696d69e6312e9fa6b86352b58cc17da6dbb1a7b
[biamove.git] / mainwindow.py
1 # Main Window class for the BiaMovE application
2
3 import Tkinter
4 import tkFileDialog
5 import tkSimpleDialog
6 import tkMessageBox
7 import os
8 import os.path
9 import subprocess
10 import sys
11 import ConfigParser as CP
12
13 # import all the dialog classes
14 from audiocodecdialogs import *
15 from videofilterdialogs import *
16 from videocodecdialogs import *
17 from videomuxerdialogs import *
18 from miscdialogs import *
19
20 class MainWindow (Tkinter.Frame):
21 """The main window class of the BiaMovE application"""
22 def on_misc_options (self):
23 """ Called when the misc options button is clicked"""
24 miscdlg = MiscOptionsDialog (self)
25 if miscdlg.result != None:
26 self.otherparameters.set (miscdlg.result)
27
28 def on_videofilters (self):
29 """Called when the video filters button is clicked"""
30 if self.outputvideo.get().split()[0] == "copy":
31 tkMessageBox.showinfo ("Video filters", "You cannot apply filters when the video stream is directly copied. Change the video codec.")
32 else:
33 filtersdlg = VideoFiltersDialog (self)
34 if filtersdlg.result != None:
35 self.videofilters.set (filtersdlg.result)
36
37 def build_mencoder_command (self):
38 """ To build the mencoder command """
39
40 # mencoder command line
41 commandlist = ["mencoder",]
42
43 # dvd options (if present)
44 for item in self.dvdopts.get().split():
45 commandlist.append (item)
46
47 # output format
48 commandlist.append ("-of")
49 commandlist.append (self.outputcontainer.get().split()[0])
50
51 for item in self.outputcontaineropts.get().split():
52 commandlist.append (item)
53
54 # video codec
55 commandlist.append ("-ovc")
56 commandlist.append (self.outputvideo.get().split()[0])
57
58 for item in self.videoopts.get().split():
59 commandlist.append (item)
60
61 # audio codec
62 commandlist.append ("-oac")
63 commandlist.append (self.outputaudio.get().split()[0])
64
65 for item in self.audioopts.get().split():
66 commandlist.append (item)
67
68 # video filters
69 if self.videofilters.get().strip() != "":
70 commandlist.append ("-vf")
71 commandlist.append (self.videofilters.get().strip())
72
73 # misc options
74 for item in self.otherparameters.get().split():
75 commandlist.append (item)
76
77 # input file
78 commandlist.append (self.inputfile.get())
79
80 # output file
81 commandlist.append ("-o")
82 commandlist.append (self.outputfile.get())
83
84 return commandlist
85
86 def on_encode (self):
87 """Called when the encode button is clicked"""
88 if self.inputfile.get().strip() == "" or self.outputfile.get().strip() == "":
89 tkMessageBox.showerror ("Cannot encode", "No input and/or output file specified")
90 else:
91 commandlist = self.build_mencoder_command ()
92
93 if tkMessageBox.askyesno ("Confirm", "Are you sure you wish to encode (in *NIX you must have TERM environment variable set)?"):
94 if sys.platform.startswith ('win'):
95 po, pi = os.popen2 ("cmd /K " + subprocess.list2cmdline (commandlist))
96 else:
97 if "TERM" in os.environ:
98 if os.environ["TERM"] == "xterm":
99 term_command = os.environ["TERM"] + " -hold -e " + subprocess.list2cmdline (commandlist)
100 else:
101 term_command = os.environ["TERM"] + " -e " + subprocess.list2cmdline(commandlist)
102 po, pi = os.popen2 (term_command)
103 else:
104 tkMessageBox.showerror ("Cannot encode", "The TERM environment variable is not set. Cannot find a suitable terminal.")
105
106 def on_save_profile (self):
107 """ Called when the save profile button is clicked"""
108 profile_name = tkSimpleDialog.askstring ("Save profile", "Give a name for this profile")
109 if profile_name != None:
110 config = CP.SafeConfigParser ()
111
112 cfgfile = os.path.join (os.path.expanduser ("~"), ".biamoverc")
113
114 config.read ( cfgfile )
115 if (config.has_section (profile_name)):
116 if not tkMessageBox.askyesno ("Section exists", "This section exists. Do you wish to overwrite the settings?"):
117 return
118 else:
119 config.add_section (profile_name)
120
121 config.set (profile_name, "ContainerFormat", self.outputcontainer.get())
122 config.set (profile_name, "VideoCodec", self.outputvideo.get())
123 config.set (profile_name, "AudioCodec", self.outputaudio.get())
124 config.set (profile_name, "ContainerParameters", self.outputcontaineropts.get())
125 config.set (profile_name, "VideoParameters", self.videoopts.get())
126 config.set (profile_name, "AudioParameters", self.audioopts.get())
127 config.set (profile_name, "VideoFilters", self.videofilters.get())
128 config.set (profile_name, "OtherParameters", self.otherparameters.get())
129
130 config.write (file (cfgfile, "w"))
131
132 def on_load_profile (self):
133 """ Called when the load profile button is clicked"""
134 loaddlg = ProfileLoadDialog (self)
135 sect = loaddlg.result
136 if sect != None:
137 config = CP.SafeConfigParser ()
138 cfgfile = os.path.join (os.path.expanduser("~"), ".biamoverc")
139 config.read (cfgfile)
140
141 if (config.has_section (sect)):
142 self.outputcontainer.set (config.get (sect, "ContainerFormat"))
143 self.outputvideo.set (config.get (sect, "VideoCodec"))
144 self.outputaudio.set (config.get (sect, "AudioCodec"))
145 self.outputcontaineropts.set (config.get (sect, "ContainerParameters"))
146 self.videoopts.set (config.get (sect, "VideoParameters"))
147 self.audioopts.set (config.get (sect, "AudioParameters"))
148 self.videofilters.set (config.get (sect, "VideoFilters"))
149 self.otherparameters.set (config.get (sect, "OtherParameters"))
150
151 def on_container_options (self):
152 """ Called when the container options button is clicked"""
153 containerfmt = self.outputcontainer.get().split()[0]
154 if (containerfmt == "lavf"):
155 lavfdlg = LAVFMuxerDialog (self)
156 if lavfdlg.result != None:
157 self.outputcontaineropts.set (lavfdlg.result)
158 elif (containerfmt == "mpeg"):
159 mpegdlg = MPEGMuxerDialog (self)
160 if mpegdlg.result != None:
161 self.outputcontaineropts.set (mpegdlg.result)
162 else:
163 tkMessageBox.showinfo ("Muxer options","No options for this muxer or options not implemented yet")
164 self.outputcontaineropts.set ("")
165
166 def on_codec_video (self):
167 """ Called when the video codec options button is clicked"""
168 videocodec = self.outputvideo.get().split()[0]
169 if (videocodec == "nuv"):
170 nuvdlg = NUVDialog (self)
171 if nuvdlg.result != None:
172 self.videoopts.set (nuvdlg.result)
173 elif (videocodec == "lavc"):
174 lavcdlg = LAVCVideoDialog (self)
175 if lavcdlg.result != None:
176 self.videoopts.set (lavcdlg.result)
177 elif (videocodec == "xvid"):
178 xviddlg = XvidEncDialog (self)
179 if xviddlg.result != None:
180 self.videoopts.set (xviddlg.result)
181 elif (videocodec == "x264"):
182 x264dlg = X264EncDialog (self)
183 if x264dlg.result != None:
184 self.videoopts.set (x264dlg.result)
185 else:
186 tkMessageBox.showinfo ("Video options", "No options for this codec or options not implemented yet")
187 self.videoopts.set ("")
188
189 def on_codec_audio (self):
190 """ Called when the audio codec options button is clicked"""
191
192 # if the output audio codec is lavc show the lavc codec dialog
193 audiocodec = self.outputaudio.get().split()[0]
194 if (audiocodec == "lavc"):
195 lavcdlg = LAVCAudioDialog (self)
196 if lavcdlg.result != None:
197 self.audioopts.set (lavcdlg.result)
198 # if the output audio codec is lame show the lame codec dialog
199 elif (audiocodec == "mp3lame"):
200 lamedlg = LAMEDialog (self)
201 if lamedlg.result != None:
202 self.audioopts.set (lamedlg.result)
203 elif (audiocodec == "twolame"):
204 twolamedlg = TwolameDialog (self)
205 if twolamedlg.result != None:
206 self.audioopts.set (twolamedlg.result)
207 elif (audiocodec == "faac"):
208 faacdlg = FAACDialog (self)
209 if faacdlg.result != None:
210 self.audioopts.set (faacdlg.result)
211 else:
212 tkMessageBox.showinfo ("Audio options", "No options for this codec or options not implemented yet")
213 self.audioopts.set ("")
214
215 def on_input_browse (self):
216 """Called when the input browse button is clicked"""
217 infile = tkFileDialog.askopenfilename ()
218 if infile != None:
219 self.inputfile.set (infile)
220
221 def on_output_browse (self):
222 """ Called when the output browse button is clicked"""
223 outfile = tkFileDialog.asksaveasfilename ()
224 if outfile != None:
225 self.outputfile.set (outfile)
226
227 def on_dvd_device (self):
228 """ called when the DVD options button is clicked"""
229 dvddlg = DVDDialog (self)
230 if dvddlg.result != None:
231 self.inputfile.set (dvddlg.result)
232 self.dvdopts.set (dvddlg.result_args)
233
234 def create_widgets (self):
235 """ Called during __init__ """
236 Tkinter.Label (self, text="You need Mencoder installed (compiled with appropriate codecs) for this program to function properly. This program does NOT detect which codecs are available and which are not.", fg = "darkblue", wraplength=600).grid(column=0, row=0, columnspan=4)
237
238 Tkinter.Label (self, text="Input file/source URL").grid (column=0, row=1)
239
240 self.inputfile = Tkinter.StringVar ()
241 Tkinter.Entry (self, textvariable=self.inputfile).grid (column=1, row=1)
242
243 Tkinter.Button (self, text="browse...", command=self.on_input_browse).grid (column=2, row=1)
244
245 dvdframe = Tkinter.Frame (self)
246
247 self.dvdopts = Tkinter.StringVar ()
248
249 Tkinter.Button (dvdframe, text="DVD...", command=self.on_dvd_device).pack (side=Tkinter.LEFT)
250 Tkinter.Entry (dvdframe, textvariable=self.dvdopts).pack (side=Tkinter.RIGHT)
251
252 dvdframe.grid (column=3, row=1, columnspan=2)
253
254 Tkinter.Label (self, text="Output file").grid (column=0, row=2)
255
256 self.outputfile = Tkinter.StringVar ()
257 Tkinter.Entry (self, textvariable=self.outputfile).grid (column=1, row=2)
258
259 Tkinter.Button (self, text="browse...", command=self.on_output_browse).grid (column=2, row=2)
260
261 Tkinter.Label (self, text="mencoder options", fg="darkblue").grid (column=0, row=3, pady=5, columnspan=4)
262
263 Tkinter.Label (self, text="Output container format").grid (column=0, row=4)
264
265 self.outputcontainer = Tkinter.StringVar()
266 self.outputcontainer.set ("avi Microsoft AVI")
267 Tkinter.OptionMenu (self, self.outputcontainer, "avi Microsoft AVI", "mpeg MPEG 1/2 stream", "lavf FFMPEG libavformat muxers", "rawvideo Raw video (only) stream", "rawaudio Raw audio (only) stream").grid (column=1, row=4)
268
269 Tkinter.Button (self, text="Container options...", command=self.on_container_options).grid (column=2, row=4)
270
271 self.outputcontaineropts = Tkinter.StringVar ()
272 Tkinter.Entry (self, textvariable=self.outputcontaineropts).grid (column=3, row=4)
273
274 Tkinter.Label (self, text="Output video codec").grid (column=0, row=5)
275
276 self.outputvideo = Tkinter.StringVar ()
277 self.outputvideo.set ("copy Frames copy")
278 Tkinter.OptionMenu (self, self.outputvideo, "copy Frames copy", "raw Uncompressed video", "nuv Nuppel video", "lavc FFMPEG codecs ", "xvid XviD encoding", "x264 H.264 encoding").grid (column=1, row=5)
279
280 Tkinter.Button (self, text="codec options...", command=self.on_codec_video).grid (column=2, row=5)
281
282 self.videoopts = Tkinter.StringVar ()
283 Tkinter.Entry (self, textvariable=self.videoopts).grid (column=3, row=5)
284
285 Tkinter.Label (self, text="Output audio codec").grid (column=0, row=6)
286
287 self.outputaudio = Tkinter.StringVar ()
288 self.outputaudio.set ("copy Frames copy")
289 Tkinter.OptionMenu (self, self.outputaudio, "copy Frames copy", "pcm Uncompressed PCM", "mp3lame MP3 using LAME", "lavc FFMPEG codecs", "twolame TwoLAME MP2", "faac FAAC AAC Audio").grid (column=1, row=6)
290
291 Tkinter.Button (self, text="codec options...", command = self.on_codec_audio).grid (column=2, row=6)
292
293 self.audioopts = Tkinter.StringVar ()
294 Tkinter.Entry (self, textvariable = self.audioopts).grid (column=3, row=6)
295
296 Tkinter.Label (self, text="Video filters").grid (column=0, row=7)
297 Tkinter.Button (self, text="setup filters...", command=self.on_videofilters).grid (column=1, row=7)
298
299 self.videofilters = Tkinter.StringVar ()
300 Tkinter.Entry (self, textvariable=self.videofilters).grid (column=2, row=7)
301
302 Tkinter.Label (self, text="Other Mencoder parameters").grid (column=0, row=8, pady=10)
303
304 Tkinter.Button (self, text="Misc Options...", command=self.on_misc_options).grid (column=1, row=8)
305
306 self.otherparameters = Tkinter.StringVar ()
307 Tkinter.Entry (self, textvariable=self.otherparameters).grid (column=2, row=8)
308
309 Tkinter.Label (self, text="Save/Load Profile", fg="darkblue").grid (column=0, row=9, pady=5, columnspan=2)
310
311 leftframe = Tkinter.Frame (self)
312 Tkinter.Button (leftframe, text="Save...", command=self.on_save_profile).pack (side=Tkinter.LEFT)
313 Tkinter.Button (leftframe, text="Load...", command=self.on_load_profile).pack (side=Tkinter.RIGHT)
314 leftframe.grid (column=0, row=10, columnspan=2)
315
316 Tkinter.Label (self, text="Actions", fg="darkblue").grid (column=2, row=9, pady=5, columnspan=2)
317
318 rightframe = Tkinter.Frame (self)
319 Tkinter.Button (rightframe, text="Encode", command=self.on_encode).pack (side=Tkinter.LEFT)
320 Tkinter.Button (rightframe, text="Quit", command=self.quit).pack (side=Tkinter.RIGHT)
321 rightframe.grid (column=2, row=10, columnspan=2)
322
323 def __init__ (self, master=None):
324 Tkinter.Frame.__init__ (self, master)
325
326 self.grid (padx=10,pady=10)
327 self.create_widgets ()