PyPodcastPlayer
Podcastを読み込み、再生するPythonスクリプト。
ファイル再生にpygame使用。
ソースファイル
- -
PyPodcastPlayer.py
import os import sys import string import urllib2 import xml.dom.minidom import pygame.mixer class PodcastPlayer : podcast_data = "" now_playing = "" def __init__(self, podcast_data) : self.podcast_data = podcast_data self.managePlayer() def managePlayer(self) : self.setTrack() while(True) : self.displayPlayer() self.selectFile() def setTrack(self) : for i, v in enumerate(self.podcast_data) : for j, data in enumerate(v) : self.podcast_data[i][j]["track"] = str(i + 1) + "-" + str(j + 1) def displayPlayer(self) : print "q : Quit" print "0 : All Play" for i, v in enumerate(self.podcast_data) : for j, data in enumerate(v) : print '%-5s: [%s]\n %s\t%s\n %s' %\ (data["track"], data["title"], \ data["pubDate"], data["category"], \ data["link"]) def selectFile(self) : track = raw_input("Select track number(N-N) & Press Enter key: ") if (track == "q") : sys.exit() elif (track == "0") : for i, v in enumerate(self.podcast_data) : for j, data in enumerate(v) : self.now_playing = self.podcast_data[i][j] self.playFile() else : try : num =string.split(track, "-") r = int(num[0]) - 1 s = int(num[1]) - 1 self.now_playing = self.podcast_data[r][s] self.playFile() except : print "Unexpected error:", sys.exc_info()[0] def playFile(self) : pygame.mixer.init() pygame.mixer.music.load(self.now_playing["path"]) print "Now playing... track["+ self.now_playing["track"] + "]" pygame.mixer.music.play() self.controlPlayer() def controlPlayer(self) : while(True) : key = raw_input("Press key & Enter key(z:stop, x: pause): ") if(key == "z") : pygame.mixer.music.stop() break elif(key == "x") : pygame.mixer.music.pause() key = raw_input("Press key & Enter key(z:stop, c: play): ") if(key == "z") : pygame.mixer.music.stop() break elif(key == "c") : pygame.mixer.music.unpause() else : pygame.mixer.music.stop() break else : pygame.mixer.music.stop() break class PodcastManager : def getFile(self, data) : urlpath = string.replace(data["enclosure"], "http://", "") urlsp = string.split(urlpath, "/") file_name = urlsp[len(urlsp) - 1] del urlsp[len(urlsp) - 1] dir_name ="archive"+ os.sep + string.join(urlsp, os.sep) if not os.path.exists(dir_name) : os.makedirs(dir_name) file_path = dir_name + os.sep + file_name if not os.path.exists(file_path) : file = open(file_path, "wb") file.write(urllib2.urlopen(data["enclosure"]).read()) file.close() data["path"] = file_path return data def getXmldata(self, xml_data) : dom = xml.dom.minidom.parseString(xml_data) dom_data = dom.getElementsByTagName("item") data_list = [] i = 0 while i < dom_data.length : data_map = {} item = dom_data.item(i) enclosure_elm = item.getElementsByTagName("enclosure").item(0) if enclosure_elm != None : enclosure = enclosure_elm.getAttribute("url") data_map["enclosure"] = enclosure title_elm = item.getElementsByTagName("title").item(0) title = title_elm.firstChild.data data_map["title"] = title try : link_elm = item.getElementsByTagName("link").item(0) link = link_elm.firstChild.data data_map["link"] = link except: data_map["link"] = "no link" try : category_elm = item.getElementsByTagName("category").item(0) category = category_elm.firstChild.data data_map["category"] = category except : data_map["category"] = "no category" try : pubDate_elm = item.getElementsByTagName("pubDate").item(0) pubDate = pubDate_elm.firstChild.data data_map["pubDate"] = pubDate except : data_map["pubDate"] = "no date" data_list.append(data_map) i = i + 1 return data_list def getPodcastdata(self, list) : pdata = [] for i, v in enumerate(list) : if(len(v) != 0) : print "Now Loading " + v + " ...", xmldata = urllib2.urlopen(v).read() pdata.append(self.getXmldata(xmldata)) print "OK" for j, v in enumerate(pdata) : for k, w in enumerate(pdata[j]) : print "Now Downloading "+ w["enclosure"] + " ...", pdata[j][k] = self.getFile(w) print "OK" return pdata def readPodcastlist(self) : print "Now Loading podcast_list.txt ...", listf = open("podcast_list.txt") line = listf.readline() list = [] while line : list.append(line.strip()) line = listf.readline() listf.close() print "OK" return list if __name__=='__main__' : pm = PodcastManager() podcast_list = pm.readPodcastlist() podcast_data = pm.getPodcastdata(podcast_list) pp = PodcastPlayer(podcast_data)
podcast_list.txt(例)
http://podfeedsp.podcastjuice.jp/app/rss_convert.cgi?url=http%3A%2F%2Ftbs954%2Ecocolog%2Dnifty%2Ecom%2Fbujio%2F http://ajaxian.podbus.com/ http://feeds.feedburner.com/cinecast http://pod.abc1008.com/1008podcast.xml http://podcast.1242.com/fukuda/index.xml http://podcast.rubyonrails.org/podcast.xml http://www.awaretek.com/python/index.xml http://www.j-wave.co.jp/blog/estation/task/index.xml http://www.joqr.net/blog/shounen/index.xml http://www.oreillynet.com/pub/feed/37?format=rss2 http://www.perlcast.com/rss/current.xml
実行例
> python PyPodcastPlayer.py Now Loading podcast_list.txt ... OK Now Loading http://podfeedsp.podcastjuice.jp/app/rss_convert.cgi?url=http%3A%2F%2Ftbs954%2Ecocolog%2Dnifty%2Ecom%2Fbujio%2F ... OK 〜(略) Now Downloading http://tbs954.cocolog-nifty.com/bujio/files/b1010.mp3 ... OK Now Downloading http://tbs954.cocolog-nifty.com/bujio/files/b1007.mp3 ... OK 〜(略) q : Quit 0 : All Play 1-1 : [10/10ブジオ!] MON, 10 Oct 2005 20:58:27 +0900 月曜日 http://tbs954.cocolog-nifty.com/bujio/2005/10/1010_10b4.html 1-2 : [10/7無事?!終了です☆] Fri, 7 Oct 2005 21:36:52 +0900 金曜日 http://tbs954.cocolog-nifty.com/bujio/2005/10/post_34e8.html 〜(略) Select track number(N-N) & Press Enter key:
操作例
Select track number(N-N) & Press Enter key: 1-1 #(track num入力) Now playing... track[1-1] Press Key & Enter key(z:stop, x:pause): x #(一時停止) Press Key & Enter key(z:stop, c:play): c #(再生) Press Key & Enter key(z:stop, x:pause): z #(停止) q : Quit 0 : All Play 1-1 : [10/10ブジオ!] MON, 10 Oct 2005 20:58:27 +0900 月曜日 http://tbs954.cocolog-nifty.com/bujio/2005/10/1010_10b4.html 1-2 : [10/7無事?!終了です☆] Fri, 7 Oct 2005 21:36:52 +0900 金曜日 http://tbs954.cocolog-nifty.com/bujio/2005/10/post_34e8.html 〜(略) Select track number(N-N) & Press Enter key:q #(終了) >
ダウンロードしたファイルは「archive」フォルダにURLで分類して保存する。
1度ダウンロードしたファイルは再ダウンロードしない。レジューム機能無し。
全ての例外を処理していないので注意。
ファイルが多く、画面が小さいと、一覧表示の際にナンバの小さいトラックが見えなくなるのが問題。