ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Html Video set currentTime not working(not change)
    JS 2024. 8. 5. 14:37

    문제

    1. currentTime을 0이 아닌 값으로 변경해도 0으로 설정되는 이슈
    2. controls 설정을 true로 해서 타임라인bar를 변경해도 원래시간으로 돌아감.

    해결과정

    1. 이벤트 리스너들을 통해 정상적으로 load되는지 확인.
    2. 예시코드
    <video id="testVideo" width="640" controls>
        <source src="/static/myVideo.mp4" type="video/mp4">
        Your browser does not support the video tag.
    </video>
    <script>
        const video = document.getElementById('testVideo');
    
        video.addEventListener('loadedmetadata', function() {
            console.log('메타데이터 로드됨, 비디오 길이:', video.duration);
            console.log('Ready state:', video.readyState);
            console.log('Network state:', video.networkState);
        });
    
        video.addEventListener('loadeddata', function() {
            console.log('비디오 데이터 로드됨');
            console.log('Ready state:', video.readyState);
            console.log('Network state:', video.networkState);
        });
    
        video.addEventListener('canplaythrough', function() {
            console.log('비디오 완전히 로드됨');
            const seekableRanges = video.seekable;
            if (seekableRanges.length > 0) {
                for (let i = 0; i < seekableRanges.length; i++) {
                    console.log(`Seekable range ${i}: ${seekableRanges.start(i)} to ${seekableRanges.end(i)}`);
                }
            } else {
                console.log('No seekable ranges available.');
            }
            console.log('Ready state:', video.readyState);
            console.log('Network state:', video.networkState);
        });
    
        video.addEventListener('progress', function() {
            const buffered = video.buffered;
            for (let i = 0; i < buffered.length; i++) {
                console.log(`Buffered range ${i}: ${buffered.start(i)} to ${buffered.end(i)}`);
            }
            console.log('Ready state:', video.readyState);
            console.log('Network state:', video.networkState);
        });
    
        video.addEventListener('error', function(e) {
            console.error('비디오 로드 중 오류 발생:', e);
            console.log('Ready state:', video.readyState);
            console.log('Network state:', video.networkState);
        });
    </script>
    // console.log 결과 출력
    Buffered range 0: 0 to 0.0 // seek할 수 있는 범위 (여기가 문제임)
    Ready state: 4
    Network state: 1
    1. 다양한 시행착오 결과...같은 html소스라도 서버에서 html을 반환하는것과 정적으로 띄우는것에서 차이가 생김을 발견.
    2. 비디오 경로를 일반 static 경로가 아닌, 서버에서 파일 객체를 반환하는 mappingUrl을 사용
    3.  
    // html 소스
    
    // 기존
    <video id="testVideo" width="640" controls>
        <source src="/static/myVideo.mp4" type="video/mp4">
        Your browser does not support the video tag.
    </video>
    
    
    // 변경
    <video id="testVideo" width="640" controls>
        <source src="/server/getVideo.mp4" type="video/mp4">
        Your browser does not support the video tag.
    </video>
    import from starlette.responses import FileResponse
    
    # 서버 소스 추가
    @router.get("/server/{name_video}")
    def get_video(request: Request, name_video: str):
        video_path = "static/" + name_video
    
        return FileResponse(video_path, headers={"Accept-Ranges": "bytes"})
    

    결론

    • 비디오 파일을 로드하는데 문제가 있는거라고 밖에 안보임.(물론 네트워크 탭에서 200이지만..)
    • html에서 video src를 직접 정의하는것이 아닌, 서버를 통해 파일 객체를 받아오게 정의하면 currentTime을 변경할때 문제가 되지 않음.

     

    +추가

    • 서버에서 File을 리턴할때 header에 추가해준 "Accept-Ranges" 덕분에 js에서 범위를 특정부분으로 이동할 수 있게 됬던거임.

     

    댓글

#dev-hahm#