
비디오 업로드 전용 서버를 구축하면서 비디오 관리 도구로 Vimeo를 사용하기로 결정했다.
업로드 API를 가져다 사용하면서, 비동기식으로 최대한 고효율을 내고자 개발을 진행하던 중, Vimeo가 tus 프로토콜을 업로드할 때 권장한다고 했다.
그게 뭔데…? 대략적으로 알아보았다.
재개 가능한 업로드를 위한 새로운 오픈 프로토콜
tus 공식 홈페이지에 나와 있는 문구이다. 다양한 기능들을 제공하고 공식/비공식 구현들의 예제도 잘 나와있고, 다양한 언어 또한 지원한다고 한다. 아래는 공식 깃허브이다
https://github.com/orgs/tus/repositories
자세한 것은 https://tus.io/protocols/resumable-upload 을 참고
헤더들 중 핵심적인 것들을 살펴보면
Upload-Offset : 현재 전송된 offsetUpload-Length : 전체 파일 크기Tus-Version : 지원하는 프로토콜 버전 리스트Tus-Resumable : 현재 사용중인 프로토콜 버전Tus-Extension : 서버에서 지원하는 확장 리스트Tus-Max-Size : 파일 허용 크기X-HTTP-Method-Override : http 메서드 재정의HTTP 기반 프로토콜
: 기존에 사용하던 라이브러리, 프록시 및 방화벽을 이용하여 애플리케이션에 쉽게 통합할 수 있으며, 웹사이트에 직접 사용가능
검증된 프로토콜
: Vimeo, Google과 같이 유명 기업에서 피드백을 받으며 수많은 개선을 해왔기 때문
오픈 소스 기반 프로토콜
: 모든 소스코드가 github에 공개되어 있고, MIT License 이기 때문에 모두가 사용 가능
미니멀리즘 지향
: 개발자 편의를 위해 클라이언트와 서버 내 직접 구현해야 하는 코드를 최소화, dependency만 추가하면 누구나 쉽게 사용 가능
확장성
: 병렬 업로드, md5 checksum 비교 및 재개 업로드 만료 시간 적용과 같은 추가 기능 제공
지속적인 피드백
: 오픈 소스 기반 프로토콜이기 때문에 issue를 통해 꾸준히 피드백을 받고 있음
tus protocol 에 대한 이해를 돕고자 내가 사용한 Vimeo와 곁들여 설명해보자.
Vimeo 공식 API Reference 다. 자세한 것은 공식 홈페이지를 참고 바란다.
또한 HTTP 통신 요청 방법에 대한 개념은 알고 있다고 생각하도록 하겠다.
Vimeo는 현재 tus, post , pull 이 세 가지의 업로드 접근 방식을 지원하고 있으나, tus만 다루도록 하자.
요약하자면 3단계로 이루어진다.
살펴보도록 하자.
먼저, 아래와 같은 POST 요청을 Vimeo 서버에 보낸다.
POST https://api.vimeo.com/me/videos
-H 'Authorization: bearer <access_token>'
-H 'Content-Type: application/json'
-H 'Accept: application/vnd.vimeo.*+json;version=3.4'
그리고 Request Body에서 upload.approach 값을 tus로 설정하고, upload.size 값을 업로드할 비디오 파일의 크기를 byte로 전송한다.
{
"upload": {
"approach": "tus",
"size": "{size}"
}
}
tus protocol에서는upload.size가 필수이다. 절대 잊어버리면 안된다.
아래는 내가 보낸 예시이다.

그리고 나면, HTTP 200코드와 함께 upload.upload_link 에 사용자가 비디오 파일을 업로드해야 할 링크가 오고, uri 에 Vimeo에서 비디오가 어느 경로에 저장될지에 대한 경로가 같이 온다. 이렇게 Vimeo 계정을 확인해보면,

이런 식으로 비디오 껍데기가 생겨 있다.
전체 비디오 파일의 binary data를 방금 받아온 upload.upload_link에 PATCH메서드로 전송한다.
PATCH {upload.upload_link}
-H 'Tus-Resumable: 1.0.0' \
-H 'Content-Type: application/offset+octet-stream' \
-H 'Upload-Offset: 0' \
-H 'Authorization: bearer <access_token>'
-H 'Accept: application/vnd.vimeo.*+json;version=3.4'
Upload-Offset의 경우 초기값은 0이다. 이 Upload-Offset 은 처음에 입력했던 upload.size와 같아질 때까지 계속해서 Upload Pending 상태로 업로드 요청을 대기할 것이다. 그리고 비디오 파일의 binary data를 chunk 단위로 끊어서 전체 파일을 다 보낼 때까지 계속 해당 Request를 보내면 된다.
초기에는 0 → response header의 Upload-Offset 값으로 다시 헤더 설정해서 요청 → (반복…) → 어느순간 upload.size == Upload-Offset 이면, 업로드 종료. Optimizing을 시작한다.
tus를 사용하는 경우 128MB~512MB 정도의chunk사이즈를 권장한다.

이 단계는 사실 2번째 단계 진행중에 해야되는 단계이다.
HEAD {upload.upload_link}
-H 'Tus-Resumable: 1.0.0' \
-H 'Content-Type: application/json' \
-H 'Upload-Offset: 0' \
-H 'Authorization: bearer <access_token>'
-H 'Accept: application/vnd.vimeo.*+json;version=3.4'
Request Body의 내용이 빠진, 헤더만 받아와서 Upload-Offset값에 따른 업로드 진행도를 알아보기 위한 방식에 불과하기 떄문에 나는 거의 안썼다.
( + 업로드 진행도를 알기 위해서는 Upload-Offset / upload.size * 100 을 하면 진행도를 %로 나타낼 수 있을 것이다.)
확실히 예시를 들고 실제로 사용해보고 나니, 이해가 좀 더 잘되는 것 같다.
대용량 파일 업로드에 지금으로서는 가장 적합한 방식이라고 생각하고, 향후 파일 업로드 관련 서버를 외부 API 없이 직접 구축하게 된다면 반드시 고려해봐야 되는 기술이라고 생각한다.