Progress bar for music duration - how to?

Hi there,
I wonder if anyone can point me in the right direction and thought this might be useful to others too. I am loading different music tracks in different screens and each track has a different duration but I would like to display the progress of each track within a predefined area as a rect or line - for example with a maxWidth.x value of 500.
I searched for a way to translate music.currentTime as a percentage of the maxWidth.x by looking at an old processing sketch I thought I could adapt. After trying a few things but I just can’t seem to get the typical behaviour everyone sees in media players…I am probably blinded by the simplicity of it haha…
Any help greatly appreciated - J

@jasi Maybe this will give you an idea. Select a time and tap the screen.


function setup()
    parameter.integer("time",10,60,30)   
    h=0
    st=false
end

function draw()
    background(40,40,50)
    fill(255)
    text("select time then tap screen to start",WIDTH/2,HEIGHT-100)
    noFill()
    stroke(255)
    strokeWidth(2)
    rect(100,100,100,600)   
    fill(255)
    rect(100,100,100,h)
    d=600/time
    t1=os.date("*t")
    sec=t1.sec
    if t2~=sec and st then
        t2=sec
        h=h+d  
        if h>=600 then
            st=false  
        end
    end
end

function touched(t)
    if t.state==BEGAN then
        t1=os.date("*t")
        t2=t1.sec
        st=true
    end   
end

I think this is what you are looking for:

function setup()
    music("Game Music One:Happy Song")
    
    size = vec2(500, 100)
    
    x, y = WIDTH / 2, HEIGHT / 2
end

function draw()
    background(0)
    
    strokeWidth(5)
    stroke(255) fill(0,0)
    
    rect(x - size.x / 2, y - size.y / 2, size.x, size.y)
    
    fill(255)
    
    local p = music.currentTime / music.duration
    rect(x - size.x / 2, y - size.y / 2 + strokeWidth()/2, size.x * p, size.y - strokeWidth())
end

Here’s a class version that will allow you to have the bar go horizontal or vertical. If the width is greater than the height, then it goes horizontal. If the height is greater that the width, then it goes vertical. I have both bars showing, but you can only have one music theme playing at one time. You can also change the background and foreground colors of the bar.


function setup()
    -- x,y,w,h,bg,fg,music
    m1=musicBar(100,200,40,400,color(0,188,255),
            color(255,0,0),"A Hero's Quest:Battle")
    m2=musicBar(50,100,400,40,color(27, 255, 0, 255),
            color(246, 0, 255, 255),"A Hero's Quest:Battle")
end

function draw()
    background(40, 40, 50)
    m1:draw()
    m2:draw()
end

musicBar=class()

function musicBar:init(x,y,w,h,bg,fg,m)
    self.x=x    -- x position
    self.y=y    -- y position
    self.w=w    -- width
    self.h=h    -- height 
    self.bg=bg  -- background color
    self.fg=fg  -- foreground color
    self.m=music(m) -- music
    self.dur=music.duration     -- duration
    self.time=0
end

function musicBar:draw()
    fill(self.bg)
    stroke(255)
    strokeWidth(2)
    rect(self.x,self.y,self.w,self.h)
    fill(self.fg)
    self.time=music.currentTime/self.dur
    if self.w>self.h then
        rect(self.x,self.y,self.w*self.time,self.h)
    else
        rect(self.x,self.y,self.w,self.h*self.time)
    end
end

Thanks for your help folks! The different examples are really useful to me but once I saw one line of code from @JakAttak I understood what I missed! Here is the working test I adapted - I also coded a currentTouch.x & .y for panning and volume but took them out as I need to be able to refine it - kinda fun though! Now I am a bit stuck converting decimal seconds to minutes and seconds to be able to display time but I will figure it out… We all start somewhere eh?

function setup()
    music("A Hero's Quest:Hero's Loss",true)
    music.currentTime = music.duration -10
    mx = 50
    my = 50   
end

function draw()
    background(51, 55, 82, 255)
    fill(10, 195, 219, 113)
    
    local m = music.currentTime / music.duration
    dut = math.floor(music.currentTime)
    dur = math.floor(music.duration)
    
    fontSize(18)
    text(dur,WIDTH/2-mx*3,HEIGHT/2)
    text(dut,WIDTH/2+mx*3,HEIGHT/2)
    
    ellipse(WIDTH/2,HEIGHT/2,mx*5)
    ellipse(WIDTH/2,HEIGHT/2,mx*m*5)
    
    rect(WIDTH/2-mx/2*5,my*3,mx*5,my)
    rect(WIDTH/2-mx/2*5,my*3,mx*5*m,my)
end

@jasl, I adapted your code to show the duration and current time in the minutes:seconds format.

function setup()
    music("Game Music One:Happy Song",true)
    music.currentTime = music.duration -10
    mx = 50
    my = 50   
end

function draw()
    background(51, 55, 82, 255)
    fill(10, 195, 219, 113)

    local m = music.currentTime / music.duration
    local dut = math.floor(music.currentTime / 60) .. ":" .. string.format("%02d", math.floor(music.currentTime % 60))
    local dur = math.floor(music.duration / 60) .. ":" .. string.format("%02d", math.floor(music.duration % 60))

    fontSize(18)
    text(dur,WIDTH/2-mx*3,HEIGHT/2)
    text(dut,WIDTH/2+mx*3,HEIGHT/2)

    ellipse(WIDTH/2,HEIGHT/2,mx*5)
    ellipse(WIDTH/2,HEIGHT/2,mx*m*5)

    rect(WIDTH/2-mx/2*5,my*3,mx*5,my)
    rect(WIDTH/2-mx/2*5,my*3,mx*5*m,my)
end

EDIT: I found a much better way to do the formatting, so I updated the code accordingly

@JakAttak, thanks so much! I didn’t know how to format the time as you have because I just don’t know the code well enough (I’ve not needed to use string.format before). Could you maybe explain what the … do beginning here? >

..":".. string.format("%02d", math.floor(music.currentTime % 60))

‘…’ is for string concatenation.

@Jmv38 - thanks yes…! Been playing around with it so all very clear now.

@jasl, glad you figured it out. It’s a very useful feature.