JS

Html Video set currentTime not working(not change)

dev-hahm 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에서 범위를 특정부분으로 이동할 수 있게 됬던거임.