Как правильно выгрузить / уничтожить элемент ВИДЕО - PullRequest
38 голосов
/ 15 июля 2010

Я работаю над приложением для просмотра / воспроизведения мультимедиа в реальном времени, которое использует <video> объекты в браузере для воспроизведения, когда это возможно.

Я использую сочетание прямого javascript и jQuery,

Меня беспокоит именно память.Приложение никогда не перезагружается в окне, и пользователь может смотреть много видео, поэтому со временем управление памятью становится большой проблемой.На сегодняшнем тестировании я вижу, как профиль памяти прыгает по размеру видео, которое будет передаваться при каждой последующей загрузке, и никогда не опускается до базовой линии.

Я пробовал следующие вещи с тем же результатом:

1 - очистить родительский контейнер, содержащий созданный элемент, например:

$(container_selector).empty();

2 - приостановить и удалить дочерние элементы, соответствующие 'video', а затем очистить родительский контейнер:

$(container_selector).children().filter("video").each(function(){
    this.pause();
    $(this).remove();
});
$(container_selector).empty();

Кто-нибудь еще сталкивался с этой проблемой, и есть ли лучший способ сделать это?

Ответы [ 13 ]

64 голосов
/ 21 января 2015

Очень сложно удалить видео из структуры DOM. Это может привести к сбою браузера. Вот решение, которое помогло мне в моем проекте.

var videoElement = document.getElementById('id_of_the_video_element_here');
videoElement.pause();
videoElement.removeAttribute('src'); // empty source
videoElement.load();

это сбросит все, молчит без ошибок!

Редактировать: Вот полная информация, как рекомендуется в Стандарте: https://html.spec.whatwg.org/multipage/media.html#best-practices-for-authors-using-media-elements

Надеюсь, это разрешит ваш запрос.

16 голосов
/ 15 июля 2010

Сообщается, что это «решение» работает, вероятно, потому, что оно сделает эти объекты видео контейнера доступными для сбора мусора (см. Примечание ниже для обсуждения того, почему delete не должно иметь значения). В любом случае ваши результаты могут отличаться в зависимости от браузера:

$(container_selector).children().filter("video").each(function(){
    this.pause(); // can't hurt
    delete this; // @sparkey reports that this did the trick (even though it makes no sense!)
    $(this).remove(); // this is probably what actually does the trick
});
$(container_selector).empty();

Примечание: Нет сомнений в том, что ключевое слово delete указывается только для удаления свойств из объектов (как другие отмечали в комментариях). Запись this на консоль как до, так и после строки delete this, приведенной выше, каждый раз показывает один и тот же результат. delete this ничего не должен делать и ничего не менять. Тем не менее, этот ответ продолжает набирать обороты, и люди сообщают, что пропуск delete this заставляет его перестать работать. Возможно, есть странность в том, как некоторые движки JS браузеров реализуют delete, или необычное взаимодействие между браузером delete и тем, что jQuery делает с this.

Итак, просто знайте, что если этот ответ решит вашу проблему, то, если он сработает, непонятно, почему это так, и с такой же вероятностью он перестанет работать по любому числу причин.

4 голосов
/ 04 марта 2014

Для сброса видео в пустое без удаления

$("#video-intro").first().attr('src','')

Останавливает видео

3 голосов
/ 13 мая 2015
delete(this); 

- это , а не решение.Если это сработало для x или y, это неправильное поведение браузера.Прочитайте здесь :

Оператор удаления удаляет свойство из объекта.

Правда в том, что некоторые браузеры (например, Firefox) будут кэшироватьв памяти видеобуфер, когда свойство autoplay включено.Трудно иметь дело.

Удаление тега видео из DOM или приостановка его работы могут привести только к нестабильным результатам.Вы должны выгрузить буфер.

var video = document.getElementById('video-id');
video.src = "";

Мой эксперимент показывает, что это сделано так, но, к сожалению, это реализация браузера, не полностью определенная spec .Вам не нужно вызывать load () после изменения src.При изменении src тега video вы неявно вызываете load () для него, это указано в спецификации W3C.

2 голосов
/ 16 июля 2010

Просто чтобы уточнить, кто попробует это позже, решение было таким: (подтверждено видео h264 в Safari 5.0, еще не протестировано в FF / opera)

$(container_selector).children().filter("video").each(function(){
    this.pause();
    delete(this);
    $(this).remove();
});
$(container_selector).empty();
1 голос
/ 18 мая 2017

Согласно этой ошибке:

https://bugs.chromium.org/p/chromium/issues/detail?id=255456&can=2&q=255456&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified

это похоже на проблему утечки памяти в Chrome!

1 голос
/ 04 ноября 2016

Этот фрагмент не выполняет никаких эффективных манипуляций с DOM (без удаления тегов) и не запускает error событие для <video> в отличие от этого ответа :

var video = document.getElementById('video');
video.removeAttribute('src');
video.load();

Кроме того, он не запускает событие loadstart.И это похоже на то, что оно должно работать - без видео, без загрузки.

Проверено в Chrome 54 / FF 49.

1 голос
/ 31 августа 2012

хорошо, вот простое решение, которое, безусловно, работает:

var bodypage = document.getElementsByTagName('body')[0];
var control_to_remove = document.getElementById('id_of_the_element_here');
bodypage.removeChild(control_to_remove);
0 голосов
/ 08 июня 2019

Это то, что я сделал, чтобы решить эту проблему. Я создал 2 видеоэлемента (video1 и video2). После окончания использования video1 получите значение атрибута source (src) и затем удалите video1 из DOM.

Затем установите источник видео2 (src) на любое значение, которое вы получили от видео1.

Не использовать поток из video1, так как он кэшируется в памяти.

Надеюсь, это поможет.

0 голосов
/ 31 августа 2018

Я столкнулся с этой проблемой на более сложном уровне, когда мы загружаем ~ 80 видео на страницу и у меня возникают проблемы с управлением памятью в IE и Edge. Я разместил наше решение по аналогичному вопросу, который я задал специально о нашей проблеме: https://stackoverflow.com/a/52119742/1253298

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...