Shuvit game master repo. http://shuvit.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MusicPlayer.py 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import bge
  2. import os
  3. import aud
  4. import random
  5. import glob
  6. from DList import DoubleList
  7. from collections import OrderedDict
  8. from tinytag import TinyTag
  9. """ This is the Music Player as a component """
  10. class MusicPlayer(bge.types.KX_PythonComponent):
  11. args = OrderedDict([])
  12. def start(self, args):
  13. # dictionary
  14. self.dictionary = bge.logic.globalDict
  15. # get mp3 files from the disk and create a list
  16. self.directory = bge.logic.expandPath('//Music')
  17. file_name = self.directory + '\\*.mp3'
  18. file_list = glob.glob(file_name)
  19. # use the mp3 list to make a playlist of nodes
  20. self.playlist = DoubleList()
  21. for name in file_list:
  22. self.playlist.append(name)
  23. # previously played list of nodes
  24. self.alreadyPlayed = DoubleList()
  25. # get a random song from the playlist,
  26. # remove it from the playlist
  27. # add it to the alreadyPlayed list
  28. # NOTICE: currentNode is a reference to a NODE in a list, if you want to play the song inside the node, use .data
  29. self.currentNode = self.playlist.get(random.randint(0, self.playlist.getLength()))
  30. self.nowPlaying = self.currentNode.getData()
  31. self.playlist.remove(self.currentNode)
  32. self.alreadyPlayed.append(self.nowPlaying)
  33. print("Now Playing: " + self.nowPlaying)
  34. self.setTag()
  35. self.isPlaying = False
  36. # create audio devices
  37. self.device = aud.device()
  38. self.factory = aud.Factory(self.nowPlaying)
  39. self.handle = None
  40. """ Update is called once every frame, and this is where
  41. any input handling should go
  42. Controller Buttons:
  43. Y-Button - Play/Pause
  44. LB - Previous Track
  45. RB - Next Track
  46. TODO: Keyboard Buttons if these aren't alright
  47. P - Play/Pause
  48. Pad Plus - Next Track
  49. Pad Minus- Prev Track
  50. """
  51. def update(self):
  52. keyboard = bge.logic.keyboard.events
  53. up_dict = bge.logic.globalDict
  54. #print(dictionary)
  55. pKey = keyboard[bge.events.PKEY]
  56. pPlus = keyboard[bge.events.PADPLUSKEY]
  57. pMinus = keyboard[bge.events.PADMINUS]
  58. lb = up_dict['lBump']
  59. last_lb = up_dict['last_lBump']
  60. rb = up_dict['rBump']
  61. last_rb = up_dict['last_rBump']
  62. y = up_dict['yBut']
  63. last_y = up_dict['last_yBut']
  64. JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
  65. #Run player on startup
  66. if up_dict['music_start'] == True:
  67. if self.isPlaying:
  68. self.stopMusic()
  69. else:
  70. self.playMusic()
  71. up_dict['music_start'] = False
  72. # Music controls only during pause/replay
  73. if (up_dict['npause'] == True or up_dict['playback'] == True) or up_dict['music_start'] == True:
  74. #stop/play
  75. if (y == False and last_y == True) or pKey == JUST_ACTIVATED:
  76. if self.isPlaying:
  77. self.stopMusic()
  78. up_dict['music_player'] = 0
  79. else:
  80. self.playMusic()
  81. up_dict['music_player'] = 1
  82. # Prev/Next
  83. if self.isPlaying and self.handle.status:
  84. if pMinus == JUST_ACTIVATED or (lb == False and last_lb == True):
  85. self.prevSong()
  86. if pPlus == JUST_ACTIVATED or (rb == False and last_rb == True):
  87. self.nextSong()
  88. # if song ends, play next song
  89. if self.isPlaying and not self.handle.status:
  90. self.nextSong()
  91. """ get info about song using TinyTag, then print to console """
  92. def setTag(self):
  93. self.currTrackPath = os.path.join(self.directory, self.nowPlaying)
  94. tag = TinyTag.get(self.currTrackPath)
  95. self.currArtist = tag.artist
  96. self.currTrackTitle = tag.title
  97. self.dictionary['mu_artist'] = self.currArtist
  98. self.dictionary['mu_title'] = self.currTrackTitle
  99. print('Artist: %s' % self.currArtist,
  100. ' Track: %s' % self.currTrackTitle)
  101. def playMusic(self):
  102. print('Play Music')
  103. self.setTag()
  104. self.handle = self.device.play(self.factory)
  105. self.isPlaying = True
  106. def stopMusic(self):
  107. print('Stop Music')
  108. self.handle.stop()
  109. self.isPlaying = False
  110. def nextSong(self):
  111. print('Next Song')
  112. # stop the current song
  113. self.handle.stop()
  114. # get a song from the playlist
  115. self.currentNode = self.playlist.get(random.randint(0, self.playlist.getLength()))
  116. self.nowPlaying = self.currentNode.getData()
  117. self.playlist.remove(self.currentNode)
  118. # add the song to the already played list
  119. self.alreadyPlayed.append(self.nowPlaying)
  120. # start the song
  121. self.factory = aud.Factory(self.nowPlaying)
  122. self.handle = self.device.play(self.factory)
  123. self.setTag()
  124. # If playlist is empty, re-fill it
  125. if self.playlist.getLength() == 0:
  126. file_name = self.directory + '\\*.mp3'
  127. file_list = glob.glob(file_name)
  128. for name in file_list:
  129. self.playlist.append(name)
  130. """ Note on first call of this method, the current node will be equal to the tail of the already played list,
  131. however, it will be a node from a different list. We need to set current node equal to the tail node
  132. of the already played list so that we can iterate through that list, instead of the other list """
  133. def prevSong(self):
  134. print('Prev Song')
  135. # stop the current song
  136. self.handle.stop()
  137. if self.currentNode.getData() == self.alreadyPlayed.getTail().getData():
  138. self.currentNode = self.alreadyPlayed.getTail()
  139. self.currentNode = self.currentNode.getPrev()
  140. self.nowPlaying = self.currentNode.getData()
  141. # start the song
  142. self.factory = aud.Factory(self.nowPlaying)
  143. self.handle = self.device.play(self.factory)
  144. self.setTag()