4 #Viper - Video In Python Editing Reptile, a video editor
5 #Copyright 2009 - 2010 Paul Hänsch
7 #This file is part of Viper.
9 #Viper is free software: you can redistribute it and/or modify
10 #it under the terms of the GNU General Public License as published by
11 #the Free Software Foundation, either version 3 of the License, or
12 #(at your option) any later version.
14 #Viper is distributed in the hope that it will be useful,
15 #but WITHOUT ANY WARRANTY; without even the implied warranty of
16 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 #GNU General Public License for more details.
19 #You should have received a copy of the GNU General Public License
20 #along with Viper. If not, see <http://www.gnu.org/licenses/>
23 from timeline import *
24 from videoview import *
27 from pysqlite2 import dbapi2 as sqlite
41 self.protocol('WM_DELETE_WINDOW', self.quit)
44 upper = Frame(self, height = 300)
45 upper.pack(side = TOP, expand = True, fill = BOTH)
47 self.subgets['menubar'] = Menu(self)
48 self.config(menu = self.subgets['menubar'])
49 self.subgets['timeline'] = Timeline(self)
50 self.subgets['timeline'].pack(fill = X, side = BOTTOM, anchor = S)
51 self.subgets['mainview'] = VideoView(upper)
52 self.subgets['mainview'].place( relx = .55, rely = 0, relwidth = .45, relheight = 1)
53 self.subgets['editbook'] = Pmw.NoteBook(upper)
54 self.subgets['editbook'].place( relx = 0, rely = 0, relwidth = .55, relheight = 1)
55 self.subgets['filtertab'] = self.subgets['editbook'].add('Filters')
56 self.subgets['effecttab'] = self.subgets['editbook'].add('Effects')
57 self.subgets['filterdiag'] = FilterDiag( self.subgets['filtertab'] )
58 self.subgets['filterdiag'].pack( expand = True, fill = BOTH)
59 self.subgets['effectdiag'] = EffectDiag( self.subgets['effecttab'] )
60 self.subgets['effectdiag'].pack( expand = True, fill = BOTH)
62 self.subgets['timeline'].set_view(self.subgets['mainview'])
63 self.subgets['timeline'].set_mods([self.subgets['filterdiag'],
64 self.subgets['effectdiag']
75 file_menu.add_command(label = 'Open Project', command = self.open_project)
76 file_menu.add_command(label = 'Save Project', command = self.save_project)
77 file_menu.add_command(label = 'Save Project As...', command = self.named_save_project)
78 file_menu.add_separator()
79 file_menu.add_command(label = 'Import Video', command = self.open_video)
80 file_menu.add_command(label = 'Export Video', command = self.export_video)
81 file_menu.add_separator()
82 file_menu.add_command(label = 'Quit', command = self.quit)
86 view_menu.add_checkbutton(label = 'Animate Chunks',
87 variable = self.subgets['timeline'].animChunks,
88 command = self.subgets['timeline'].switch_animChunks)
90 self.subgets['menubar'].add_cascade(label='File', menu = file_menu)
91 self.subgets['menubar'].add_cascade(label='View', menu = view_menu)
92 self.subgets['menubar'].add_command(label='Help')
94 def m_animChunks(self):
97 def save_project(self):
99 Save a project to project directory
101 call named_save_project() if no
102 project directory is set yet
105 self.named_save_project()
107 def named_save_project(self):
109 Ask for directory to save to (and save project)
112 savedir = tkFileDialog.asksaveasfilename(filetypes = [('Viper Project Directory', '*.vpd')])
114 dbcon = sqlite.connect(savedir + '/description.sqlite')
115 dbcur = dbcon.cursor()
116 dbcur.execute('CREATE TABLE chunks (iorder INTEGER PRIMARY KEY, filename TEXT, start REAL, frames INTEGER, played INTEGER, marked BOOLEAN);')
117 dbcur.execute('CREATE TABLE filters (iorder INTEGER PRIMARY KEY, chunk INTEGER, FOREIGN KEY (chunk) REFERENCES chunks (iorder));')
118 dbcur.execute('CREATE TABLE filter_lines (iorder INTEGER PRIMARY KEY, line TEXT, filter INTEGER, FOREIGN KEY (filter) REFERENCES filters (iorder));')
119 for chunk in self.subgets['timeline'].chunks:
126 def open_project(self):
128 Load a previously saved project
129 (includes Open-Dialog)
132 opendir = tkFileDialog.askopenfilename(filetypes = [('Project Description', '*/description.sqlite')])
134 for chunk in self.subgets['timeline'].chunks: chunk.delete()
136 dbcon = sqlite.connect(opendir)
137 dbcur = dbcon.cursor()
139 dbcur.execute('SELECT iorder, filename, start, frames, played, marked ' +
140 'FROM chunks ORDER BY iorder;')
141 for vc in dbcur.fetchall():
142 self.subgets['timeline'].add(file = vc[1], start = vc[2], frames = vc[3])
143 if vc[4] == 1: self.subgets['timeline'].chunks[-1].played.set(True)
144 else: self.subgets['timeline'].chunks[-1].played.set(False)
145 if vc[5] == 1: self.subgets['timeline'].chunks[-1].marked.set(True)
146 else: self.subgets['timeline'].chunks[-1].marked.set(False)
147 self.subgets['timeline'].chunks[-1].load_filters(dbcur, vc[0])
149 def export_video(self):
153 for vc in self.subgets['timeline'].chunks:
155 fileExport.export(self.subgets['timeline'].chunks)
157 def open_video(self):
162 filetypes = [('3GP Cell Phone Video', '*.3gp'),
163 ('Advanced Systems Format', '*.asf'),
164 ('Advanced Video Codec High Definition', '*.avchd'),
165 ('Audio Video Interleave', '*.avi'),
166 ('Digital Video (Tape/Disc)', '*.dv'),
167 ('DVD Track', '*.vob'),
168 ('Flash Video', '*.flv *.swf'),
169 ('Matroska', '*.mkv *.MKV'),
170 ('Moving Pictures Experts Group (MPEG)', '*.mpe *.mpeg *.mpg'),
171 ('MPEG 1', '*.m1v *.mp1 *.mpg1'),
172 ('MPEG 2', '*.m2v *.mp2 *.mpg2'),
173 ('MPEG 4', '*.m4v *.mp4 *.mpg4'),
174 ('Ogg Media Stream', '*.ogg *.ogm'),
175 ('Quake 3', '*.roq'),
176 ('Quick Time', '*.mov'),
177 ('Real Media', '*.rm'),
178 ('Windows Media Video', '*.wmv'),
179 ('Undefined', '*.flic *.vid *.video'),
183 for type in filetypes:
184 typelist.append((type[0], type[1] + ' ' + type[1].upper()))
185 mimes += ' ' + type[1]
187 typelist.insert(0, ('All known Video File Types', mimes))
188 typelist.append(('All Types', '*'))
189 files = tkFileDialog.askopenfilenames(parent = self,
190 title = 'Import Video',
193 for file in files: self.subgets['timeline'].add(file)
197 Gracefully terminate the program
199 self.subgets['mainview'].stop_video()
200 if not self.subgets['mainview'].attached_view:
201 self.subgets['mainview'].attach_view()
202 for chunk in self.subgets['timeline'].chunks:
204 self.after(50, self.destroy)
207 #win.wm_geometry("800x600")