programing

비디오 요소를 올바르게 언로드/파괴하는 방법

padding 2023. 8. 11. 21:34
반응형

비디오 요소를 올바르게 언로드/파괴하는 방법

다음을 사용하는 실시간 미디어 브라우징/재생 응용 프로그램을 만들고 있습니다.<video>사용 가능한 경우 재생할 수 있도록 브라우저의 개체를 표시합니다.

스트레이트 자바스크립트와 jQuery를 혼합하여 사용하고 있습니다.

제 관심사는 특히 기억력입니다.애플리케이션은 창에서 다시 로드되지 않으며 사용자는 많은 비디오를 볼 수 있으므로 메모리 관리는 시간이 지남에 따라 큰 문제가 됩니다.오늘 테스트에서는 메모리 프로파일이 이후 로드할 때마다 스트리밍할 비디오 크기만큼 점프하고 기준선으로 다시 내려가지 않는 것을 확인했습니다.

저는 같은 결과로 다음과 같은 것들을 시도해 보았습니다.

1 - 생성된 요소가 들어 있는 상위 컨테이너를 비웁니다(예:

$(container_selector).empty();

2 - '비디오'와 일치하는 어린이를 일시 중지하고 제거한 다음 부모 컨테이너를 비웁니다.

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

다른 사람이 이 문제에 부딪혔는데 더 나은 방법이 있습니까?

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

쿼리가 해결되기를 바랍니다.

수집에 할 수 있도록 작동하는 사항을 하십시오).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작동을 중지시킵니다. 일부 이 어떻게 입니다.delete또는 브라우저 간의 비정상적인 상호 작용delete jQuery가사로 무엇을 있습니까?this.

그러니까, 만약 이 답이 여러분의 문제를 해결한다면, 만약 그것이 효과가 있다면, 왜 그것이 사실인지는 분명하지 않으며, 많은 이유로 인해 작동을 멈출 가능성이 있다는 것을 명심하세요.

비디오를 제거하지 않고 공백으로 재설정하려면 다음과 같이 하십시오.

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

비디오를 중지합니다.

delete(this); 

해결책이 아닙니다.x 또는 y에 대해 작동했다면 브라우저의 잘못된 동작입니다.여기에서 읽기:

삭제 연산자가 개체에서 속성을 제거합니다.

실제로 일부 브라우저(예: Firefox)는 자동 재생 속성이 설정되어 있을 때 비디오 버퍼를 메모리에 캐시합니다.그것은 다루기 힘든 고통입니다.

DOM에서 비디오 태그를 제거하거나 일시 중지하면 불안정한 결과만 발생할 수 있습니다.버퍼를 언로드해야 합니다.

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

제 실험에 따르면 그렇게 되어 있지만 안타깝게도 이것은 사양에 의해 완전히 지정되지 않은 브라우저 구현입니다.src 변경 후 load()를 호출할 필요가 없습니다.로드()를 암시적으로 호출하는 비디오 태그의 src를 변경할 때, 이는 W3C 사양에 명시되어 있습니다.

인 DOM 제거 없음)을 실행되지 않습니다.error를 위한 이벤트입니다.<video> 대답과 달리:

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

은 발사되지 , 그은발지않습다니사되.loadstart이벤트입니다. 마치 작동해야 하는 것 같습니다. 비디오가 없으면 로드가 시작되지 않습니다.

Chrome 54 / FF 49에서 확인.

나중에 이것을 시도하는 사람들을 위해 명확하게 설명하자면, 솔루션은 다음과 같습니다. (Safari 5.0의 h264 비디오에서 확인됨, FF/opera에서는 아직 테스트되지 않음)

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

동영상을 동적으로 로드하는 동안 문제가 발생했습니다.나는 두 가지 출처를 가지고 있었습니다.<video>하나는 mp4이고 다른 하나는 webmas 폴백입니다.그래서 나는 반복해서 반복해야 했습니다.<source>그런 것 같아요.

function removeMedia(){
    let videos = document.getElementsByTagName('video');
    for(let vid in videos){
        if(typeof videos[vid] == 'object'){
            let srcs = videos[vid].getElementsByTagName('source');
            videos[vid].pause();
            for(let xsrc in srcs){
                if(srcs[xsrc].src !== undefined){
                    srcs[xsrc].src = '';
                }
            }
            videos[vid].load();
            videos[vid].parentNode.removeChild(videos[vid]);
        }
    }
}

좋아요, 여기 확실히 효과가 있는 간단한 해결책이 있습니다.

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

이 버그에 따르면:

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의 메모리 누수 문제인 것 같습니다!

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

한 페이지에 최대 80개의 비디오를 로드하고 IE와 Edge의 메모리 관리에 문제가 있는 더 복잡한 수준에서 이 문제에 직면했습니다.저는 특별히 우리의 문제에 대해 물었던 비슷한 질문에 우리의 솔루션을 올렸습니다: https://stackoverflow.com/a/52119742/1253298

내 코드가 사용하지 않았습니다.<video>a가 있는 요소src태그, 대신 다중 사용<source>여러 형식으로 비디오를 설정할 수 있습니다.

이 비디오를 제대로 제거하고 언로드하려면 이 페이지에서 여러 개의 답변을 사용해야 했고, 그 결과 다음과 같은 결과가 나왔습니다.

var videoElement = $('#my-video')
videoElement[0].pause()  // Pause video
videoElement.empty()     // Remove all <source> children
videoElement.load()      // Load the now sourceless video
delete videoElement      // The call mentioned in other answers
videoElement.remove()    // Removing the video element altogether

이것이 누군가에게 도움이 되기를 바랍니다.

다음은 카메라를 닫는 방법에 대한 답입니다. 일시 중지만 하는 것이 아닙니다.정지해야 하는 것은 스트림입니다. 비디오 요소 참조가 아닙니다. stream.stop()

그다지 복잡하지 않습니다.src를 null로 설정합니다.

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

비디오가 제거됩니다.src기여하다.다 했어요.

이것이 제가 이 문제를 해결하기 위해 한 일입니다.2개의 비디오 요소(video1 및 video2)를 만들었습니다.video1 사용을 완료한 후 source(src) 특성 값을 가져온 다음 dom에서 video1을 제거합니다.

그런 다음 video1에서 얻은 값으로 video2 소스(src)를 설정합니다.

video1의 스트림은 메모리에 캐시되므로 사용하지 마십시오.

이것이 도움이 되기를 바랍니다.

Angular에서 나에게 효과가 있었던 하나의 솔루션JS는 다음 코드를 사용합니다.원본 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();

누군가 그것을 유용하게 생각하길 바랍니다.

이것이 오래된 질문이라는 것을 알지만, 저는 같은 문제를 접했고, 다음을 언급하는 거의 모든 해결책을 시도했습니다.<video>src속성, 그리고 모든 솔루션에는 단점이 있는 것 같았습니다.

내 특정한 경우에는, 게다가<video>요소, 저도 사용하고 있습니다.<audio>요소들을 동시에.

MDN에서 기사를 읽고 있을 때 저는 그것을 다루는 것을 깨달았습니다.src속성이 잘못된 것일 수 있습니다.대신 추가 및 제거하기 위해 모든 코드를 다시 작성했습니다.<source>양자의 요소.<video>그리고.<audio>요소들.

그것이 새로운 부하를 유발하거나 오류 또는 기타 바람직하지 않은 알림을 생성하지 않는 유일한 방법이었습니다.

사용 중인 코드의 최소/간단 버전입니다(Firefox 86 및 Chrome 88에서 테스트됨).

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui, shrink-to-fit=no" />
</head>
<body>
    <button type="button" onclick="play()">Play</button>

    <button type="button" onclick="stop()">Stop</button>

    <video id="myVideo"></video>

    <script type="text/javascript">
        "use strict";

        var myVideo = document.getElementById("myVideo");

        myVideo.onloadstart = () => {
            console.log("onloadstart");
        };

        myVideo.onloadeddata = () => {
            console.log("onloadeddata");
        };

        myVideo.onload = () => {
            console.log("onload");
        };

        myVideo.onerror = () => {
            console.log("onerror");
        };

        function play() {
            while (myVideo.firstChild)
                myVideo.removeChild(myVideo.firstChild);

            var source = document.createElement("source");
            source.src = "example.mp4";
            myVideo.appendChild(source);
            myVideo.load();
            myVideo.play();
        }

        function stop() {
            while (myVideo.firstChild)
                myVideo.removeChild(myVideo.firstChild);

            myVideo.load();
        }
    </script>
</body>
</html>

저의 경우, @toonlite가 언급한 솔루션을 사용했습니다.

 Array.from(document.getElementsByTagName('video')).forEach(video => {
   video.pause();
   video.removeAttribute('src');
   video.load();
 })

그러나 Chrome 브라우저(버전 93)에서 또 다른 문제가 발생합니다.

[Intervention] Blocked attempt to create a WebMediaPlayer as there are too many WebMediaPlayers already in existence. See crbug.com/1144736#c27

브라우저 버전의 제한(내 것은 너무 오래됨)에 관한 것이라고 생각합니다. 어쨌든 몇 가지 추가 작업을 추가하여 이 버그를 수정했습니다.

video.src = '';
video.srcObject = null;  
video.remove()

마지막으로 코드는 다음과 같습니다.

Array.from(document.getElementsByTagName('video')).forEach(video => {
  video.pause();
  video.removeAttribute('src'); // video.src = '' works so this line can be deleted
  video.load();
  video.src = '';
  video.srcObject = null;  
  video.remove()
})

언급URL : https://stackoverflow.com/questions/3258587/how-to-properly-unload-destroy-a-video-element

반응형