Search code examples
pythontypeerrorarcade

TypeError: get_stream_position() takes 1 positional argument but 2 were given


I have googled a bunch on how to fix this problem, but I'm kind of a beginner and none of the articles were related to python arcade, so I couldn't figure it out.

I'm trying to play background music in my game and I tried the python arcade Background Music example, but upon trying to get the position the example throws an error at me, saying: TypeError: get_stream_position() takes 1 positional argument but 2 were given. Has some update messed up some code or something?

Heres the code I think is relevant to the problem:

def __init__(self, width, height, title):
    super().__init__(width, height, title)

    arcade.set_background_color(arcade.color.WHITE)

    self.music_list = []
    self.current_song_index = 0
    self.current_player = None
    self.music = None

def advance_song(self):

    self.current_song_index += 1
    if self.current_song_index >= len(self.music_list):
        self.current_song_index = 0
    print(f"Advancing song to {self.current_song_index}.")

def play_song(self):

    if self.music:
        self.music.stop()

    print(f"Playing {self.music_list[self.current_song_index]}")
    self.music = arcade.Sound(self.music_list[self.current_song_index], streaming=True)
    self.current_player = self.music.play(MUSIC_VOLUME)
    time.sleep(0.03)

def setup(self):

    self.music_list = [":resources:music/funkyrobot.mp3", ":resources:music/1918.mp3"]
    self.current_song_index = 0
    self.play_song()

def on_update(self, dt):

    position = self.music.get_stream_position(self.current_player)

    if position == 0.0:
        self.advance_song()
        self.play_song()

Here's the full error:

Playing :resources:music/funkyrobot.mp3
Traceback (most recent call last):
  File "c:/Users/[name]/Documents/Projects/background_music.py", line 77, in <module>
    main()
  File "c:/Users/[name]/Documents/Projects/background_music.py", line 74, in main
    arcade.run()
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\arcade\window_commands.py", line 236, in run
    pyglet.app.run()
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\pyglet\app\__init__.py", line 107, in run
    event_loop.run()
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\pyglet\app\base.py", line 167, in run
    timeout = self.idle()
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\pyglet\app\base.py", line 237, in idle
    redraw_all = self.clock.call_scheduled_functions(dt)
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\pyglet\clock.py", line 292, in call_scheduled_functions
    item.func(now - item.last_ts, *item.args, **item.kwargs)
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\arcade\application.py", line 213, in _dispatch_updates
    self.dispatch_event('on_update', delta_time)
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\pyglet\window\__init__.py", line 1333, in dispatch_event
    if EventDispatcher.dispatch_event(self, *args) != False:
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\pyglet\event.py", line 422, in dispatch_event
    self._raise_dispatch_exception(event_type, args, getattr(self, event_type), exception)
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\pyglet\event.py", line 476, in _raise_dispatch_exception
    raise exception
  File "C:\Users\[name]\AppData\Local\Programs\Python\Python38\lib\site-packages\pyglet\event.py", line 415, in dispatch_event
    if getattr(self, event_type)(*args):
  File "c:/Users/[name]/Documents/Projects/background_music.py", line 65, in on_update
    position = self.music.get_stream_position(self.current_player)
TypeError: get_stream_position() takes 1 positional argument but 2 were given

TL;DR: Example I wanted to use as reference doesn't function - TypeError: get_stream_position() takes 1 positional argument but 2 were given.


Solution

  • Seems, that you're using old Arcade version. You have two options:

    • update Arcade with pip install arcade --upgrade
    • slightly modify your code by removing all arguments from self.music.get_stream_position()

    Here is the working example for old Arcade version:

    import arcade
    import time
    
    SCREEN_WIDTH = 600
    SCREEN_HEIGHT = 300
    SCREEN_TITLE = "Starting Template Simple"
    MUSIC_VOLUME = 0.5
    
    
    class MyGame(arcade.Window):
        """ Main application class. """
    
        def __init__(self, width, height, title):
            super().__init__(width, height, title)
    
            arcade.set_background_color(arcade.color.WHITE)
    
            # Variables used to manage our music. See setup() for giving them
            # values.
            self.music_list = []
            self.current_song_index = 0
            self.current_player = None
            self.music = None
    
        def advance_song(self):
            """ Advance our pointer to the next song. This does NOT start the song. """
            self.current_song_index += 1
            if self.current_song_index >= len(self.music_list):
                self.current_song_index = 0
            print(f"Advancing song to {self.current_song_index}.")
    
        def play_song(self):
            """ Play the song. """
            # Stop what is currently playing.
            if self.music:
                self.music.stop()
    
            # Play the next song
            print(f"Playing {self.music_list[self.current_song_index]}")
            self.music = arcade.Sound(self.music_list[self.current_song_index], streaming=True)
            self.current_player = self.music.play(MUSIC_VOLUME)
            # This is a quick delay. If we don't do this, our elapsed time is 0.0
            # and on_update will think the music is over and advance us to the next
            # song before starting this one.
            time.sleep(0.03)
    
        def setup(self):
            """ Set up the game here. Call this function to restart the game. """
    
            # List of music
            self.music_list = [":resources:music/funkyrobot.mp3", ":resources:music/1918.mp3"]
            # Array index of what to play
            self.current_song_index = 0
            # Play the song
            self.play_song()
    
        def on_draw(self):
            """ Render the screen. """
    
            arcade.start_render()
    
            position = self.music.get_stream_position()
            length = self.music.get_length()
    
            size = 20
            margin = size * .5
    
            # Print time elapsed and total
            y = SCREEN_HEIGHT - (size + margin)
            text = f"{int(position) // 60}:{int(position) % 60:02} of {int(length) // 60}:{int(length) % 60:02}"
            arcade.draw_text(text, 0, y, arcade.csscolor.BLACK, size)
    
            # Print current song
            y -= size + margin
            text = f"Currently playing: {self.music_list[self.current_song_index]}"
            arcade.draw_text(text, 0, y, arcade.csscolor.BLACK, size)
    
        def on_update(self, dt):
    
            position = self.music.get_stream_position()
    
            # The position pointer is reset to 0 right after we finish the song.
            # This makes it very difficult to figure out if we just started playing
            # or if we are doing playing.
            if position == 0.0:
                self.advance_song()
                self.play_song()
    
    
    def main():
        """ Main method """
        window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
        window.setup()
        arcade.run()
    
    
    if __name__ == "__main__":
        main()