我的第二个在 Boa Constructor 下写的 wxPython 程序…
基本功能:
1, 拖入含音轨的媒体文件(任意格式), 列出音轨, 选中需要压制的音轨, 选择压缩选项, 然后单击”Go”即可开始压制.
***ChangeLog***
20100617 0.1a 发布
下载请移步: http://code.google.com/p/ffnraudio/downloads/list
以下是全部代码:
#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()
请问是否能生成一个exe以便在windows下使用?感谢
抱歉 这个不再维护了.
对于windows 和linux文件\和/的区别,python有自己的系统来管理,我忘了是哪一个,你不用硬写的。仔细google一下。
谢谢..不过一直没找到= =||||
刚刚找了一下,找到了,是
os.sep
谢谢 🙂
看你在shlug里的发言了,所以到这里来看看。BOA这个东西比较老了吧。开发人员也不是很活跃。我还是比较倾向用gtk or PyQt.
我现在在尝试eric4,但是在我的系统上刚安装完就有一堆错误…
eric4是个传说。别信这种不成熟的IDE。直接用qt design 画界面,然后用 vim/emacs/eclipse/gedit 之类的写逻辑。
我对这个逻辑很郁闷,pyuic4貌似不能转含中文的.ui文件…
还是想找类似VB6的开发方式,后来的都习惯不了
你才多大,就说习惯不了。习惯不了的只是自己的懒惰。
后来的各种方式都有尝试过. 用起来觉得没有VB6那样的方便, 仅此而已.
另外, 反对以年龄论事.
不熟neo的软件。是把音频提出成wav, 然后再压成MP3?
如果是,为什么不用lame 把wav 压成 mp3? lame是自由软件。
nero压出来的低码率AAC比低码率的MP3能更好的表现电影配音,这是压片者普遍认同的观点.
首先你的软件真的要有人用,最好先考虑清楚版权。lame之类的比较好的地方就是GPL的。你自己的软件如果是GPL的,你把lame放在一起用就可以了。现在你这个所谓跨平台,因为neo的打原因也只能在windows中用吧。
nero本身也是跨平台的,可以跨平台用.
AAC可以有很多自由软件压吧。handbrake, gstream应该也可以吧。这都是非常出名的自由软件。尤其gstream,现在几乎成了多媒体的底层标准。要多看前沿的东西啊。
是影视组用,他们要求用nero,所以我才用的nero;
另外这个想修改不难的
faac是重点测试过的和nero相比较的编码器, 压片组认为它在低码率时没有nero表现力好
你是有组织的人啊,那就当我没有说。不过也应该,跳开组织,有点自己的思考。
您说的几个都是用的faac,而faac是nero的前身.
现在我在看aacplusenc,这个是另一个开源解决方案:)
label 用 gettext 之类的localization 方案比较好。这样硬写进去不是很好。
我还是新手 😛
为什么要用那么多全局变量?
不怎么会用类,不会传参…
可以跨平台吗?需要装python解释器和安装wx吗?
可以跨平台,需要python 2.6 和 wxpython unicode 2.8 for python 2.6
沙发!一窍不通就像天书!