Spring Framework 및 Chrome으로 비디오 스트림 설정

Aug 19 2020

Amazon S3 스토어의 비디오 (또는 오디오) 파일을 스트리밍 할 수있는 HTTP 엔드 포인트를 제공하는 Spring 서비스를 작성하고 있습니다. 기본 아이디어는 Google 크롬 주소 표시 줄에 URL을 입력 할 수 있으며 서비스가 S3에서 파일을 가져 와서 스트리밍하여 사용자가 다운로드를 기다릴 필요없이 즉시 시청을 시작할 수 있도록하는 것입니다. 완료되고 사용자가 비디오의 진행률 표시 줄에서 임의의 지점을 클릭하고 즉시 해당 지점에서 비디오 시청을 시작할 수 있습니다.

이것이 이론적으로 작동한다는 것을 이해하는 방식은 Chrome이 파일 다운로드를 시작한다는 것입니다. 이 서비스는 HTTP 200으로 응답하며 Accept-Ranges: bytesContent-Length: filesize헤더를 포함합니다 . 이는 filesize전체 파일을 가져 오지 않고 S3에서 메타 데이터로 쿼리 할 수 ​​있기 때문에 알려져 있습니다. 이러한 헤더를 포함하면 브라우저가 다운로드를 취소하고 헤더가있는 파일을 다시 요청합니다 Range: bytes=0-whatever( whateverChrome이 결정하는 일부 청크 크기). 그러면 서비스는 HTTP 206 (부분 콘텐츠) 및 요청 된 바이트 범위로 응답합니다. S3는 동일한 범위 프로토콜을 지원하기 때문에 쉽게 확인할 수 있습니다. 그런 다음 Chrome은 스트림이 끝날 때까지 서비스에서 연속 청크를 요청합니다.

Spring 측에서는 ResponseEntity<InputStreamResource>( 이 SO 답변에 따라 ) 데이터를 전송합니다 .

그러나 실제로 Chrome이 수백 바이트 후에 첫 번째 요청을 취소하는 동안 관찰됩니다. 그러나 Range: bytes=0-헤더 와 함께 두 번째 요청을 전송 하여 전체 파일을 효과적으로 요청합니다. 서버는 HTTP 206으로 응답합니다. 결과적으로은 (는) 수백 바이트의 비디오 만 다운로드했으며 비디오는 분명히 재생을 시작하지 않습니다.

흥미롭게도 Firefox에서는 모든 것이 제대로 작동합니다. 안타깝게도 앱은 Chrome을 지원해야합니다. 프로토콜의 일부가 누락 되었습니까?

답변

2 jqno Sep 01 2020 at 21:28

Content-Range응답 헤더 에 하나씩 오류가있는 것으로 나타 났습니다 .

구문은 Content-Range: bytes start-end/total입니다. totalof를 사용 10하여 전체 범위를 얻으려면 우리가하던 bytes 0-9/10일이 아니라 를 지정해야합니다 0-10/10.

물론 실제 파일의 크기가 더 크고 파일의 중간에있는 청크의 실제 범위로 인해이 오류는 이전 단락의 인위적인 예제보다 눈에 띄기가 훨씬 더 어려웠습니다 ... ಠ_ಠ