I was making a VCD the other day for my kid and rediscover how hard it can be to make one of those – in Ubuntu-. I love the OS but every application that I tried was from useless to lousy, as often happen in the Linux world I discover the absolute best tools are on the command line.
While I don’t mind playing with the terminal, the truth is there’s no way I’ll ever remember all those special flags, parameters and other strange things you need to re-encode videos, so I decided to try my freshly acquired Python knowledge to make a small tool to pass my commands to the terminal and encode the videos using mencoder.
I was harder than expected and the final result could be better, but it’s not bad for a first hands on!
To develop this project I used:
- Geany. For coding
- Glade. To design the interface
Functionalities:
- Can convert a single video to VCD or SVCD
- Can crop a single video (Time start – Time End) < Both in seconds
- Can convert all videos in a directory to VCD or SVCD
Problems:
- The progress bar is useless, it never seems to update
- Better to be run from terminal so you can see the actual progress of the task
The source:
This code include the glade file, the final .xml to define the interface and the python file (Change the format after downloading)
VCDmaker.zip
The python code.
-
#!/usr/bin/env python
-
-
# gtk-builder-convert tutorial.glade vcdmaker.xml
-
# Then save this file as tutorial.py and make it executable using this command:
-
# chmod a+x vcdtrigger.py
-
# And execute it:
-
# ./vcdtrigger.py
-
-
import pygtk
-
pygtk.require("2.0")
-
import gtk
-
import os
-
import subprocess
-
-
class vcd(object):
-
def __init__(self):
-
builder = gtk.Builder()
-
builder.add_from_file("vcdmaker.xml")
-
builder.connect_signals(self)
-
self.window = builder.get_object("Video Maker")
-
self.saveas = builder.get_object("txt_saveas")
-
self.filesource = builder.get_object("file_source")
-
self.dirsource = builder.get_object("dirchooser")
-
self.dirsource.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
-
self.pbar = builder.get_object("progressbar1")
-
self.type = builder.get_object("sel_target")
-
self.type.set_active(1)
-
self.output = builder.get_object("txtoutput")
-
self.ini = builder.get_object("spin_start")
-
self.end = builder.get_object("spin_end")
-
self.window.show()
-
-
def on_window_destroy(self, widget, data=None):
-
gtk.main_quit()
-
-
def target_name(self,filename):
-
parts = os.path.split(filename)
-
name = parts[1]
-
name = name.replace(" ","_")
-
name = name.lower()
-
ext = os.path.splitext(name)[1]
-
ext = ext[1:]
-
ext = ext.lower()
-
videoformats = [‘mpg’,‘avi’,‘mpeg’, ‘flv’]
-
if (ext in videoformats):
-
return(parts[0] + os.sep + "VCD" + os.sep + "VCD_" + os.path.splitext(name)[0]+".mpg")
-
else:
-
return False
-
-
def on_dirchooser_file_set(self, dir_chooser):
-
self.saveas.set_text("Multiple")
-
-
def on_file_source_file_set(self, file_chooser):
-
if (self.filesource.get_filename() != None):
-
saveas = self.target_name(self.filesource.get_filename())
-
if (saveas != False):
-
self.saveas.set_text(saveas)
-
else:
-
self.error_message ("Please select a video file")
-
-
def on_btnstart_clicked(self, button):
-
if (self.saveas.get_text() == ""):
-
print("Please select a file first")
-
self.error_message("Please select a file first")
-
elif self.saveas.get_text() == "Multiple":
-
print self.dirsource.get_filename()
-
self.convert_all(self.dirsource.get_filename(), self.type.get_active())
-
else:
-
targetdir = os.path.split(self.saveas.get_text())
-
print (targetdir)
-
self.check_target_dir(targetdir[0])
-
c = converter()
-
if self.type.get_active() == 1:
-
c.svcd(self.filesource.get_filename(), self.saveas.get_text(), self.ini.get_value_as_int(), self.end.get_value_as_int())
-
else:
-
c.vcd(self.filesource.get_filename(), self.saveas.get_text(), self.ini.get_value_as_int(), self.end.get_value_as_int())
-
-
-
def check_target_dir(self, dirname):
-
print (dirname)
-
if not os.path.isdir(dirname):
-
os.makedirs(dirname)
-
-
-
def convert_all(self, dir, format):
-
print ("dir: %s" % dir)
-
c = converter()
-
self.check_target_dir(dir + os.sep + "VCD")
-
x=0
-
for directory, subdirectories, files in os.walk(dir):
-
file_count = len(files)
-
if (x==0):
-
self.pbar.set_text("Processing %d" % file_count)
-
for file in files:
-
x +=1
-
print ("Processing file %d of %d " % (x, file_count))
-
self.pbar.set_fraction( x / file_count)
-
print (x/file_count)
-
source = os.path.join(directory,file)
-
target = self.target_name(source)
-
if self.type.get_active() ==1:
-
c.svcd(source, target, 0, 0)
-
else:
-
c.vcd(source, target, 0, 0)
-
-
def error_message(self, message):
-
print message
-
dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, message)
-
dialog.run()
-
dialog.destroy()
-
-
class converter:
-
def test(self):
-
print ("test ok")
-
-
def get_common_cmd(self, source, ini, end):
-
command = [‘mencoder’, source]
-
if (ini != 0 ):
-
command.append("-ss")
-
command.append("%d" % ini)
-
if (end!=0):
-
command.append("-endpos")
-
command.append("%d " % end)
-
return command
-
-
def vcd(self, source, target, ini=0, end=0):
-
command = self.get_common_cmd(source, ini,end)
-
command += [‘-oac’ ,‘lavc’ ,‘-ovc’ ,‘lavc’ ,‘-of’ ,‘mpeg’ ,‘-mpegopts’ ,‘format=xsvcd’ ,‘-vf’ ,‘scale=480:576,harddup’ ,‘-srate’ ,‘44100’ ,‘-af’ ,‘lavcresample=44100’ ,‘-lavcopts’ ,‘vcodec=mpeg2video:mbd=2:keyint=15:vrc_buf_size=917:vrc_minrate=600:vbitrate=2500:vrc_maxrate=2500:acodec=mp2:abitrate=224:aspect=16/9’ ,‘-ofps’ ,’25’ ,‘-o’, target]
-
self.convert(command)
-
-
def svcd(self,source, target, ini=0, end=0):
-
command = self.get_common_cmd(source, ini,end)
-
command += [‘-oac’, ‘lavc’ ,‘-ovc’, ‘lavc’ ,‘-of’ ,‘mpeg’ ,‘-mpegopts’ ,‘format=xvcd’ ,‘-vf’ ,‘scale=352:288,harddup’ ,‘-srate’, ‘44100’ ,‘-af’ ,‘lavcresample=44100’ ,‘-lavcopts’ ,‘vcodec=mpeg1video:keyint=15:vrc_buf_size=327:vrc_minrate=1152:vbitrate=1152:vrc_maxrate=1152:acodec=mp2:abitrate=224:aspect=16/9’ ,‘-ofps’ ,’25’ ,‘-o’, target]
-
self.convert(command)
-
-
def convert (self, command):
-
print (command)
-
#Execute the actual command and put result in text
-
#os.execl ("mencoder", command)
-
subprocess.call(command)
-
-
if __name__ == "__main__":
-
app = vcd()
-
gtk.main()
-