Masaatoshi Ito の備忘録

主にザウルス(SL-C3100)に関する備忘録を書いています。更新停滞中&書く内容迷走中…。

PythonでMPlayerの疑似?フロントエンド作成

2009年06月14日 12時05分31秒 | Zaurus/Python
ZPlayerやQuasarでレジューム再生の方法が分からないので(というかほとんど使用していないため知らないだけかも)、PythonとかQtとかの勉強もかねてMPlayerの疑似フロントエンドを作成してみました。フロントエンドのくせに操作はキー操作やイヤホンに付けるリモコンで操作します。GUIはありません。とりあえず少し長いですが、ソースを貼ってみます。 うまくインデントが効いていますでしょうか?音量調節に zvol とか使用していますが、ご愛敬ということで。プレイリストは独自形式で、とりあえず以下のようにすれば大丈夫だと思います。
$ ls [ファイルのフルパス:例えば /mnt/card/Documents/Music_Files/*.mp3] >?/home/zaurus/Settings/play.conf

Python自体のインストールは以下のサイトを参考にしました。

Festina lente: ZaurusにPythonインストール
http://noel-festinalente.cocolog-nifty.com/blog/2006/06/zauruspython_a346_1.html

2010/03/18:追記
mplayer-bvdd-iwmmxt_1.2.0-1 でないと動作しないみたいです。
mplayer-bvdd-iwmmxt_1.1.5-1 だと動作しないのを確認しました。
本来は、-slaveオプションを指定して処理するのが正しそうです。
1.2.0-1用ですが、実際は以下のソースからある程度修正していますので、その内ブログに書くかもしれません。

#!/home/QtPalmtop/bin/python
# vim: fileencoding=utf-8
import sys
import os
import select
import popen2
import codecs
import re
from qt import *
from qtpe import *

class PlayList:
	def __init__(self):
		self.__listfile = '/home/zaurus/Settings/play.conf'
		self.__files = []
		self.__times = []
		self.__lasts = []
	def read(self):
		for line in codecs.getreader('utf-8')(open(self.__listfile,'r')):
			items = line[:-1].split('t')
			if items:
				if len(items) >= 3:
					self.__files.append(items[0])
					self.__times.append(items[1])
					self.__lasts.append(items[2])
				elif len(items) >= 1:
					self.__files.append(items[0])
					self.__times.append('00:00:00.0')
					self.__lasts.append('24:00:00.0')
	def write(self):
		out = codecs.getwriter('utf-8')(open(self.__listfile,'w'))
		for i in xrange(0,len(self.__files),1):
			out.write(self.__files[i])
			out.write('t')
			out.write(self.__times[i])
			out.write('t')
			out.write(self.__lasts[i])
			out.write('n')
		out.close()
	def setcurrent(self,file,time,last):
		self.__files[0] = file
		self.__times[0] = time
		self.__lasts[0] = last
	def getcurrent(self):
		return(
			self.__files[0],
			self.__times[0],
			self.__lasts[0]
		)
	def next(self):
		self.__files.append(self.__files[0])
		self.__times.append(self.__times[0])
		self.__lasts.append(self.__lasts[0])
		del self.__files[0]
		del self.__times[0]
		del self.__lasts[0]

class MPlayer:
	def __init__(self,file,time,last):
		self.__file  = file
		self.__time  = time
		self.__last  = last
		self.__re_f  = re.compile('^Playing (.*). *$')
		self.__re_t  = re.compile('^A:.*((.*?)).*((.*?)).*% *$')
		self.__re_t1 = re.compile('^(d+):(d+):(d+).(d+)$')
		self.__re_t2 = re.compile(      '^(d+):(d+).(d+)$')
		self.__re_t3 = re.compile(            '^(d+).(d+)$')
		self.checktime()
	def __to100msec(self,time):
		hour = 0
		min  = 0
		sec  = 0
		csec = 0
		m = self.__re_t1.match(time)
		if m:
			hour = int(m.group(1))
			min  = int(m.group(2))
			sec  = int(m.group(3))
			csec = int(m.group(4))
		m = self.__re_t2.match(time)
		if m:
			min  = int(m.group(1))
			sec  = int(m.group(2))
			csec = int(m.group(3))
		m = self.__re_t3.match(time)
		if m:
			sec  = int(m.group(1))
			csec = int(m.group(2))
		return hour*36000+min*600+sec*10+csec
	def isplaying(self):
		return self.__pipe.poll()==-1
	def isplayend(self):
		if self.__to100msec(self.__time) >= self.__to100msec(self.__last):
			return True
		return False
	def checktime(self):
		if self.isplayend():
			self.__time = '00:00:00.0'
	def getfileinfo(self):
		return(self.__file,self.__time,self.__last)
	def play(self):
		cmd = []
		cmd.append(u'mplayer')
		cmd.append(u'-ss')
		cmd.append(self.__time)
		cmd.append(self.__file.encode('utf-8'))
		self.__pipe = popen2.Popen3(cmd)
	def __readline2(self,f):
		line = ''
		c = f.read(1)
		while c:
			if c != 'r' and c != 'n':
				break
			c = f.read(1)
		while c:
			if c == 'r' or c == 'n':
				break
			line = line + c
			c = f.read(1)
		return line
	def loop(self):
		r,w,e = select.select([self.__pipe.fromchild],[],[],0.001)
		while r:
			f = r[0]
			line = self.__readline2(f)
			if not line:
				return
			m = self.__re_f.match(line)
			if m:
				self.__file = unicode(m.group(1),'utf-8')
			m = self.__re_t.match(line)
			if m:
				self.__time = unicode(m.group(1),'utf-8')
				self.__last = unicode(m.group(2),'utf-8')
			r,w,e = select.select([self.__pipe.fromchild],[],[],0.001)
	def ctl_stop(self):
		self.__pipe.tochild.write('q')
		self.__pipe.tochild.flush()
	def ctl_pauseplay(self):
		self.__pipe.tochild.write(' ')
		self.__pipe.tochild.flush()
	def ctl_fwd10min(self):
		self.__pipe.tochild.write("x1b[5~")
		self.__pipe.tochild.flush()
	def ctl_bwd10min(self):
		self.__pipe.tochild.write("x1b[6~")
		self.__pipe.tochild.flush()
	def ctl_fwd1min(self):
		self.__pipe.tochild.write("x1b[A")
		self.__pipe.tochild.flush()
	def ctl_bwd1min(self):
		self.__pipe.tochild.write("x1b[B")
		self.__pipe.tochild.flush()
	def ctl_fwd10sec(self):
		self.__pipe.tochild.write("x1b[C")
		self.__pipe.tochild.flush()
	def ctl_bwd10sec(self):
		self.__pipe.tochild.write("x1b[D")
		self.__pipe.tochild.flush()

class MainWindow(QMainWindow):
	def __init__(self,*args):
		apply(QMainWindow.__init__,(self,)+args)
		self.setCaption('Play')
		self.__labelfile = QLabel(self)
		self.__labelfile.resize(640,20)
		self.__labelfile.move(0,0)
		self.__labelfile.setFont(QFont('lcfont',18,QFont.Normal))
		self.__labeltime = QLabel(self)
		self.__labeltime.resize(180,40)
		self.__labeltime.move(0,40)
		self.__labeltime.setFont(QFont('lcfont',36,QFont.Normal))
		self.__labellast = QLabel(self)
		self.__labellast.resize(180,40)
		self.__labellast.move(200,40)
		self.__labellast.setFont(QFont('lcfont',36,QFont.Normal))
		self.__timer = QTimer(self)
		self.__pl = PlayList()
		self.__pl.read()
		self.__playcurrent()
		self.connect(self.__timer,
			     SIGNAL('timeout()'),
			     self.timeout)
		self.__timer.start(200,False)
	def __playcurrent(self):
		file,time,last = self.__pl.getcurrent()
		self.__labelfile.setText(file)
		self.__labeltime.setText(time)
		self.__labellast.setText(last)
		self.__mp = MPlayer(file,time,last)
		self.__mp.play()
	def timeout(self):
		self.__mp.loop()
		file,time,last = self.__mp.getfileinfo()
		if self.__mp.isplaying():
			self.__labeltime.setText(time)
			self.__labellast.setText(last)
		elif self.__mp.isplayend():
			self.__pl.setcurrent(file,time,last)
			self.__pl.next()
			self.__pl.write()
			self.__playcurrent()
	def closeEvent(self,event):
		event.accept()
		self.__timer.stop()
		self.__mp.ctl_stop()
		self.__mp.loop()
		file,time,last = self.__mp.getfileinfo()
		self.__pl.setcurrent(file,time,last)
		if self.__mp.isplayend():
			self.__pl.next()
		self.__pl.write()
	def keyPressed(self,key):
		if   key == 0x201d or key == Qt.Key_Q:
			self.close()
		elif key == 0x201c or key == Qt.Key_Space:
			self.__mp.ctl_pauseplay()
		elif key == 0x201e or key == Qt.Key_Right:
			self.__mp.ctl_fwd10sec()
		elif key == 0x201f or key == Qt.Key_Left:
			self.__mp.ctl_bwd10sec()
		elif key == 0x2020 or key == Qt.Key_Up:
			os.system('/home/QtPalmtop/bin/zvol +10')
		elif key == 0x2021 or key == Qt.Key_Down:
			os.system('/home/QtPalmtop/bin/zvol -10')
		else:
			print key
			return False
		return True
	def keyPressEvent(self,event):
		ret = self.keyPressed(event.key())
		if ret:
			event.accept()
		else:
			event.ignore()

if __name__ == '__main__':
	a = QPEApplication(sys.argv)
	win = MainWindow()
	a.showMainWidget(win)
	a.exec_loop()

Pythonの組み方など、色々意見をいただければと思います。

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« zten改の修正バージョン | トップ | weatherの改造 »
最新の画像もっと見る

コメントを投稿

Zaurus/Python」カテゴリの最新記事