web-dev-qa-db-ja.com

VIDEO要素を適切にアンロード/破棄する方法

私は、ブラウザで<video>オブジェクトを使用して、利用可能な場合に再生するリアルタイムメディアブラウジング/再生アプリケーションに取り組んでいます。

ストレートjavascriptとjQueryを組み合わせて使用​​していますが、

私の懸念は、特にメモリです。アプリケーションがウィンドウにリロードされることはなく、ユーザーは多くのビデオを視聴できるため、時間の経過とともにメモリ管理が大きな懸念事項になります。今日のテストでは、メモリプロファイルは、後続の各ロードでストリーミングされるビデオのサイズごとにジャンプし、ベースラインに戻ることはありません。

私は同じ結果で次のことを試しました:

1-作成された要素を含む親コンテナを空にします。例:

$(container_selector).empty();

2-「ビデオ」に一致する子を一時停止および削除し、親コンテナを空にします。

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

他の誰かがこの問題に遭遇しましたか?これを行うより良い方法はありますか?

42
sparkey0

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 =

クエリが解決されることを願っています。

69
toon lite

この「解決策」は、おそらくビデオコンテナオブジェクトをガベージコレクションに利用できるようになるために機能すると報告されています(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キーワードがオブジェクトからプロパティを削除するためだけに指定されていることは間違いありません(他の人がコメントで指摘しているように)。上記のdelete this行の前後でthisをコンソールに記録すると、毎回同じ結果が表示されます。 delete thisは何もせず、違いも生じないはずです。それでも、この回答には引き続き票が寄せられ、人々はdelete thisを省略すると機能しなくなると報告しています。おそらく、一部のブラウザーJSエンジンがdeleteを実装する方法に奇妙な点があるか、ブラウザーのdeleteとjQueryがthisで実行していることとの間に異常な相互作用があります。

したがって、この答えがあなたの問題を解決する場合、それが機能する場合、それが事実である理由は明確ではなく、さまざまな理由で機能しなくなる可能性があることに注意してください。

17
Ken Redler

ビデオを削除せずに空白にリセットするには

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

ビデオを停止します

5
Bishoy Hanna
delete(this); 

not解決策です。 xまたはyで機能した場合は、ブラウザの誤動作です。読み取り ここ

削除演算子は、オブジェクトからプロパティを削除します。

真実は、自動再生プロパティがオンになっていると、一部のブラウザー(たとえば、Firefox)がビデオバッファーをメモリにキャッシュすることです。対処するのは苦痛です。

DOMからビデオタグを削除したり、一時停止したりすると、不安定な結果しか生成されません。バッファをアンロードする必要があります。

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

私の実験では、そのように行われていることが示されていますが、残念ながら、これは spec で完全に指定されていないブラウザ実装です。 srcの変更後にload()を呼び出す必要はありません。ビデオタグのsrcを変更する場合、暗黙的にload()を呼び出します。これはW3C仕様に記載されています。

4
Arnaud Leyder

これを後で試す人のために明確にするために、解決策はこれでした:(Safari 5.0のh264ビデオで確認済み、FF/operaではまだテストされていません)

$(container_selector).children().filter("video").each(function(){
    this.pause();
    delete(this);
    $(this).remove();
});
$(container_selector).empty();
3
sparkey0
var video = document.getElementById('video');
        if (video.firstChild) {
            video.removeChild(video.firstChild);
            video.load();
        }
2
Quan Quan
2
Bernd

さて、確かに機能する簡単なソリューションを次に示します。

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

このスニペットは効率的なDOM操作を行わず(タグを削除しない)、 この回答 とは異なり、<video>に対してerrorイベントを発生させません。

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

さらに、loadstartイベントは発生しません。そして、それはうまくいくはずです-ビデオなし、ロード開始なし。

チェックインChrome 54/FF 49。

2
Paul Annekov

この問題は、ページに〜80本のビデオをロードするより複雑なレベルで発生し、IE and Edge。のメモリ管理に問題があります。私たちの問題について具体的に尋ねました: https://stackoverflow.com/a/52119742/1253298

1
BBaysinger

一時停止だけでなく、カメラを閉じる方法についての回答を次に示します。停止する必要があるのはストリームです。ビデオ要素の参照ではありません: stream.stop()

AngularJSで私のために働いた1つのソリューションは、以下のコードを使用することです:ソース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();

誰かがそれを役に立つと思うことを願っています。

1
Nishant Patel

これは私がこの問題を解決するためにしたことです。 2つのビデオ要素(video1とvideo2)を作成しました。 video1の使用が終了したら、source(src)属性値を取得し、DOMからvideo1を削除します。

次に、video2ソース(src)をvideo1から取得した値に設定します。

Video1はメモリにキャッシュされるため、video1からのストリームを使用しないでください。

これが役立つことを願っています。

1
Shamsul Akmal

それほど複雑ではありません。 srcをnullにするだけです。

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

動画のsrc属性が削除されます。できた.

1