Подтвердить что ты не робот

Как правильно разгрузить/уничтожить элемент VIDEO

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

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

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

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

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

$(container_selector).empty();

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

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

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

4b9b3361

Ответ 1

Располагать видео из структуры 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

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

Ответ 2

Сообщается, что это "решение" работает, по-видимому, потому, что оно сделает эти объекты видеоконтента доступными для сбора мусора (см. примечание ниже для обсуждения того, почему 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.

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

Ответ 3

В reset видео в Blank без его удаления

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

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

Ответ 4

delete(this); 

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

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

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

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

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

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

Ответ 5

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

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

Ответ 6

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

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

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

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

Ответ 7

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

var bodypage = document.getElementsByTagName('body')[0];
var control_to_remove = document.getElementById('id_of_the_element_here');
bodypage.removeChild(control_to_remove);

Ответ 9

var video = document.getElementById('video');
        if (video.firstChild) {
            video.removeChild(video.firstChild);
            video.load();
        }

Ответ 10

Вот ответ о том, как закрыть камеру - не только пауза. Это поток, который нужно остановить, а не ссылку на видеоэлементы: stream.stop()

Ответ 11

Не очень сложно. Просто установите свой src на ноль.

Eg: document.querySelector('#yourVideo').src = null;

Это удалит ваш атрибут видео src. Готово.

Ответ 12

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

Ответ 13

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

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

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

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

Ответ 14

Одно из решений, которое сработало для меня в AngularJS, использует следующий код: Если вы не хотите удалять исходный URL и сбросить его до начала видео

let videoElement = $document[0].getElementById('video-id');
videoElement.pause();
videoElement.seekable.start(0);
videoElement.load();

А если вы хотите удалить источник из тега видео:

let videoElement = $document[0].getElementById('video-id');
videoElement.pause();
videoElement.src="";
videoElement.load();

Надеюсь, кто-то найдет это полезным.