영상 스트리밍 #6. 스트리밍

Bobby·2023년 3월 12일
0

streaming

목록 보기
6/9

테스트 영상은 여기서 다운받았다.

업로드 한 영상을 재생 해보자.

🎥 스트리밍 하기

  • 스트리밍 할 영상

📺 영상 응답

  • 해당 영상 파일의 Resource를 전달한다.
  • ContentType을 헤더에 전달해준다.(mp4의 MimeType은 video/mp4 이다)

VodController

@Controller
public class VodController {

    @Value("${tus.save.path}")
    private String savedPath;

    @ResponseBody
    @GetMapping("/vod/{date}/{filename}")
    public ResponseEntity<Resource> resource(
            @PathVariable String date,
            @PathVariable String filename
    ) throws IOException {
        String path = savedPath + "/" + date + "/" + filename;
        Resource resource = new FileSystemResource(path);

        return ResponseEntity.ok()
                .contentType(MediaTypeFactory.getMediaType(resource).orElse(MediaType.APPLICATION_OCTET_STREAM))
                .contentLength(resource.contentLength())
                .body(resource);
    }
}

실행

GET http://localhost:8080/vod/{date}/{filename}

  • 크롬 브라우저의 경우 video/mp4타입을 재생시켜준다.
  • 브라우저가 알아서 분할요청 해준다.

📺 chunk size 지정

  • 영상을 응답할 때 chunk size를 지정하여 전달 할 수 있다.
@Controller
public class VodController {

    @Value("${tus.save.path}")
    private String savedPath;

    @ResponseBody
    @GetMapping("/vod/chunk/{date}/{filename}")
    public ResponseEntity<ResourceRegion> chunkResource(
            @RequestHeader HttpHeaders headers,
            @PathVariable String date,
            @PathVariable String filename
    ) throws IOException {

        String path = savedPath + "/" + date + "/" + filename;
        Resource resource = new FileSystemResource(path);

        long chunkSize = 1024 * 1024;
        long contentLength = resource.contentLength();


        HttpRange httpRange = headers.getRange().stream().findFirst()
                .orElse(HttpRange.createByteRange(0, contentLength - 1));

        long rangeLength = calculateRangeLength(httpRange, contentLength, chunkSize);
        ResourceRegion region = new ResourceRegion(resource, httpRange.getRangeStart(contentLength), rangeLength);

        return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
                .cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES))
                .contentType(MediaTypeFactory.getMediaType(resource).orElse(MediaType.APPLICATION_OCTET_STREAM))
                .header("Accept-Ranges", "bytes")
                .eTag(path)
                .body(region);
    }

    private long calculateRangeLength(HttpRange httpRange, long contentLength, long chunkSize) {
        long start = httpRange.getRangeStart(contentLength);
        long end = httpRange.getRangeEnd(contentLength);
        return Long.min(chunkSize, end - start + 1);
    }
}

실행

  • 지정했던 1MB씩 분할하여 전송했다.

📺 video 태그 이용하여 재생

  • video 태그 src에 영상 소스를 입력한다.
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Uploaded vod</title>
</head>
<body>
<div style="display: flex; align-items: start">
    <div>
        <h3>normal</h3>
        <video src="http://localhost:8080/vod/2023-03-12/f0704db526574661885e1ed87f3fa745.mp4"
               width="360px"
               height="240px"
               autoplay
               muted
               controls>
        </video>
    </div>
    <div>
        <h3>chunk</h3>
        <video src="http://localhost:8080/vod/chunk/2023-03-12/f0704db526574661885e1ed87f3fa745.mp4"
               width="360px"
               height="240px"
               autoplay
               muted
               controls>
        </video>
    </div>

</div>
</body>
</html>

실행


코드

profile
물흐르듯 개발하다 대박나기

0개의 댓글