修复了切换清晰度时 hls 等实例不被销毁导致内存泄漏的问题 (#1369)

* 修复了切换清晰度时 hls 等实例不被销毁导致内存泄漏的问题

* 在文档中增加了销毁实例以防内存泄漏的提示,并移除了过时内容
This commit is contained in:
koszzz 2026-02-21 20:14:48 +08:00 committed by GitHub
parent 3fd7896375
commit c07900cb8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 116 additions and 6 deletions

View File

@ -412,15 +412,56 @@ const dp = new DPlayer({
});
```
When using `customType` ([Work with other MSE library](#work-with-other-mse-library)), you should listen for the `destroy` and `quality_end` events to destroy the MSE library instance in a timely manner to avoid memory leaks.
```js
const dp = new DPlayer({
container: document.getElementById('dplayer'),
video: {
quality: [
{
name: 'HD',
url: 'demo_hd.m3u8',
type: 'Hls',
},
{
name: 'SD',
url: 'demo_sd.m3u8',
type: 'Hls',
},
],
defaultQuality: 0,
customType: {
Hls: (video, player) => {
const hls = new window.Hls();
hls.loadSource(video.src);
hls.attachMedia(video);
hls.sessionId = crypto.randomUUID();
player.sessionId = hls.sessionId;
player.events.on('destroy', () => {
hls.destroy();
});
player.events.on('quality_end', () => {
if (hls.sessionId !== player.sessionId) {
hls.destroy();
}
});
},
},
},
});
```
## Danmaku
### Danmaku API
`danmaku.api`
**Ready-made API**
<!-- **Ready-made API**
url: https://api.prprpr.me/dplayer/
url: https://api.prprpr.me/dplayer/ -->
Daily backup data: [DPlayer-data](https://github.com/DIYgod/DPlayer-data)
@ -788,4 +829,4 @@ For full browser support it should look like this:
### Why can't player autoplay in some mobile browsers?
Most mobile browsers forbid video autoplay, you wont be able to achieve it without hacks.
Most mobile browsers forbid video autoplay, you wont be able to achieve it without hacks.

View File

@ -396,15 +396,56 @@ const dp = new DPlayer({
});
```
在使用 `customType` [配合其他 MSE 库使用](#配合其他-mse-库使用)时,需要监听 `destroy``quality_end` 事件及时销毁 MSE 库实例,避免内存泄漏
```js
const dp = new DPlayer({
container: document.getElementById('dplayer'),
video: {
quality: [
{
name: 'HD',
url: 'demo_hd.m3u8',
type: 'Hls',
},
{
name: 'SD',
url: 'demo_sd.m3u8',
type: 'Hls',
},
],
defaultQuality: 0,
customType: {
Hls: (video, player) => {
const hls = new window.Hls();
hls.loadSource(video.src);
hls.attachMedia(video);
hls.sessionId = crypto.randomUUID();
player.sessionId = hls.sessionId;
player.events.on('destroy', () => {
hls.destroy();
});
player.events.on('quality_end', () => {
if (hls.sessionId !== player.sessionId) {
hls.destroy();
}
});
},
},
},
});
```
## 弹幕
### 弹幕接口
`danmaku.api`
**现成的接口**
<!-- **现成的接口**
链接: https://api.prprpr.me/dplayer/
链接: https://api.prprpr.me/dplayer/ -->
每日备份: [DPlayer-data](https://github.com/DIYgod/DPlayer-data)
@ -772,4 +813,4 @@ dp.danmaku.draw(danmaku);
### 为什么播放器不能在手机上自动播放?
大多数移动端浏览器禁止了视频自动播放。
大多数移动端浏览器禁止了视频自动播放。

View File

@ -382,6 +382,7 @@ class DPlayer {
this.type = 'normal';
}
const src = this.quality.url; // 真实的视频 url, 用于切换清晰度时销毁实例
switch (this.type) {
// https://github.com/video-dev/hls.js
case 'hls':
@ -396,6 +397,12 @@ class DPlayer {
hls.destroy();
delete this.plugins.hls;
});
// 切换清晰度时销毁实例
this.events.on('quality_end', () => {
if (src !== this.quality.url) {
hls.destroy();
}
});
} else {
this.notice('Error: Hls is not supported.');
}
@ -424,6 +431,14 @@ class DPlayer {
flvPlayer.destroy();
delete this.plugins.flvjs;
});
// 切换清晰度时销毁实例
this.events.on('quality_end', () => {
if (src !== this.quality.url) {
flvPlayer.unload();
flvPlayer.detachMediaElement();
flvPlayer.destroy();
}
});
} else {
this.notice('Error: flvjs is not supported.');
}
@ -444,6 +459,12 @@ class DPlayer {
window.dashjs.MediaPlayer().reset();
delete this.plugins.dash;
});
// 切换清晰度时销毁实例
this.events.on('quality_end', () => {
if (src !== this.quality.url) {
window.dashjs.MediaPlayer().reset();
}
});
} else {
this.notice("Error: Can't find dashjs.");
}
@ -473,6 +494,13 @@ class DPlayer {
client.destroy();
delete this.plugins.webtorrent;
});
// 切换清晰度时销毁实例
this.events.on('quality_end', () => {
if (src !== this.quality.url) {
client.remove(torrentId);
client.destroy();
}
});
} else {
this.notice('Error: Webtorrent is not supported.');
}