jaseg / python-mpv

Python interface to the awesome mpv media player
https://git.jaseg.de/python-mpv.git
Other
531 stars 67 forks source link

Memory issue #233

Closed Chalkybot closed 1 year ago

Chalkybot commented 1 year ago

I'm using this library to listen to an online radio. My problem is that hte memory usage of the script goes up by around 1MB every minute or two. This leads to the process eating up potentially gigabytes of memory if I listen to the radio for long periods of time, as i do. I have tested and this does not occur without starting the "play" function.

dfaker commented 1 year ago

A quick test of this with these flags set:

import mpv

player = mpv.MPV()
player.cache=False
player.demuxer_max_bytes=100
player.demuxer_readahead_secs=0

player.play('https://media-ice.musicradio.com/CapitalMP3')
t = time.time()

Logging memory with

process = psutil.Process(os.getpid())
process.memory_info().rss
Playback time (s) Total Memory (b) Memory Increase since play (b)
5 37052416 4096
60 37163008 118784
120 37163008 118784
180 37437440 393216
240 37437440 393216
300 37978112 933888
540 37978112 933888
600 38014976 970752
810 38760448 1716224
860 38080512 1036288
872 33800192 -3244032
1043 34840576 -2203648
1200 33882112 -3162112
1320 33882112 -3162112
1440 33882112 -3162112
1500 33882112 -3162112
1560 33882112 -3162112
1620 33882112 -3162112
1680 33882112 -3162112
1740 33882112 -3162112

Tracemalloc shows no matching increase or decrease in python variable memory.

Process monitor seems to confirm a similar freeing.

So this would seem like normal caching and release on the mpv side, interestingly I'm seeing notable spikes when the tracks change or it switches to adverts so perhaps some kind of metadata in the stream is being cached?

Have we confirmed the predicted gigabytes of memory usage in practice or is it extrapolated?

If so is it reproducible with those cache flags set on the mpv instance?

jaseg commented 1 year ago

I'm reasonably sure that this is an issue inside libmpv, not python-mpv. First of all, there are not many places where python-mpv could leak memory while doing nothing. The only place where data gets passed between libmpv and python-mpv in the background is the event loop, but when running @dfaker's test code, the event loop does not receive any more events after the stream has started. Also, in its internal bookkeeping mpv uses a fixed-size buffer for the event loop and automatically frees the events (we don't have to do that from python).

The second indicator that this is a libmpv issue is that I observe the same issue when running command-line mpv on the stream URL from @dfaker's reply. From a cursory search it seems like this could be https://github.com/mpv-player/mpv/issues/5889 . On my system, mpv --demuxer-max-bytes=100k --demuxer-max-back-bytes=100k already seems to stop growing after a few seconds. From the mpv manpage's description of these options, beyond these two there are still other caches inside mpv's processing pipeline that might grow over time.

jaseg commented 1 year ago

I'm closing this as it seems that this is a libmpv issue. Please feel free to re-open or submit a new issue if it turns out that it is actually on the python-mpv side.