Open acmele opened 5 years ago
SImilar problem here! Looking for a fix
Same problem here. Fixing #78 would make this a lot easier to avoid, I would think.
I've been trying to debug this problem, and I think I've found the issue - but not a fix. Each time the player gets loaded with a source, I see an entry in lsof of type STREAM for the main python process. When player.stop() or .quit() is called, that entry does not go away. For example, after playing a sound effect 7 times, here's an excerpt of lsof | grep 'python':
python 12611 pi 0u CHR 136,2 0t0 5 /dev/pts/2
python 12611 pi 1u CHR 136,2 0t0 5 /dev/pts/2
python 12611 pi 2u CHR 136,2 0t0 5 /dev/pts/2
python 12611 pi 3u unix 0x9be72d00 0t0 219115 type=STREAM
python 12611 pi 4u unix 0x9be74c00 0t0 219245 type=STREAM
python 12611 pi 5u unix 0x9be71b00 0t0 218986 type=STREAM
python 12611 pi 6u unix 0x9be71800 0t0 219102 type=STREAM
python 12611 pi 7u unix 0x9be70000 0t0 219122 type=STREAM
python 12611 pi 8u unix 0x9be76a00 0t0 219986 type=STREAM
python 12611 pi 9u unix 0x9be76700 0t0 220066 type=STREAM
So far I haven't figured out a way to kill those open streams without killing the main python process, but I'll report back if I do.
I ran into the same problem and solved it for me with the following workaround:
You should not create new instances of OMXPlayer
, only create them once (player0
and player1
for you).
Instead call load()
with the new video to play.
With this approach the number of open streams does not increase anymore.
@michaelnimbs
You are my savior, everything works. You just need to use the method load()
Looking at the lsof output, the open fds are UNIX sockets, so I suspect this is the connection to the dbus daemon. Looking at the source, I indeed see that OMXPlayer._connection is created, but it is never actually closed.
I suspect that it would be solved by disconnecting dbus on quit, e.g. by adding this to the end of the quit()
method (alternatively, you can call this after you call quit from your program as well so you do not need to modify the library, then replace self
with your player instance):
self._connection._bus.close()
self._connection = None
Anyone care to test this?
Hi, using a single instance and only calling load
does not seem like it will help because the DBus connection is opened every time a new process is spawned. (see https://github.com/willprice/python-omxplayer-wrapper/blob/master/omxplayer/player.py#L163)
It may be that in most cases the garbage collector closes the connections but I encountered resource exhaustion at least once with 140 DBus sockets open in a long running Python process which used omxplayer-wrapper.
I'll monkey-patch the quit method to call self._connection._bus.close()
and see if this resolves the problem.
In case it helps someone, a quick patch looks like this:
def patch_OMXPLayer_quit():
old_quit = OMXPlayer.quit
def new_quit(self):
self._connection._bus.close()
old_quit(self)
OMXPlayer.quit = new_quit
patch_OMXPLayer_quit()
I'll let you know if it solved the problem definitely.
Ok, I've tested this for quite a long time now and the change I posted definitively fixed the problem with leaking bus connections.
Thanks @jpc for looking into this, would you be able to open a PR with this change and i'll merge it in!
I add @matthijskooijman suggestion in player.py at function quit() and it's work.(Tested 72 hours none stop playing 9 mp4 files, until now pi still playing without [Errno 24])
def quit():
if self._connection._bus is not None:
self._connection._bus.close()
logger.debug('[Errno 24][patch]BusConnection closed')
"""
Quit the player, blocking until the process has died
"""
......
Thanks for the confirmation @bonnyone. I'll make the change and make a new release later today.
@willprice U r welcome.
This is my code for test
def threadingPlayer():
while True:
try:
movie = movies[movie_index]
print('********************************')
print(movie)
print('********************************')
player = OMXPlayer(Path(movie),
args=['--no-osd', '--no-keys', '-o', 'hdmi'],
dbus_name='org.mpris.MediaPlayer2.omxplayer1')
player.set_volume(player_volume)
sleep(2.5)
player.play_sync()
player.quit()
player = None
print('Play Next')
movie_index = movie_index + 1
if movie_index == len(movies):
movie_index = 0
except OSError as e:
logger.error(e)
except Exception as e:
logger.error(e)
threading.Thread(target=threadingPlayer).start()
Issue Report
Description
Alternating between two player instances to put a video display on a tour. This eventually produces a [Errno 24] Too many open files after about an hour.
Problem reproduction
this is the current test code
Please let me know if you need more details, amateur here and first time posting.