1

在播放播放列表大约两天后,内存从大约 100 兆字节增加到几千兆字节。线程数保持不变,大约 20 个线程。我正在处理来自 mediaplayer 元素的媒体(当更改为新媒体时),如下所示:

                            if(web.MediaPlayer.Media != null) {
                                web.MediaPlayer.Media.Dispose();
                            }
                    
                            web.MediaPlayer.Media = media;

以及创建新媒体播放器时:

                            if(web.MediaPlayer != null) {
                                if(web.MediaPlayer.Media != null) {
                                    web.MediaPlayer.Media.Dispose();
                                }
                                web.MediaPlayer.Dispose();
                            }

                            web.MediaPlayer = new MediaPlayer(media) { EnableHardwareDecoding = true };

这足以像这样处置媒体吗?

当到达终点时,我会像这样播放下一个媒体,调用 init video 会调用第一段代码。在媒体播放器中切换媒体。

                    web.MediaPlayer.EndReached += (s, e) => ThreadPool.QueueUserWorkItem(_ => { 
                        if(this.tab_objects.ContainsKey(tab_index)) {
                            tab tab_object = this.tab_objects[tab_index];
                            string next_media = tab_object.get_next_media();
                            ....some other code....
                            if(next_media != null) {
                                this.init_video(next_media, tab_index, true);
                            } else {
                                
                    
                            }
                        }
                    });

任何帮助表示赞赏。

我已将代码更改为此没有结果:

            using(Media media = new Media(this.lib_vlc, uri)) {
                using(MediaPlayer p = web.MediaPlayer) {
                    if(p != null) {
                        /*using(Media last_media = p.Media) {
                            if(last_media != null) {
                                last_media.Dispose();
                            }
                        }*/
                    }   
                    web.MediaPlayer = null;
                    if(p != null) {
                        p.Dispose();
                    }
                    web.MediaPlayer = new MediaPlayer(media) { EnableHardwareDecoding = true };
                    media.Dispose();
                }
            }

我已经注释掉了“last_media”部分,因为它没有效果。我将 web.MediaPlayer 设置为 null,因为在将 MediaPlayer 对象设置为其他对象之前,它会导致崩溃。

我会将媒体包装在“使用”中并明确处理它就足够了。但内存使用量仍在攀升。处理最后播放的媒体对象的正确方法是什么?

4

1 回答 1

1

调用 MediaPlayer.Media 调用获取媒体的本机函数,并创建一个新的媒体实例。每次调用该属性时,都会得到一个新实例。从 C# 方面来看,这并不是一个真正的问题,因为所有这些实例都将被垃圾收集,但它们没有被正确处理。本机获取媒体函数在内部递增一个引用计数器,当您调用 Dispose 时该计数器递减。

如果您调用 N 次 MediaPlayer.Media,您将增加 N 次 ref 计数器,但在调用 Dispose 时仅释放一次。

另一个相关注意事项:当您将媒体传递给媒体播放器时,您可以(如果您不重复使用它可能应该)立即处理它(即减少引用计数并让 libvlc 成为唯一的引用用法)

编辑:为了澄清,而不是在 MediaPlayer.Media 上进行操作,您应该存储属性的结果并在完成后处理它

于 2021-02-20T16:57:09.193 回答