Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android Background music continues to play, after app is minimized #1828

Closed
powertomato opened this issue Aug 10, 2022 · 4 comments
Closed
Assignees
Labels
11.4 Android bug Something isn't working
Milestone

Comments

@powertomato
Copy link

powertomato commented Aug 10, 2022

I'm having issues that background music continues to play after the app is minimized.
During my investigation on how to fix or work around it I found the following code:

#ifdef LOVE_ANDROID

I debugged to confirm the code is actually executed (it is). But for some reason it doesn't actually pause the audio sources. The source type (static/stream) makes no difference.

I can replicate this behavior with two phones:

  • A Samsung Galaxy S20 (SM-G981B) with Android 12 (API 31)
  • A Huawei p30 pro with Android 10 (API 29)

As well as with a virtual Pixel 2 with Android 12 (API 31).

My current woraround was to implement the love.focus handler and pause the background music manually.

An other odd detail: if, in the same love.focus-handler, I check wether the source is playing with source:isPlaying() they will return false.

@slime73 slime73 added bug Something isn't working 11.4 labels Aug 10, 2022
@MikuAuahDark MikuAuahDark self-assigned this Aug 11, 2022
@MikuAuahDark
Copy link
Contributor

MikuAuahDark commented Aug 22, 2022

I tried to reproduce this with this code.

function love.load()
	rolling = love.audio.newSource("test.mp3", "stream")
	rolling:setLooping(true)
end

function love.draw()
	love.graphics.print(tostring(rolling:isPlaying()), 64, 64)
end

function love.mousereleased()
	if rolling:isPlaying() then
		rolling:pause()
	else
		rolling:play()
	end
end

Then run the app, tap anywhere to start the audio, then press the home button. I can't reproduce it on Samsung Galaxy A52s (SM-A528B) and Pixel 3 AVD, both running Android 12. Audios are paused when I back to home. Are there any specific instruction on how to reproduce this?

@MikuAuahDark MikuAuahDark added the more info needed Further information is needed from the user label Aug 22, 2022
@powertomato
Copy link
Author

Thanks for looking into it. I can confirm your above code works as expected. It helped me find the source of the culprit, however. In my code the play() call happens in the love.update function and wether or not it happens depends on several factors. I was able to reproduce the issue with some small changes to your code:

local play = false

function love.load()
	rolling = love.audio.newSource("test.mp3", "stream")
	rolling:setLooping(true)
end

function love.draw()
	love.graphics.print(tostring(rolling:isPlaying()), 64, 64)
end

function love.mousereleased()
    play = not play
end

function love.update()
    if play then
	rolling:play()
    else
        rolling:pause()
    end
end

@MikuAuahDark
Copy link
Contributor

In that case, I think there's another 1 frame that slip through just after LOVE receives event that it should pauses all sources. So, the flow will look like this:

event poll
- got event "will be minimized"
- all playing audio is paused
update loop
- audio is played again
draw loop
present draws

event poll
- event poll is blocked until it got "app restored" event
- got event "app restored"
- all previously played audio is resumed
update loop
draw loop
present draws

I think the actual solution to this is using OpenAL-soft's ALC_SOFT_pause_device extension, but falling back to the current code if it's unavailable.

@MikuAuahDark MikuAuahDark removed the more info needed Further information is needed from the user label Aug 24, 2022
@powertomato
Copy link
Author

powertomato commented Aug 24, 2022

The frame slipping and replaying seems plausible. I my initial claim that source:isPlaying() returns false is wrong and I probabbly debug-printed the state before source:play() was called again.

Using the following update function, play gets printed once after minimizing the app.

function love.update()
    if play then
        if not rolling:isPlaying() then 
            rolling:play()
            print("play")
        end
    else
        rolling:pause()
    end
end

I think the actual solution to this is using OpenAL-soft's ALC_SOFT_pause_device extension, but falling back to the current code if it's unavailable.

I would agree current solution seems a bit like a hack. As for the fallback in addition to pausing, it might make sense to also set the volume of all playing sources to 0 and restore the volumes again on regaining focus. This could lead to other problems, but they seem less annoying than background music still playing. But that's just my two cents.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
11.4 Android bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants