So here is my code, the problem is that the play function in my Player class doesn't work properly if I have a print statement between self.song.play()
and self.song.seek(self.pos)
, then it works fine, else it doesn't work. Below I will show my console output because there is also a ffpyplayer warning by kivy and the time comparison of the actual time played and the current time of the song. You can ignore the s()
and t()
functions for the problem they are just for the console output to show which time the song actually should be at.
from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.core.audio import SoundLoader
import os
import random
from time import time
class Main(RelativeLayout):
def __init__(self, **kw):
super().__init__(**kw)
self.player = Player()
playbutton = Button(
text = "Play",
size_hint = (.1, .1),
pos_hint = {"center_x": 0.4, "center_y": 0.3},
on_press = self.player.play)
stopbutton = Button(
text = "Stop",
size_hint = (.1, .1),
pos_hint = {"center_x": 0.6, "center_y": 0.3},
on_press = self.player.stop)
self.add_widget(playbutton)
self.add_widget(stopbutton)
class MyApp(App):
def build(self):
return Main()
class Player:
def __init__(self):
self.path = "C:/Users/Marc/Music/Lieder/"
self.playlist = os.listdir(self.path)
#self.mix_playlist()
self.song = SoundLoader.load(self.path + self.playlist[0])
self.pos = 0
self.start_time = None
self.stop_time = 0
self.stopped_time = None
def mix_playlist(self):
mixedPlaylist = []
while len(self.playlist) > 0:
item = random.choice(self.playlist)
mixedPlaylist.append(item)
self.playlist.remove(item)
self.playlist = mixedPlaylist
def t(self):
if self.start_time is None:
self.start_time = time()
return int(time() - self.start_time - self.stop_time)
def s(self):
if self.stopped_time:
self.stop_time += time() - self.stopped_time
def play(self, _):
if self.song.state == "stop":
self.s()
self.song.play()
if self.pos > 0:
################# IF HERE IS A PRINT STATEMENT -> seek works, else not #######################
self.song.seek(self.pos)
print("pos:", self.pos, "song.get_pos:",self.song.get_pos(), "play time:",self.t())
def stop(self, _):
self.pos = self.song.get_pos()
self.song.stop()
self.stopped_time = time()
app = MyApp()
app.run()
My Console Output
My thought was that through the print statement enough time passes so self.song.play()
function counts for the self.song.seek(self.pos)
function.
Quick update, i solved the problem. The problem was that seek() function only works when the song is playing and somehow seek() doesnt work if play() was called in the same frame of the kivy event loop like in my code. So the solution is to schedule seek() for the next frame like this: Clock.schedule_once(seek, 0) Sources: https://kivy.org/doc/stable/api-kivy.clock.html https://kivy.org/doc/stable/api-kivy.core.audio.html
def play(self, _):
if self.song.state == "stop":
self.song.play()
if self.pos > 0:
Clock.schedule_once(self.unpause,0)
def unpause(self, _):
self.song.seek(self.pos)