An7ar35 / ctune

nCurses internet radio player for Linux
GNU Affero General Public License v3.0
17 stars 0 forks source link

Error: 'Failed to capture next audio frame' leads to audio stop #27

Open antbricks opened 1 year ago

antbricks commented 1 year ago

Running ctune 1.2.0 on Arch + Konsole (latest)

While playing a stream, occasionally (every 5-10 minutes, depending on station) will get the error in the title. Can resume playing by hitting the 'r' key.

Attached log while running --debug.

I experience the issue more frequently on this station: "Technolovers DRUM N BASS" but it happens on other stations as well.

Rather than stopping completely, I would expect the playback to resume as soon as possible. Maybe there would be an audio drop for a second while the buffers catch up, but not a complete stop just for missing a frame. I have to switch back to the terminal and hit 'r' whenever this happens.

I realize this is ffmpeg throwing the error, but maybe it could be restarted, just logging the error?

ctune_audio_stop.log

An7ar35 commented 1 year ago

I realize this is ffmpeg throwing the error, but maybe it could be restarted, just logging the error?

Might be able to rig an optional toggle for retry-on-fail for these types of cases for that. I'll need a bit of time to think about a clean approach to implement that code-wise.

Meanwhile, a possible temporary solution would be to switch to the VLC player input plugin (IO::Plugin::Player= in the config file).

antbricks commented 1 year ago

switching to 'vlc' worked for a while, maybe a little longer, but then I got a stream underflow error from pulseaudio. See attached log. Neither ffmpeg nor vlc seem to recover automatically from errors like this, at least with my current settings. Again, pressing 'r' resumed the audio, but of course folks probably don't want to have to do that :P. ctune_stream_underflow.log

An7ar35 commented 1 year ago

The underflow warnings are just pulse saying 'I've got nothing to play'. The sound server plugin gets shutdown as a side effect of the player stopping since it's injected as a dependency on load in cTune.

You're right; constantly pressing resume is not ideal! After some more musings on that optional "force retry on fail" toggle, I'm thinking of also adding a configurable number n for sequential attempts at resuming the stream until giving up. The n count would be reset on success then. Thoughts?

antbricks commented 1 year ago

My opinion of course, but I think the idea of "giving up" is what you want to get away from. A resilient system would always try to automatically recover without human intervention. As long as they're running ctune they're expecting audio to pop out, right? To me, it feels like it should automatically recover, since I would like to run it in the background while I'm doing other stuff. That's my use case, at least. If you're worried about people thinking there's something wrong with ctune when it's really their bad connection, you could display an error banner or something to indicate why the audio stopped. The use could then read and dismiss the banner and hopefully not write a problem report like this one :).

Adding an error count threshold would still result in the audio stoppage, requiring human intervention, right? It would just take longer/be less likely. I guess it feels like kicking the can down the road. What if a user's on a dodgy wi-fi link? You might want the design to account for less-than-perfect connections, rather than assuming that everything should be reliable. Thanks for asking :)

An7ar35 commented 1 year ago

Ideally; yes, I agree. The problem is dealing with systems outside our controls. In perfect conditions the network would never loose packets or go down and the stream would always be up and serving up consistent and well formed frames. Reality doesn't quite hold up to that unfortunately! It's kind of a miracle the internet actually works as well as it does when you think about the number of layers/abstractions and things that can go wrong within each!

The idea was not to give up after n errors total but to reset that counter every time we recover before that threshold. So in practice: if a stream is misbehaving a user-customizable number or retries is attempted. If the stream gets picked up again/the next frame is well formed then the error state is reset and the application continues as if nothing happened.

For network failures, there is already a timeout variable by the way ("stream timeout" in the configuration menu). That's something both vlc and ffmpeg require or have internal defaults. This is why I've enable user configuration for that particular variable so that it can be tweaked as required. I can add larger values for edge cases but there isn't much I can do beyond that I'm afraid.

In your particular case with the bad frames, it's manageable as long as it's occasional but will need some work. I'll add a "ignore" option to the error counter threshold I'm planing so that you or anyone else with that problem can set that and force playback and ignore these types of errors when they are recurring on a large scale on a particular stream (consider notifying the stream's admin as they might not be aware).

The error banner message is a good idea - I'll see if I can squeeze that in along with the changes for the next version, time allowing.

Thank you for the feedback. It's always good to get some perspective from outside the lens of the code base! :)