player.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!./bin/python3
  2. import time
  3. import threading
  4. import pygame # type: ignore
  5. from display import Display
  6. from typing import Dict
  7. from pymplb import MPlayer
  8. class Player(Display):
  9. '''
  10. Player object which interacts with mplayer.
  11. '''
  12. def __init__(self, config, pydsp):
  13. super().__init__({
  14. "dimx" : config.get("dimx"),
  15. "dimx" : config.get("dimy"),
  16. "playlist" : config.get("dimy"),
  17. "fontsize" : config.get("fontsize"),
  18. }, pydsp)
  19. self.playing = False # Flag if the player is playing
  20. self._playingItem = None
  21. self._playingPlaylist = None # Current playing order
  22. self._data = [] # Current playlist
  23. self._player = MPlayer() # Reference to mplayer control object
  24. threading.Thread(target=self._updateFromPlayer, daemon=True).start()
  25. def _updateFromPlayer(self):
  26. '''
  27. Thread to update the player display from the state of mplayer.
  28. '''
  29. font = pygame.font.Font('freesansbold.ttf', int(self._fontsize))
  30. while True:
  31. try:
  32. time.sleep(0.5)
  33. if self.playing:
  34. player_playing = self._player.p_path
  35. # Update playlist display if the current song has changed
  36. # and the item can be found in the current playlist
  37. if player_playing != self._playingItem.get("path"):
  38. for i, item in enumerate(self._data):
  39. if item.get("path") == player_playing:
  40. self._selection_pointer = i
  41. self._current_item = item
  42. self.update()
  43. # Start the playlist again if the player ran out of items
  44. if player_playing == "(null)":
  45. for item in self._playingPlaylist:
  46. self._player.loadfile(item["path"], 1)
  47. except Exception as e:
  48. print("Error update from player:", e)
  49. def setPlaylist(self, data: Dict):
  50. '''
  51. Set the playlist for this player.
  52. '''
  53. self._bgImg = None
  54. self._selection_pointer = 0
  55. self._data = data
  56. def getPlaylist(self) -> Dict:
  57. '''
  58. Return the playlist for this display.
  59. '''
  60. return self._data
  61. def togglePlay(self):
  62. '''
  63. Toggle playing the selected item.
  64. '''
  65. if not self._current_item:
  66. return
  67. if self._player.p_path == self._current_item["path"]:
  68. # Stop what is currently playing
  69. self.playing = False
  70. self._player.stop()
  71. else:
  72. ci = self._current_item["path"]
  73. self._playingPlaylist = []
  74. # Build up the playlist in mplayer in the correct order
  75. add = 0
  76. for item in self._data:
  77. if item == self._current_item:
  78. self.playing = True
  79. self._playingItem = item
  80. self._player.loadfile(item["path"])
  81. self._playingPlaylist.append(item)
  82. add = 1
  83. elif add == 1:
  84. self._player.loadfile(item["path"], 1)
  85. self._playingPlaylist.append(item)
  86. for item in self._data:
  87. if item != self._current_item:
  88. self._player.loadfile(item["path"], 1)
  89. self._playingPlaylist.append(item)
  90. else:
  91. break