PLAYBACK NOTES · 01

야코레드 재생 기록: 중간으로 넘길 때 다시 기다리는 이유

야코레드 편집 기록발행

처음부터 볼 때는 괜찮았는데 중간으로 넘기는 순간 기다림이 시작된다면, ‘인터넷이 느리다’는 말만으로는 설명이 끝나지 않아요. 필요한 뒷부분을 따로 받을 수 있는지도 영향을 줍니다. 야코레드에서는 같은 MP4 파일에 같은 구간을 요청하고, 서버의 응답 방식을 바꿔 그 차이를 확인했어요.

이번 기록의 핵심

같은 65,536바이트 요청에 한쪽은 206과 해당 구간을, 다른 쪽은 200과 전체 4,372,373바이트를 보냈어요. 성공 코드만 볼 게 아니라 ‘무엇을 요청했고, 실제로 무엇이 왔는지’를 맞춰 봐야 합니다.

파일은 그대로 두고, 응답 방식만 바꿨어요

사용한 파일은 W3C 미디어 서버에 공개된 Sintel 예고편 MP4입니다. 내려받은 파일은 4,372,373바이트였어요. 로컬 서버의 두 경로가 이 한 파일을 읽도록 만들었습니다. 한 경로는 Range 헤더를 처리하고, 다른 경로는 그 헤더를 무시하고 파일 전체를 반환하도록 설정했어요.

그다음 HTTP 클라이언트에서 Range: bytes=1048576-1114111을 보냈습니다. 시작 위치와 끝 위치를 모두 포함하므로 1,114,111 − 1,048,576 + 1 = 65,536바이트, 즉 64 KiB를 요구한 셈이에요. 이 위치는 비교를 위해 고른 파일상의 위치입니다. 영상의 ‘몇 분 몇 초’를 뜻하지는 않아요.

확인 날짜
2026-10-24
환경
Windows · Python HTTP 클라이언트와 로컬 서버
고정한 조건
파일 내용, 요청 범위, 압축 없는 응답
바꾼 조건
부분 요청 처리 여부, 마지막 사례의 요청 시작 위치

캐시는 쓰지 않도록 했고 응답 본문은 끝까지 읽었습니다. 따라서 아래 값은 브라우저의 화면 로딩 시간이나 실제 시청 중 데이터 사용량이 아니라, 이 요청 한 번에 끝까지 받은 본문 크기예요. 파일과 응답 본문의 SHA-256도 기록해, 크기만 같고 내용이 다른 경우를 걸렀습니다.

세 가지 요청에서 실제로 받은 것

로컬 HTTP 비교 결과 · 2026-10-24
조건응답받은 본문Content-Range
구간 요청 처리20665,536 Bbytes 1048576-1114111/4372373
같은 구간 요청 무시2004,372,373 B없음
파일 끝 다음부터 요청4160 Bbytes */4372373

첫 응답은 요청했던 65,536바이트와 길이가 맞았고, 원본에서 잘라 낸 같은 구간의 해시와도 일치했어요. 두 번째 응답은 전체 파일의 해시와 같았습니다. 단지 상태 코드만 다른 게 아니라, 실제로 도착한 데이터의 범위가 달랐던 거죠.

도식의 상자 크기는 전송량 비율을 나타내지 않습니다. 전체 요청 헤더·해시 원자료

두 본문 크기를 나누면 약 66.7배예요. 하지만 ‘66.7배 빨라진다’는 해석은 틀립니다. 브라우저는 응답을 끝까지 받기 전에 취소할 수 있고, 이미 받은 데이터와 서버까지의 거리도 영향을 주거든요. 우리가 확인한 차이는 전송 단위이지, 체감 대기 시간의 배수가 아닙니다.

200도 성공인데, 왜 구분할까요?

200 OK는 요청에 성공적으로 응답했다는 뜻이에요. 그런데 부분 요청을 보냈어도 서버가 그 요청을 무시하고 전체 표현을 보내는 경우가 있습니다. HTTP 규격도 이런 동작을 허용해요. 그래서 ‘206은 정상, 200은 고장’이라고 나누는 대신, 요청한 범위와 응답한 범위가 맞는지를 보려고 합니다. 근거: HTTP Semantics의 Range 규정

동영상에서 필요한 구간만 따로 받을 수 있으면 아직 받지 않은 위치로 이동할 때 도움이 됩니다. 다만 파일의 바이트 위치와 재생 시간은 일대일 비례하지 않아요. 컨테이너의 인덱스, 인코딩 구조, 디코딩에 필요한 앞선 데이터까지 관여합니다. 이번 64 KiB 조각만으로 한 장면이 재생된다고 주장하지 않는 이유예요.

416은 주소가 막혔다는 뜻이 아니었어요

세 번째 요청은 일부러 bytes=4372373-로 보냈어요. 4,372,373바이트짜리 파일의 마지막 바이트 위치는 0부터 세기 때문에 4,372,372입니다. 우리가 요청한 시작점은 이미 파일 밖이었고, 서버는 416과 현재 전체 길이를 돌려줬습니다.

이 사례에서는 서버가 닿지 않은 게 아니라, 서버가 요청을 받고 줄 수 없는 범위라고 답한 것이었어요. 실제 서비스의 416을 모두 같은 원인으로 설명할 수는 없지만, 오류 코드만 보고 도메인 차단으로 분류하면 중요한 정보를 놓칠 수 있습니다. MDN의 416 설명

화면에서는 ‘이동한 시간’과 ‘받아 둔 구간’을 나눠 보세요

재생기의 시간 표시가 이동했다고 해서 그 장면까지 데이터가 도착한 것은 아닙니다. 웹 미디어에는 이미 받은 구간인 buffered와 이동 가능한 구간인 seekable이 따로 있어요. 부분 요청을 지원하면 아직 모두 내려받지 않은 구간도 이동 가능 범위에 들어갈 수 있습니다. 두 값의 의미는 MDN의 미디어 버퍼·탐색 설명에서 확인할 수 있어요.

독자 입장에서 우선 남길 만한 건 세 가지입니다. 첫 장면이 나온 시점, 이동하려던 시점, 그리고 같은 지점에서 다시 시도했을 때의 결과예요. 재생기가 버퍼 범위를 표시하지 않더라도 이 순서는 기록할 수 있습니다. 설정을 여러 개 바꾸기 전에 남겨 두면 다음 비교에 도움이 됩니다.

설명용 기록 예시

“처음 00:10까지 정상 재생 → 00:40으로 이동 → 시간 표시는 바뀌었지만 영상은 정지 → 같은 영상의 00:20으로 이동했을 때는 재생됨.” 실제 이번 실험의 재생 관찰값은 아니며, 증상을 전달하는 형식의 예시입니다.

네트워크 기록을 볼 수 있다면

  1. 개발자 도구의 Network를 켠 상태에서 문제의 시점으로 한 번 이동해요. 문서나 썸네일이 아니라 그때 요청된 미디어 항목을 찾습니다.
  2. 요청에 Range가 있는지 보고, 응답 상태와 Content-Range를 함께 확인해요. 단순히 Accept-Ranges 헤더 하나만 보고 실제 구간 요청 결과를 대신 판단하지 않습니다.
  3. 206이면 요청·응답 구간이 어떻게 맞는지, 200이면 전체 응답인지 기록합니다. 416이면 요청 시작 위치와 응답에 적힌 전체 크기를 비교해요.

이 순서는 직접 MP4를 받는 경우에 맞춰져 있어요. .m3u8 목록과 여러 세그먼트를 받는 스트리밍에서는 구조가 다릅니다. 작은 세그먼트 파일을 200으로 정상 수신하는 것까지 문제로 해석하면 안 돼요. 네트워크 도구에서 항목을 찾지 못했거나 확신이 없다면, 증상과 시점만 남겨도 충분합니다.

이 기록으로 해결했다고 말하지 않는 부분

부분 전송은 재생 경로의 한 요소예요. 소리는 나는데 화면이 안 나오는 코덱 문제, 기기의 디코딩 성능, 특정 파일의 손상, 인증 만료는 이 비교에서 검사하지 않았습니다. 외부 사이트의 라이브 재생 상태도 측정하지 않았고, Chrome·Safari나 실제 휴대전화 사이의 차이도 이번 결과로는 알 수 없어요.

그래서 이번에 얻은 결론은 좁지만 분명합니다. ‘페이지가 열렸다’, ‘HTTP 요청이 성공했다’, ‘필요한 영상 구간이 도착했다’는 서로 다른 확인 항목이에요. 다음에 중간 이동에서만 기다림이 생기면, 주소를 무작정 바꾸기 전에 어느 단계까지 됐는지부터 남겨보세요. 그 기록이 있어야 다음 점검이 같은 자리를 맴돌지 않습니다.

실험 자료와 참고 문서

측정은 로컬 비교 환경에서 수행했습니다. 외부 영상 파일은 이 사이트에 복제하거나 자동 재생하지 않습니다.