실무에서 서버 작업을 하다보면
스프링을 이용해 영상 스트리밍 기능을 만들어야 할 때가 있다.
이때 , HTTP range requests를 활용하면 쉽게 기능 개발을 할 수 있다.
1. HTTP Range Requests 란?
HTTP 범위 요청이란 HTTP 를 통해 일정한 부분을 서버에서 클라이언트로 보내는 것을 Accept하고 보내는 방법입니다.
범위를 알 수 있는 대형 미디어 파일을 나누어서 읽을 수 있습니다. 파일 다운로드 도중 일시정지와 다시 시작 기능에 유용한 점을 이용해 클라이언트에선 미디어파일을 재생, 일시정지, 다시시작을 가능하게 만들 수 있습니다.
예를 들어 4.5mb짜리 파일을 받겠다하면, 서버는 전체 범위(Content-Length)와 일정 범위에 해당하는 파일을 bytes 로 내려보내줍니다.
2. Spring 을 이용한 HTTP Range Requests 처리
우선 소스코드는 다음과 같습니다.
@RequiredArgsConstructor
@Controller
public class VideoController {
Logger logger = LoggerFactory.getLogger(this.getClass());
private String url = "보여줄 비디오 url 경로";
@GetMapping(value = "/video/{name}")
public ResponseEntity<ResourceRegion> getVideo(@RequestHeader HttpHeaders headers, @PathVariable String name) throws IOException {
logger.info("VideoController.getVideo");
UrlResource video = new UrlResource("file:(기본 경로 입력)"+name+".mp4");
ResourceRegion resourceRegion;
final long chunkSize = 1000000L;
long contentLength = video.contentLength();
Optional<HttpRange> optional = headers.getRange().stream().findFirst();
HttpRange httpRange;
if (optional.isPresent()) {
httpRange = optional.get();
long start = httpRange.getRangeStart(contentLength);
long end = httpRange.getRangeEnd(contentLength);
long rangeLength = Long.min(chunkSize, end - start + 1);
resourceRegion = new ResourceRegion(video, start, rangeLength);
} else {
long rangeLength = Long.min(chunkSize, contentLength);
resourceRegion = new ResourceRegion(video, 0, rangeLength);
}
return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
.contentType(MediaTypeFactory.getMediaType(video).orElse(MediaType.APPLICATION_OCTET_STREAM))
.body(resourceRegion);
}
}
MediaTypeFactory를 통해 파일의 content-type의 유형을 가져오거나, 기본값으로 8 bit 스트림 유형인 APPLICATION_OCTET_STREAM 리턴합니다.
잘 보시면 body에 ResouceRegion 객체를 담아 보내는데요. ResourceRegion은 파일 객체의 Range 범위 만큼을 가져올 수 있는 스프링 코어 객체입니다.
그리고 처음 요청(else구문) 은 chunk 사이즈로 자른 시작값부터 청크 사이즈 만큼의 ResoureRegion을 return하고 그 다음 요청은 header에 담긴 range 범위만큼 짤라 보냅니다.
이렇게 하고 url 을 브라우저에서 입력해보면...
위 이미지와 같이 영상이 재생되는 것을 볼 수 있다.
로그를 보면 영상이 재생됨에 따라 해당 url로 다시 request를 요청하여 영상정보를 받아와서 재생한다는 것을 알 수 있다.
'Backend > Spring' 카테고리의 다른 글
Spring Batch TransactionManager 개념, 구현체 종류와 특징 (0) | 2023.02.28 |
---|---|
테스트 케이스 돌리니 TestEngine with ID 'junit-vintage' failed to discover tests 오류가 뜨는 경우 (0) | 2021.11.06 |
[Thymeleaf]HTML Form 태그로 서버에 Multipart 형식의 데이터 전송하기(+로그인 인증문제 해결) (0) | 2021.02.03 |
[Spring] 쉽게 익히는 JDBC Template 사용법 및 간단 예제 (0) | 2020.11.30 |
[Spring]AOP의 개념 및 적용 예제(공통관심사 처리하기) (1) | 2020.11.23 |