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