基本功能:
1, 拖入含音轨的媒体文件(任意格式), 列出音轨, 选中需要压制的音轨, 选择压缩选项, 然后单击”Go”即可开始压制.
以下是全部代码:
#Boa:Frame:Frame1
# -*- coding: utf-8 -*-
import wx
import re
import time
import sys, os
import threading
import subprocess
#if cmp(sys.platform[:3],'win')!=0:
# reload(sys)
# sys.setdefaultencoding('utf8')
f=[] #File List
fd=[] #File Duration List
s=[] #Stream List
sf=[] #Stream to File
arg = ''
arg2 = ''
fn = 0 #File Index
def create(parent):
return Frame1(parent)
[wxID_FRAME1, wxID_FRAME1BUTTON1, wxID_FRAME1CHECKBOX1, wxID_FRAME1LISTBOX1,
wxID_FRAME1RADIOBUTTON1, wxID_FRAME1RADIOBUTTON2, wxID_FRAME1STATICTEXT1,
wxID_FRAME1TEXTCTRL1, wxID_FRAME1TEXTCTRL2,
] = [wx.NewId() for _init_ctrls in range(9)]
class Frame1(wx.Frame):
def _init_coll_flexGridSizer1_Items(self, parent):
# generated method, don't edit
parent.AddWindow(self.staticText1, 0, border=5, flag=wx.ALL)
parent.AddWindow(self.textCtrl1, 1, border=5,
flag=wx.GROW | wx.ALL | wx.EXPAND)
parent.AddWindow(self.button1, 0, border=5, flag=wx.ALL)
parent.AddWindow(self.checkBox1, 0, border=5, flag=wx.ALL)
def _init_coll_flexGridSizer2_Items(self, parent):
# generated method, don't edit
parent.AddWindow(self.radioButton1, 0, border=5, flag=wx.ALL)
parent.AddWindow(self.radioButton2, 0, border=5, flag=wx.ALL)
parent.AddWindow(self.textCtrl2, 0, border=5, flag=wx.ALL)
def _init_coll_boxSizer1_Items(self, parent):
# generated method, don't edit
parent.AddWindow(self.listBox1, 2, border=5,
flag=wx.ALL | wx.GROW | wx.EXPAND)
parent.AddSizer(self.flexGridSizer1, 0, border=0, flag=0)
parent.AddSizer(self.flexGridSizer2, 0, border=0, flag=0)
def _init_sizers(self):
# generated method, don't edit
self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
self.flexGridSizer1 = wx.FlexGridSizer(cols=0, hgap=0, rows=1, vgap=0)
self.flexGridSizer2 = wx.FlexGridSizer(cols=0, hgap=0, rows=1, vgap=0)
self._init_coll_boxSizer1_Items(self.boxSizer1)
self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
self._init_coll_flexGridSizer2_Items(self.flexGridSizer2)
self.SetSizer(self.boxSizer1)
def _init_ctrls(self, prnt):
# generated method, don't edit
wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,
pos=wx.Point(766, 341), size=wx.Size(518, 349),
style=wx.DEFAULT_FRAME_STYLE,
title=u'\u97f3\u8f68\u538b\u5236 v0.1a - By Felix Yan')
self.SetClientSize(wx.Size(518, 349))
self.SetBackgroundColour(wx.Colour(222, 222, 222))
self.Bind(wx.EVT_CLOSE, self.OnFrame1Close)
self.listBox1 = wx.ListBox(choices=[], id=wxID_FRAME1LISTBOX1,
name='listBox1', parent=self, pos=wx.Point(5, 5),
size=wx.Size(508, 267), style=0)
self.listBox1.Bind(wx.EVT_LISTBOX, self.OnListBox1Listbox,
id=wxID_FRAME1LISTBOX1)
self.staticText1 = wx.StaticText(id=wxID_FRAME1STATICTEXT1,
label=u'\u8f93\u51fa\u6587\u4ef6\u540d:', name='staticText1',
parent=self, pos=wx.Point(5, 282), size=wx.Size(69, 17), style=0)
self.textCtrl1 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL1, name='textCtrl1',
parent=self, pos=wx.Point(84, 282), size=wx.Size(160, 27),
style=0, value=u'')
self.button1 = wx.Button(id=wxID_FRAME1BUTTON1, label=u'Go',
name='button1', parent=self, pos=wx.Point(254, 282),
size=wx.Size(85, 27), style=0)
self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,
id=wxID_FRAME1BUTTON1)
self.checkBox1 = wx.CheckBox(id=wxID_FRAME1CHECKBOX1,
label=u'\u964d\u52302.0\u58f0\u9053', name='checkBox1',
parent=self, pos=wx.Point(349, 282), size=wx.Size(122, 22),
style=0)
self.checkBox1.SetValue(True)
self.radioButton1 = wx.RadioButton(id=wxID_FRAME1RADIOBUTTON1,
label=u'\u5b9a\u8d28\u91cf(-q)', name='radioButton1', parent=self,
pos=wx.Point(5, 319), size=wx.Size(90, 21), style=0)
self.radioButton1.SetValue(True)
self.radioButton1.Bind(wx.EVT_RADIOBUTTON,
self.OnRadioButton1Radiobutton, id=wxID_FRAME1RADIOBUTTON1)
self.radioButton2 = wx.RadioButton(id=wxID_FRAME1RADIOBUTTON2,
label=u'\u5b9a\u7801\u7387(-br)(\u5355\u4f4d:Kbps)',
name='radioButton2', parent=self, pos=wx.Point(105, 319),
size=wx.Size(191, 21), style=0)
self.radioButton2.Bind(wx.EVT_RADIOBUTTON,
self.OnRadioButton2Radiobutton, id=wxID_FRAME1RADIOBUTTON2)
self.textCtrl2 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL2, name='textCtrl2',
parent=self, pos=wx.Point(306, 319), size=wx.Size(80, 25),
style=0, value=u'0.25')
self._init_sizers()
def __init__(self, parent):
self._init_ctrls(parent)
dt = MyFileDropTarget(self.listBox1)
self.listBox1.SetDropTarget(dt)
def OnFrame1Close(self, event):
exit()
def updateProgress(self, i):
self.flag = self.progress.Update(i)
def destroyProgress(self):
self.flag = self.progress.Destroy()
def OnButton1Button(self, event):
global sf,f,s,arg,arg2,fn
a = self.listBox1.GetSelections()[:]
if len(a)>0:
pstream = re.compile('\#(\d\.\d)')
map=pstream.findall(s[a[0]/3].encode(sys.getfilesystemencoding()))[0].replace('.',':')
if self.checkBox1.GetValue():
ac = ' -ac 2 '
else:
ac = ' '
if cmp(sys.platform[:3],'win')==0:
path = "\\".join(f[sf[a[0]/3]].split("\\")[:-1]) + "\\"
else:
path = "/".join(f[sf[a[0]/3]].split("/")[:-1]) + "/"
if self.radioButton1.GetValue():
q='-q '+self.textCtrl2.GetValue().encode(sys.getfilesystemencoding())
else:
q='-br '+self.textCtrl2.GetValue().encode(sys.getfilesystemencoding())
arg = 'ffmpeg -i \"' + f[sf[a[0]/3]].encode(sys.getfilesystemencoding()) + '\" -vn -f wav -map '
arg += map + ac + '-'
arg2 = 'neroAacEnc -ignorelength ' + q + ' -if - -of \"' + path.encode(sys.getfilesystemencoding()) + self.textCtrl1.GetValue().encode(sys.getfilesystemencoding()) +'\"'
fn = a[0]/3
#wx.MessageBox(arg)
print arg
self.progress = wx.ProgressDialog(u"Working...", u"正在压制音轨, 请稍候…", 100, style=wx.PD_AUTO_HIDE)
self.t = TRun(self)
self.t.setDaemon(True)
self.t.start()
event.Skip()
def OnListBox1Listbox(self, event):
global sf,f
a = self.listBox1.GetSelections()
if len(a)>0:
self.listBox1.SetSelection(a[0]/3*3+1)
self.textCtrl1.SetValue('.'.join(f[sf[a[0]/3]].split("\\")[-1].split("/")[-1].split('.')[:-1])+'.m4a')
event.Skip()
def OnRadioButton1Radiobutton(self, event):
self.textCtrl2.SetValue('0.25')
event.Skip()
def OnRadioButton2Radiobutton(self, event):
self.textCtrl2.SetValue('64')
event.Skip()
class BoaApp1(wx.App):
def OnInit(self):
self.main = create(None)
self.main.Show()
self.SetTopWindow(self.main)
return True
class TRun(threading.Thread):
def __init__(self, caller):
threading.Thread.__init__(self)
self.caller = caller
self.flag = True
def run(self):
global arg,arg2,fd,fn
import subprocess
p = subprocess.Popen(args=arg, stdout=subprocess.PIPE, shell=True)
p2 = subprocess.Popen(args=arg2, stdin=p.stdout, stderr = subprocess.PIPE, shell=True)
r1 = re.compile('Processed\s(\d+)\ssecond')
all = fd[fn]
#print all
ans = ''
while p2.poll()==None:
ans+=p2.stderr.read(100)
#print ans
#wx.MessageBox(ans)
k = r1.findall(ans)
if len(k)>0:
#print int(float(k[-1])/all)
wx.CallAfter(self.caller.updateProgress, int(float(k[-1])*100/all))
time.sleep(0.01)
wx.CallAfter(self.caller.destroyProgress)
class MyFileDropTarget(wx.FileDropTarget):
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.window = window
def OnDropFiles(self, x, y, filenames):
global f,s,sf
#print "\n%d file(s) dropped at (%d,%d):\n" % (len(filenames), x, y)
for file in filenames:
#file = file.decode(sys.getfilesystemencoding())
#print file,sys.getfilesystemencoding()
arg='ffmpeg -i \"'+file.encode(sys.getfilesystemencoding())+'\"'
#print arg
p = subprocess.Popen(args=arg,stderr=subprocess.PIPE, shell=True)
a = p.communicate()[1]
pd = re.compile("Duration:\s(\d\d)\:(\d\d)\:(\d\d)\.(\d\d)\,")
b = a.split('Stream')
d = pd.findall(b[0])
fd.append(int(d[0][0])*60*60+int(d[0][1])*60+int(d[0][2]))
f.append(file)
for c in b[1:]:
if c.find(': Audio:')>=0:
d = c.split('\n')
while len(d) <= 2:
d.append(' ')
s.append(file+'\n'+d[0]+'\n'+d[2])
sf.append(len(f)-1)
k=[]
for m in s:
n = m.split('\n')
for o in n:
k.append(o)
self.window.Set(k)
return
def main():
application = BoaApp1(0)
application.MainLoop()
if __name__ == '__main__':
main()