Pip is now working with CI
[enigma2.git] / lib / python / Screens / MediaPlayer.py
1 from enigma import eTimer, iPlayableService, eServiceCenter, iServiceInformation, eSize
2 from Screens.Screen import Screen
3 from Screens.MessageBox import MessageBox
4 from Components.ActionMap import NumberActionMap
5 from Components.Label import Label
6 from Components.Input import Input
7 from Components.GUIComponent import *
8 from Components.Pixmap import Pixmap
9 from Components.Label import Label
10 from Components.FileList import FileEntryComponent, FileList
11 from Components.MediaPlayer import PlayList, PlaylistEntryComponent
12 from Plugins.Plugin import PluginDescriptor
13 from Tools.Directories import resolveFilename, SCOPE_MEDIA, SCOPE_CONFIG
14 from Components.ServicePosition import ServicePositionGauge
15 from Screens.ChoiceBox import ChoiceBox
16 from Components.ServiceEventTracker import ServiceEventTracker
17 from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS
18 from Screens.InfoBarGenerics import InfoBarSeek
19 from ServiceReference import ServiceReference
20 from Screens.ChoiceBox import ChoiceBox
21
22 import os
23
24 class MediaPlayer(Screen, InfoBarSeek):
25         def __init__(self, session, args = None):
26                 Screen.__init__(self, session)
27                 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
28                 self.session.nav.stopService()
29
30                 self.playlistparsers = {}
31                 self.addPlaylistParser(PlaylistIOM3U, "m3u")
32                 self.addPlaylistParser(PlaylistIOPLS, "pls")
33                 self.addPlaylistParser(PlaylistIOInternal, "e2pls")
34
35                 self.filelist = FileList(resolveFilename(SCOPE_MEDIA), matchingPattern = "^.*\.(mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob)", useServiceRef = True)
36                 self["filelist"] = self.filelist
37
38                 self.playlist = PlayList()
39                 self["playlist"] = self.playlist
40                 
41                 self["PositionGauge"] = ServicePositionGauge(self.session.nav)
42                 
43                 self["currenttext"] = Label("")
44                 
45                 self["artisttext"] = Label(_("Artist:"))
46                 self["artist"] = Label("")
47                 self["titletext"] = Label(_("Title:"))
48                 self["title"] = Label("")
49                 self["albumtext"] = Label(_("Album:"))
50                 self["album"] = Label("")
51                 self["yeartext"] = Label(_("Year:"))
52                 self["year"] = Label("")
53                 self["genretext"] = Label(_("Genre:"))
54                 self["genre"] = Label("")
55                 
56                 #self["text"] = Input("1234", maxSize=True, type=Input.NUMBER)
57
58                 class MoviePlayerActionMap(NumberActionMap):
59                         def __init__(self, player, contexts = [ ], actions = { }, prio=0):
60                                 NumberActionMap.__init__(self, contexts, actions, prio)
61                                 self.player = player
62
63                         def action(self, contexts, action):
64                                 self.player.show()
65                                 return NumberActionMap.action(self, contexts, action)
66
67                 self["actions"] = MoviePlayerActionMap(self, ["OkCancelActions", "DirectionActions", "NumberActions", "MediaPlayerSeekActions"],
68                 {
69                         "ok": self.ok,
70                         "cancel": self.exit,
71                         
72                         "right": self.rightDown,
73                         "rightRepeated": self.doNothing,
74                         "rightUp": self.rightUp,
75                         "left": self.leftDown,
76                         "leftRepeated": self.doNothing,
77                         "leftUp": self.leftUp,
78                         
79                         "up": self.up,
80                         "upRepeated": self.up,
81                         "down": self.down,
82                         "downRepeated": self.down,
83                         
84                         "play": self.playEntry,
85                         "pause": self.pauseEntry,
86                         "stop": self.stopEntry,
87                         
88                         "previous": self.previousEntry,
89                         "next": self.nextEntry,
90                         
91                         "menu": self.showMenu,
92                         
93             "1": self.keyNumberGlobal,
94             "2": self.keyNumberGlobal,
95             "3": self.keyNumberGlobal,
96             "4": self.keyNumberGlobal,
97             "5": self.keyNumberGlobal,
98             "6": self.keyNumberGlobal,
99             "7": self.keyNumberGlobal,
100             "8": self.keyNumberGlobal,
101             "9": self.keyNumberGlobal,
102             "0": self.keyNumberGlobal
103         }, -2)
104
105                 InfoBarSeek.__init__(self)
106
107                 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
108                         {
109                                 #iPlayableService.evStart: self.__serviceStarted,
110                                 #iPlayableService.evSeekableStatusChanged: InfoBarSeek.__seekableStatusChanged,
111
112                                 iPlayableService.evEOF: self.__evEOF,
113 #                               iPlayableService.evSOF: self.__evSOF,
114                         })
115
116                 self.onClose.append(self.delMPTimer)
117                 self.onClose.append(self.__onClose)
118                 
119                 self.righttimer = False
120                 self.rightKeyTimer = eTimer()
121                 self.rightKeyTimer.timeout.get().append(self.rightTimerFire)
122
123                 self.lefttimer = False
124                 self.leftKeyTimer = eTimer()
125                 self.leftKeyTimer.timeout.get().append(self.leftTimerFire)
126                 
127                 self.infoTimer = eTimer()
128                 self.infoTimer.timeout.get().append(self.infoTimerFire)
129                 self.infoTimer.start(500)
130                 
131                 self.currList = "filelist"
132                 
133                 self.playlistIOInternal = PlaylistIOInternal()
134                 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
135                 if list:
136                         for x in list:
137                                 self.playlist.addFile(x.ref)
138                         self.playlist.updateList()              
139                 
140         def doNothing(self):
141                 pass
142         
143         def exit(self):
144                 self.playlistIOInternal.clear()
145                 for x in self.playlist.list:
146                         self.playlistIOInternal.addService(ServiceReference(x[0]))
147                 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
148                 self.close()
149         
150         def checkSkipShowHideLock(self):
151                 self.updatedSeekState()
152         
153         def __evEOF(self):
154                 self.nextEntry()
155         
156         def __onClose(self):
157                 self.session.nav.playService(self.oldService)
158         
159         def delMPTimer(self):
160                 del self.rightKeyTimer
161                 del self.leftKeyTimer
162                 del self.infoTimer
163                 
164         def infoTimerFire(self):
165                 currPlay = self.session.nav.getCurrentService()
166                 if currPlay is not None:
167                         self.updateMusicInformation( artist = currPlay.info().getInfoString(iServiceInformation.sArtist),
168                                                                                  title = currPlay.info().getInfoString(iServiceInformation.sTitle),
169                                                                                  album = currPlay.info().getInfoString(iServiceInformation.sAlbum),
170                                                                                  genre = currPlay.info().getInfoString(iServiceInformation.sGenre),
171                                                                                  clear = True)
172                 else:
173                         self.updateMusicInformation()
174         
175         def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
176                 self.updateSingleMusicInformation("artist", artist, clear)
177                 self.updateSingleMusicInformation("title", title, clear)
178                 self.updateSingleMusicInformation("album", album, clear)
179                 self.updateSingleMusicInformation("year", year, clear)
180                 self.updateSingleMusicInformation("genre", genre, clear)
181
182         def updateSingleMusicInformation(self, name, info, clear):
183                 if info != "" or clear:
184                         if self[name].getText() != info:
185                                 self[name].setText(info)
186
187         def fwdTimerFire(self):
188                 self.fwdKeyTimer.stop()
189                 self.fwdtimer = False
190                 self.nextEntry()
191         
192         def rwdTimerFire(self):
193                 self.rwdKeyTimer.stop()
194                 self.rwdtimer = False
195                 self.previousEntry()
196         
197         def leftDown(self):
198                 self.lefttimer = True
199                 self.leftKeyTimer.start(1000)
200
201         def rightDown(self):
202                 self.righttimer = True
203                 self.rightKeyTimer.start(1000)
204                 
205         def leftUp(self):
206                 if self.lefttimer:
207                         self.leftKeyTimer.stop()
208                         self.lefttimer = False
209                         self[self.currList].pageUp()
210     
211         def rightUp(self):
212                 if self.righttimer:
213                         self.rightKeyTimer.stop()
214                         self.righttimer = False
215                         self[self.currList].pageDown()
216                         
217         def leftTimerFire(self):
218                 self.leftKeyTimer.stop()
219                 self.lefttimer = False
220                 self.switchToFileList()
221         
222         def rightTimerFire(self):
223                 self.rightKeyTimer.stop()
224                 self.righttimer = False
225                 self.switchToPlayList()
226                                 
227         def switchToFileList(self):
228                 self.currList = "filelist"
229                 self.filelist.selectionEnabled(1)
230                 self.playlist.selectionEnabled(0)
231                 self.updateCurrentInfo()
232                 
233         def switchToPlayList(self):
234                 if len(self.playlist) != 0:
235                         self.currList = "playlist"
236                         self.filelist.selectionEnabled(0)
237                         self.playlist.selectionEnabled(1)
238                         self.updateCurrentInfo()
239                 
240         def up(self):
241                 self[self.currList].up()
242                 self.updateCurrentInfo()
243
244         def down(self):
245                 self[self.currList].down()
246                 self.updateCurrentInfo()
247
248         def updateCurrentInfo(self):
249                 text = ""
250                 if self.currList == "filelist":
251                         if not self.filelist.canDescent():
252                                 text = self.filelist.getServiceRef().getPath()
253                 if self.currList == "playlist":
254                         text = self.playlist.getSelection().getPath()
255                 
256                 self["currenttext"].setText(os.path.basename(text))
257     
258         def ok(self):
259                 if self.currList == "filelist":
260                         if self.filelist.canDescent():
261                                 self.filelist.descent()
262                                 self.updateCurrentInfo()
263                         else:
264                                 self.copyFile()
265                 if self.currList == "playlist":
266                         selection = self["playlist"].getSelection()
267                         self.changeEntry(self.playlist.getSelectionIndex())
268
269         def keyNumberGlobal(self, number):
270                 pass
271         
272         def showMenu(self):
273                 menu = []
274                 if self.currList == "filelist":
275                         menu.append((_("switch to playlist"), "playlist"))
276                         if self.filelist.canDescent():
277                                 menu.append((_("add directory to playlist"), "copydir"))
278                         else:
279                                 menu.append((_("add file to playlist"), "copy"))
280                 else:
281                         menu.append((_("switch to filelist"), "filelist"))
282                         menu.append((_("delete"), "delete"))
283                         menu.append((_("clear playlist"), "clear"))
284                 menu.append((_("hide player"), "hide"));
285                 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
286                 
287         def menuCallback(self, choice):
288                 if choice is None:
289                         return
290                 
291                 if choice[1] == "copydir":
292                         self.copyDirectory(self.filelist.getSelection()[0])
293                 elif choice[1] == "copy":
294                         self.copyFile()
295                 elif choice[1] == "playlist":
296                         self.switchToPlayList()
297                 elif choice[1] == "filelist":
298                         self.switchToFileList()
299                 elif choice[1] == "delete":
300                         if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
301                                 self.stopEntry()
302                         self.deleteEntry()
303                 elif choice[1] == "clear":
304                         self.stopEntry()
305                         self.playlist.clear()
306                         self.switchToFileList()
307                 elif choice[1] == "hide":
308                         self.hide()
309
310         def copyDirectory(self, directory):
311                 filelist = FileList(directory, useServiceRef = True, isTop = True)
312                 
313                 for x in filelist.getFileList():
314                         if x[0][1] == True: #isDir
315                                 self.copyDirectory(x[0][0])
316                         else:
317                                 self.playlist.addFile(x[0][0])
318                 self.playlist.updateList()
319         
320         ADDPLAYLIST = 0
321         REPLACEPLAYLIST = 1
322         
323         def copyFile(self):
324                 if self.filelist.getServiceRef().type == 4098: # playlist
325                         list = []
326                         list.append((_("Add files to playlist"), (self.ADDPLAYLIST, self.filelist.getServiceRef())))
327                         list.append((_("Replace current playlist"), (self.REPLACEPLAYLIST, self.filelist.getServiceRef())))
328                         self.session.openWithCallback(self.playlistCallback, ChoiceBox, title=_("You selected a playlist"), list = list)
329                 else:
330                         self.playlist.addFile(self.filelist.getServiceRef())
331                         self.playlist.updateList()
332                         if len(self.playlist) == 1:
333                                 self.changeEntry(0)
334
335         def addPlaylistParser(self, parser, extension):
336                 self.playlistparsers[extension] = parser
337
338         def playlistCallback(self, answer):
339                 if answer is not None:
340                         extension = answer[1][1].getPath()[answer[1][1].getPath().rfind('.') + 1:]
341                         print "extension:", extension
342                         if self.playlistparsers.has_key(extension):
343                                 playlist = self.playlistparsers[extension]()
344                                 if answer[1][0] == self.REPLACEPLAYLIST:
345                                         self.stopEntry()
346                                         self.playlist.clear()
347                                         self.switchToFileList()
348                                 if answer[1][0] == self.REPLACEPLAYLIST or answer[1][0] == self.ADDPLAYLIST:
349                                         list = playlist.open(answer[1][1].getPath())
350                                         for x in list:
351                                                 self.playlist.addFile(x.ref)
352                                 
353
354         def nextEntry(self):
355                 next = self.playlist.getCurrentIndex() + 1
356                 if next < len(self.playlist):
357                         self.changeEntry(next)
358         
359         def previousEntry(self):
360                 next = self.playlist.getCurrentIndex() - 1
361                 if next >= 0:
362                         self.changeEntry(next)
363                         
364         def deleteEntry(self):
365                 self.playlist.deleteFile(self.playlist.getSelectionIndex())
366                 self.playlist.updateList()
367                 if len(self.playlist) == 0:
368                         self.switchToFileList()
369                 
370         def changeEntry(self, index):
371                 self.playlist.setCurrentPlaying(index)
372                 self.playEntry()
373         
374         def playEntry(self):
375                 if len(self.playlist.getServiceRefList()):
376                         currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
377                         if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
378                                 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
379                                 info = eServiceCenter.getInstance().info(currref)
380                                 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
381                                 self["title"].setText(description)
382                         self.unPauseService()
383                                 
384         def updatedSeekState(self):
385                 if self.seekstate == self.SEEK_STATE_PAUSE:
386                         self.playlist.pauseFile()
387                 elif self.seekstate == self.SEEK_STATE_PLAY:
388                         self.playlist.playFile()
389                 elif self.seekstate in ( self.SEEK_STATE_FF_2X,
390                                                                  self.SEEK_STATE_FF_4X,
391                                                                  self.SEEK_STATE_FF_8X,
392                                                                  self.SEEK_STATE_FF_32X,
393                                                                  self.SEEK_STATE_FF_64X,
394                                                                  self.SEEK_STATE_FF_128X):
395                         self.playlist.forwardFile()
396                 elif self.seekstate in ( self.SEEK_STATE_BACK_16X,
397                                                                  self.SEEK_STATE_BACK_32X,
398                                                                  self.SEEK_STATE_BACK_64X,
399                                                                  self.SEEK_STATE_BACK_128X,):
400                         self.playlist.rewindFile()
401         
402         def pauseEntry(self):
403                 self.pauseService()
404                 
405         def stopEntry(self):
406                 self.playlist.stopFile()
407                 self.session.nav.playService(None)
408                 self.updateMusicInformation(clear=True)
409
410         def unPauseService(self):
411                 self.setSeekState(self.SEEK_STATE_PLAY)
412
413
414