Ok, a bit late but here is the demo code.
This problem occurs on Ubuntu 22.04 but also on Ubuntu 18.04 (Both tested)
When playing a ogg sound file while using ffpyplayer as the audio provider after 15 times playing the ffpyplayer will crash:
[WARNING] [ffpyplayer ] [ffpyplayer_abuffersink @ 0x7f99b0006a80] Removing channel layout 0x4, redundant with 1 channels
[WARNING] [ffpyplayer ] [ffpyplayer_abuffersink @ 0x7f99b001fac0] Removing channel layout 0x4, redundant with 1 channels
[WARNING] [ffpyplayer ] SDL_OpenAudio (1 channels, 48000 Hz): Too many open audio devices
[WARNING] [ffpyplayer ] SDL_OpenAudio (1 channels, 44100 Hz): Too many open audio devices
[ERROR ] [ffpyplayer ] No more channel combinations to try, audio open failed
[CRITICAL] [ffpyplayer ] Failed to open file '/mnt/nvme0n1p1/Github/btp-kivy/test_opus.ogg' or configure filtergraph
If you 'unload' the file after it plays the crash doesn't occur.
It doesn't matter if we install kivy with pip on python 3.8 or 3.10 or compile kivy for those platforms. Ffpyplayer will always crash after a few times playing if you don't unload the file.
We also tried using different versions of ffmpeg but it makes no difference.
This problem occurs on all kind of hardware, we have thousands of systems in use in about 10 different hardware configurations and all experiences this problem if we don't unload the sound after playing. This was also the reason we compiled our own kivy with gstreamer support the last few years but unfortunately newer python/kivy versions don't compile anymore with gtreamer support on Ubuntu 22.04 so we needed a hack to prevent the ffpyplayer from crashing.
(test code and soundfile is also attached)
The test code starts with playing without unloading and when you set the
global var 'do_unload' to True it will start and unload each file after
it plays.
---- The code -----
soundfile = 'test_opus.ogg'
do_unload = False
import os
os.environ['KIVY_NO_FILELOG'] = "1"
os.environ['KIVY_GL_BACKEND'] = 'sdl2'
os.environ['KIVY_VIDEO'] = 'ffpyplayer' #'gstplayer'
os.environ['KIVY_AUDIO'] = 'ffpyplayer' #gstplayer'
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from
kivy.app import App
from kivy.core.audio import SoundLoader
Builder.load_string("""
<Content>:
Button:
text: "Press me to start playing sound"
size_hint: (0.5, 0.5)
on_press: root.start_play()
""")
class Content(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.current_sound = None
def start_play(self, *args):
if self.current_sound and do_unload:
print("Unloading previous sound")
self.current_sound.unload()
self.play()
def play(self, *args):
sound = SoundLoader.load(soundfile)
self.current_sound = sound
sound.bind(on_stop=self.start_play)
sound.play()
class TestApp(App):
def build(self):
fl = Content()
return fl
TestApp().run()