4 # Viper - Video In Python Editing Reptile, a video editor
5 # Copyright 2009 - 2011 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
104 if self.subgets['timeline'].get_basedir() == None:
105 self.named_save_project()
107 savedir = self.subgets['timeline'].get_basedir()
108 try: os.unlink(savedir + '/description.sqlite')
111 dbcon = sqlite.connect(savedir + '/description.sqlite')
112 dbcur = dbcon.cursor()
113 dbcur.execute('CREATE TABLE chunks (iorder INTEGER PRIMARY KEY, filename TEXT, start REAL, frames INTEGER, played INTEGER, marked BOOLEAN);')
114 dbcur.execute('CREATE TABLE filters (iorder INTEGER PRIMARY KEY, chunk INTEGER, FOREIGN KEY (chunk) REFERENCES chunks (iorder));')
115 dbcur.execute('CREATE TABLE filter_lines (iorder INTEGER PRIMARY KEY, line TEXT, filter INTEGER, FOREIGN KEY (filter) REFERENCES filters (iorder));')
116 for chunk in self.subgets['timeline'].chunks:
123 def named_save_project(self):
125 Ask for directory to save to (and save project)
127 savedir = tkFileDialog.asksaveasfilename(filetypes = [('Viper Project Directory', '*.vpd')])
129 self.subgets['timeline'].set_basedir(savedir)
132 def open_project(self):
134 Load a previously saved project
135 (includes Open-Dialog)
138 opendir = tkFileDialog.askopenfilename(filetypes = [('Project Description', '*/description.sqlite')])
139 self.subgets['timeline'].set_basedir(opendir[0:-19])
141 for chunk in self.subgets['timeline'].chunks: chunk.delete()
143 dbcon = sqlite.connect(opendir)
144 dbcur = dbcon.cursor()
146 dbcur.execute('SELECT iorder, filename, start, frames, played, marked ' +
147 'FROM chunks ORDER BY iorder;')
148 for vc in dbcur.fetchall():
149 self.subgets['timeline'].add(file = vc[1], start = vc[2], frames = vc[3])
150 if vc[4] == 1: self.subgets['timeline'].chunks[-1].played.set(True)
151 else: self.subgets['timeline'].chunks[-1].played.set(False)
152 if vc[5] == 1: self.subgets['timeline'].chunks[-1].marked.set(True)
153 else: self.subgets['timeline'].chunks[-1].marked.set(False)
154 self.subgets['timeline'].chunks[-1].load_filters(dbcur, vc[0])
156 def export_video(self):
160 for vc in self.subgets['timeline'].chunks:
162 fileExport.export(self.subgets['timeline'].chunks)
164 def open_video(self):
169 filetypes = [('3GP Cell Phone Video', '*.3gp'),
170 ('Advanced Systems Format', '*.asf'),
171 ('Advanced Video Codec High Definition', '*.avchd'),
172 ('Audio Video Interleave', '*.avi'),
173 ('Digital Video (Tape/Disc)', '*.dv'),
174 ('DVD Track', '*.vob'),
175 ('Flash Video', '*.flv *.swf'),
176 ('Matroska', '*.mkv *.MKV'),
177 ('Moving Pictures Experts Group (MPEG)', '*.mpe *.mpeg *.mpg'),
178 ('MPEG 1', '*.m1v *.mp1 *.mpg1'),
179 ('MPEG 2', '*.m2v *.mp2 *.mpg2'),
180 ('MPEG 4', '*.m4v *.mp4 *.mpg4'),
181 ('Ogg Media Stream', '*.ogg *.ogm'),
182 ('Quake 3', '*.roq'),
183 ('Quick Time', '*.mov'),
184 ('Real Media', '*.rm'),
185 ('Windows Media Video', '*.wmv'),
186 ('Undefined', '*.flic *.vid *.video'),
190 for type in filetypes:
191 typelist.append((type[0], type[1] + ' ' + type[1].upper()))
192 mimes += ' ' + type[1]
194 typelist.insert(0, ('All known Video File Types', mimes))
195 typelist.append(('All Types', '*'))
196 files = tkFileDialog.askopenfilenames(parent = self,
197 title = 'Import Video',
200 for file in files: self.subgets['timeline'].add(file)
204 Gracefully terminate the program
206 self.subgets['mainview'].stop_video()
207 if not self.subgets['mainview'].attached_view:
208 self.subgets['mainview'].attach_view()
209 for chunk in self.subgets['timeline'].chunks:
211 self.after(50, self.destroy)
214 #win.wm_geometry("800x600")