Godot Version
4.2
Question
I am trying at add a Timer for the remaining time for the song playing. As of now I forced the label to see the argument as a string but produces a float that goes up from 0 to 0.00000etc .
Edited to better show my current spot in this.
I don’t know if this helps or just linking to it so I will do both
https://github.com/KindaWrks/Music-Player
extends Node2D
@onready var fd_open = $FD_OPEN
@onready var music_label = $MusicLabel
@onready var music_time_label = $MusicTimeLabel
@onready var music_total_time = $MusicTotalTimeLabel
@export var audio_bus_name := "Master" #Makes the var Master audio bus
@onready var _bus := AudioServer.get_bus_index(audio_bus_name) #Sets bus index to Master
# Called when the node enters the scene tree for the first time.
func _ready():
fd_o_filters()
fd_open.visible = true
music_label.visible = false
func fd_o_filters():
fd_open.current_dir = "/" #Set current dir as Root
fd_open.add_filter("*.mp3 ; Music") #Set filter for MP3 files
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
music_label.text = fd_open.current_file.get_basename() #Gets the current file and removes the .MP3
music_time_label.text = str(int($AudioStreamPlayer.get_playback_position())) #Make time count in int rather then flaot
func _on_fd_open_file_selected(path):
var snd_file = FileAccess.open(path, FileAccess.READ) #Open path and reaf from the file
var stream = AudioStreamMP3.new() #Create a bew MP3 Audio stream
stream.data = snd_file.get_buffer(snd_file.get_length()) # Load entire song into memory(not ideal)
snd_file.close() #Close file.
$AudioStreamPlayer.stream = stream #The loaded song in memeory
$AudioStreamPlayer.play()
music_label.visible = true
music_total_time.text = str(int($AudioStreamPlayer.stream.get_length()))
func _on_h_slider_value_changed(value: float):
AudioServer.set_bus_volume_db(_bus,linear_to_db(value)) #Control volume as a float
Not sure if I understand the problem. get_playback_position()
does return a float
, and yes, if you want to show that value on a Label
you have to explicitly cast it into a string first, as with all numeric values. If you want to limit the amount of digits after the dot, use a format string, e.g. for two digits do:
music_time_label.text = "%.2f" % [$AudioStreamPlayer.get_playback_position()]
Now, in order to get the remaining time of the track, you’d only have to get the overall length of the stream with get_length()
and then subtract the current position in the stream from it:
music_time_label.text = "%.2f" % [$AudioStreamPlayer.stream.get_length() - $AudioStreamPlayer.get_playback_position()]
And yes, if you’re only interested in full seconds, just cast it into a int
at the end.
1 Like
Hi thank you for the answers, I guess I didn’t fix the top post as well as I thought.
One of my questions was indeed time remaining, I also found out str, int for whole seconds.
I was trying to declare the time as 0:00 like a modern day player. I think I have a basic idea for the custom setup where minutes are like % 60/60 … At least that is what I got from it all.
1 Like
I see why I never got the timer to work as I was putting it raw in proceses. I don’t see how I overlooked it. I needed a if statement/function for audio then display the stringed integer.
Though now I am on to my next task how to make the audiostreamplayer work with an’ array and index. I have had luck with array/index when I feed it one song. Though if I add multiple to the array it crashes or index 0s.
Correct me if I’m wrong but I need a way to always make a new player and feed the current index?
I’m not sure, I fully comprehend what you’re trying to do. Maybe post the code for what you’re trying to do? 
Sorry, i was just happy to figure out what stopped my label earlier was just idiocy. I was also relaying I was on to my new enemy the error packedstringarray or index 0.
This is not on the github as this is the test/scratch code.
I try to make it play the next song in the array via the index, kinda like a song queue. I have tried a few ways such as file new or mp3 new.
I don’t know when I last messed with this scratch in the last few days. I thought I knew how I was handling the change thourgh increasing the index. The play button for “files” is not hooked up as I was testing single file as a autoplay.
extends Node2D
@onready var btnshow = $Buttonshow #to reopen fd_open
@onready var fd_open = $FD_OPEN
@onready var music_label = $MusicLabel
@onready var music_time_label = $MusicTimeLabel
@onready var musicarray : Array = [] #start array blank array
@onready var musicindex = 0 #intial index for track progression
@export var audio_bus_name := "Master" #Makes the var Master audio bus
@onready var _bus := AudioServer.get_bus_index(audio_bus_name) #Sets bus index to Master
# Called when the node enters the scene tree for the first time.
func _ready():
fd_o_filters()
fd_open.visible = true
music_label.visible = false
func fd_o_filters():
fd_open.current_dir = "/" #Set current dir as Root
fd_open.add_filter("*.mp3 ; Music") #Set filter for MP3 files
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
if $AudioStreamPlayer.playing:
music_label.text = str(musicarray).get_file().get_basename() #Gets the current index of array and removes the .MP3
music_time_label.text = str(int($AudioStreamPlayer.get_playback_position()))
print(musicarray[musicindex])
func _on_fd_open_file_selected(path):
var snd_file = FileAccess.open(path, FileAccess.READ) #Open path and reaf from the file
var stream = AudioStreamMP3.new() #Create a bew MP3 Audio stream
stream.data = snd_file.get_buffer(snd_file.get_length()) # Load entire song into memory(not ideal)
snd_file.close() #Close file.
$AudioStreamPlayer.stream = stream #The loaded song in memeory
$AudioStreamPlayer.play()
music_label.visible = true
musicarray.append(path)
musicindex += 1
if musicindex > musicarray.size() - 1:
musicindex = 0
func _on_h_slider_value_changed(value: float):
AudioServer.set_bus_volume_db(_bus,linear_to_db(value)) #Control volume as a float
func _on_buttonshow_pressed(): #reopen fd_open
fd_open.visible = true
func _on_fd_open_files_selected(paths): #when set to files without audiostream adds all to array
music_label.visible = true
musicarray.append(paths)
musicindex += 1
if musicindex > musicarray.size() - 1:
musicindex = 0
print(musicarray[musicindex])
func music_index(): #indexs the musicarray
if $AudioStreamPlayer.finished():
musicindex += 1
if musicindex > musicarray.size() - 1:
musicindex = 0
print(musicarray[musicindex])
-edit 3- Worked on the non-srcatch version and fixed it up to use the musicarray and music index again. I also incorparated the song_list and song choice when slecting/clicking. It seems like each time I ask a question now I seem to come up with a answer and look foolish.
extends Node2D
@onready var fd_open = $FD_OPENfiles
@onready var music_time_label = $MusicTimeLabel
@onready var music_total_time = $MusicTotalTimeLabel
@export var audio_bus_name := "Master" #Makes the var Master audio bus
@onready var _bus := AudioServer.get_bus_index(audio_bus_name) #Sets bus index to Master
var musicarray = [] # Initialize array only
var musicindex = 0
# Called when the node enters the scene tree for the first time.
func _ready():
fd_o_filters()
fd_open.visible = true
func fd_o_filters():
fd_open.current_dir = "/" #Set current dir as Root
fd_open.add_filter("*.mp3 ; Music") #Set filter for MP3 files
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
if $AudioStreamPlayer.playing: #Make time count down in int rather then float and show total time
music_time_label.text = str(int($AudioStreamPlayer.stream.get_length()) - int($AudioStreamPlayer.get_playback_position()))
music_total_time.text = str(int($AudioStreamPlayer.stream.get_length()))
print(musicarray)
# Check if the song ended and play the next song in the queue
if not $AudioStreamPlayer.playing and musicarray.size() > 0:
play_next_song()
func _on_fd_open_files_selected(paths):
for path in paths:
var snd_file = FileAccess.open(path, FileAccess.READ) # Open path and read from the file
var stream = AudioStreamMP3.new() # Create a new MP3 Audio stream
stream.data = snd_file.get_buffer(snd_file.get_length()) # Load entire song into memory(not ideal)
snd_file.close() # Close file.
$AudioStreamPlayer.stream = stream # The loaded song in memory
$AudioStreamPlayer.play()
# Add the selected song to the queue
musicarray.append(path)
#Add song list
var file_name_without_extension = path.get_file().get_basename()
$song_list.add_item(file_name_without_extension)
func play_next_song():
var next_song_path = musicarray[musicindex] # Get the next song from the queue
var snd_file = FileAccess.open(next_song_path, FileAccess.READ) #Open path and read from the file
var stream = AudioStreamMP3.new() #Create a new MP3 Audio stream
stream.data = snd_file.get_buffer(snd_file.get_length()) # Load entire song into memory(not ideal)
snd_file.close() #Close file.
$AudioStreamPlayer.stream = stream #The loaded song in memory
$AudioStreamPlayer.play()
func _on_buttonshow_pressed(): #Show Filedialog
fd_open.visible = true
func _on_h_slider_value_changed(value: float):
AudioServer.set_bus_volume_db(_bus,linear_to_db(value)) #Control volume as a float
# Called when an item in the song list is selected
func _on_song_list_item_selected(index):
if index < musicarray.size():
var selected_song_path = musicarray[index]
play_song(selected_song_path)
# Function to play a selected song
func play_song(song_path):
var snd_file = FileAccess.open(song_path, FileAccess.READ)
var stream = AudioStreamMP3.new()
stream.data = snd_file.get_buffer(snd_file.get_length())
snd_file.close()
$AudioStreamPlayer.stream = stream
$AudioStreamPlayer.play()