Google API에 재개 가능한 업로드 프로토콜을 사용하면 동영상을 보다 안정적으로 업로드할 수 있습니다. 이 프로토콜은 네트워크 중단 또는 기타 전송 실패 후 업로드 작업을 재개할 수 있게 해주므로, 네트워크 오류가 발생할 때 시간과 대역폭을 절약할 수 있습니다.
특히 다음과 같은 경우 재개 가능한 업로드를 사용하면 유용합니다.
- 용량이 큰 파일을 전송하는 경우
- 네트워크가 중단될 가능성이 높은 경우
- 휴대기기와 같은 대역폭이 낮거나 인터넷 연결이 불안정한 기기에서 업로드를 시작하는 경우
이 가이드에서는 재개 가능한 업로드 절차를 사용하여 동영상을 업로드하기 위해 애플리케이션이 생성하는 HTTP 요청의 순서를 설명합니다. 이 가이드는 기본적으로 일부분에서 재개 가능한 업로드에 대한 기본적인 지원을 제공하는 Google API 클라이언트 라이브러리를 사용할 수 없는 개발자를 위해 제작되었습니다. YouTube Data API – 동영상 업로드 가이드에서는 재개 가능한 업로드 절차를 사용하여 동영상을 업로드하기 위해 Python용 Google API 클라이언트 라이브러리를 사용하는 방법을 설명합니다.
참고: 또한 HTTPS 로깅을 사용하도록 설정한 Google API 클라이언트 라이브러리 중 하나를 통해 재개 가능한 업로드에 대한 일련의 요청 또는 기타 API 작업을 확인할 수 있습니다. 예를 들어 Python에 HTTP Trace 메소드를 사용하도록 설정하려면 다음과 같이 httplib2
라이브러리를 사용하세요.
httplib2.debuglevel = 4
1단계 - 재개 가능한 세션 시작
재개 가능한 동영상 업로드를 시작하려면 다음과 같은 URL에 POST
요청을 전송합니다. part
매개 변수는 두 가지 목적을 제공합니다. 쓰기 연산에서 설정하는 속성과 API 응답에서 포함하는 속성을 식별>합니다. 매개 변수 값은 URL 인코딩해야합니다.
https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=PARTS
요청 본문을 video
리소스로 설정하고 다음 HTTP 요청 헤더도 설정합니다.
Authorization
– 요청에 대한 인증 토큰입니다.Content-Length
– 요청 본문에 제공된 바이트 수입니다. Chunked Transfer Encoding을 사용하는 경우 이 헤더를 제공할 필요가 없습니다.Content-Type
– 값을application/json; charset=UTF-8
로 설정합니다.X-Upload-Content-Length
– 다음 요청에 업로드될 바이트 수입니다. 값은 업로드하는 파일의 크기로 설정합니다.x-upload-content-type
– 업로드하는 파일의 MIME 유형입니다. 모든 MIME 형식(video/*
)의 동영상 파일 또는application/octet-stream
의 MIME 형식 파일을 업로드할 수 있습니다.
다음 예는 동영상을 업로드할 때 재개 가능한 세션을 시작하는 방법을 보여줍니다. 요청은 video
리소스의 snippet
및 status
부분에 있는 속성을 설정하고 검색하며, 리소스의 contentDetails
부분에 있는 속성도 검색합니다.
post /upload/youtube/v3/videos?uploadtype=resumable&part=parts http/1.1 host: www.googleapis.com authorization: bearer auth_token content-length: content_length content-type: application/json; charset=utf-8 x-upload-content-length: x_upload_content_length X-Upload-Content-Type: X_UPLOAD_CONTENT_TYPE video resource
다음 예는 인증 토큰의 예외로 채워진 위의 값을 모두 포함한 POST
요청을 보여줍니다. 예에 표시된 categoryId
값은 동영상 카테고리에 해당합니다. 지원되는 카테고리 목록은 API의 videoCategories.list
메소드를 사용하여 검색할 수 있습니다.
POST /upload/youtube/v3/videos?uploadType=resumable&part=snippet,status,contentDetails HTTP/1.1 Host: www.googleapis.com Authorization: Bearer AUTH_TOKEN Content-Length: 278 Content-Type: application/json; charset=UTF-8 X-Upload-Content-Length: 3000000 X-Upload-Content-Type: video/* { "snippet": { "title": "My video title", "description": "This is a description of my video", "tags": ["cool", "video", "more keywords"], "categoryId": 22 }, "status": { "privacyStatus": "public", "embeddable": True, "license": "youtube" } }
2단계 - 재개 가능한 세션 URI 저장
요청이 성공하면 API 서버는 200
(OK
) HTTP 상태 코드로 응답하며, 응답에는 재개 가능한 세션의 URI를 지정하는 Location
HTTP 헤더가 포함됩니다. 동영상 파일을 업로드할 때 이 URI를 사용합니다.
다음 예는 1단계의 요청에 대한 샘플 API 응답을 보여줍니다.
HTTP/1.1 200 OK Location: https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&upload_id=xa298sd_f&part=snippet,status,contentDetails Content-Length: 0
3단계 - 동영상 파일 업로드
API 응답에서 세션 URI를 추출한 후 해당 위치로 실제 동영상 파일 콘텐츠를 업로드해야 합니다. 요청 본문은 업로드하는 동영상의 바이너리 파일 콘텐츠입니다. 다음 예는 요청 형식을 보여줍니다.
PUT UPLOAD_URL HTTP/1.1 Authorization: Bearer AUTH_TOKEN Content-Length: CONTENT_LENGTH Content-Type: CONTENT_TYPE BINARY_FILE_DATA
요청은 다음과 같은 HTTP 요청 헤더를 설정합니다.
Authorization
– 요청에 대한 인증 토큰입니다.Content-Length
– 업로드하는 파일의 크기입니다. 이 값은 1단계의X-Upload-Content-Length
HTTP 요청 헤더와 같은 값이어야 합니다.Content-Type
– 업로드하는 파일의 MIME 유형입니다. 이 값은 1단계의X-Upload-Content-Type
HTTP 요청 헤더와 같은 값이어야 합니다.
4단계 - 업로드 절차 완료
요청으로 인해 다음 시나리오 중 하나가 발생하게 됩니다.
-
업로드가 성공적으로 완료됩니다.
API 서버가 HTTP
201
(Created
) 응답 코드로 응답합니다. 응답 본문은 직접 작성한video
리소스입니다. -
업로드하지 못했지만, 재개할 수 있습니다.
다음과 같은 경우 업로드를 재개할 수 있습니다.
-
애플리케이션과 API 서버 간의 연결이 끊어져서 요청이 중단되었습니다. 이 경우 API 응답을 받지 않습니다.
-
API 응답에서 다음
5xx
응답 코드 중 하나를 지정합니다. 이러한 응답 코드를 받은 후 업로드를 재개할 때 코드는 지수 백오프 전략을 사용해야 합니다.500
–Internal Server Error
502
–Bad Gateway
503
–Service Unavailable
504
–Gateway Timeout
업로드를 재개하려면 아래의 업로드 상태 확인 및 업로드 재개 관련 지침을 따르세요. 각 재개 가능한 세션 URI의 수명은 유한하며 결국 만료됩니다. 따라서 세션 URI를 받는 즉시 재개 가능한 업로드를 시작하거나 중단이 발생한 후 빠른 시간 내에 중단된 업로드를 재개하는 것이 좋습니다.
-
-
업로드에 영구적으로 실패했습니다.
업로드에 실패한 경우 응답에 실패의 원인을 설명하는 오류 응답이 포함되어 있습니다. 영구적으로 실패한 업로드는 API 응답에 위에 나열된 응답 코드가 아닌
4xx
응답 코드 또는5xx
응답 코드가 포함됩니다.만료된 세션 URI를 사용하여 요청을 전송하는 경우 서버는
404
HTTP 응답 코드(Not Found
)를 반환합니다. 이 경우 재개 가능한 업로드를 새로 시작하고 새 세션 URI를 받아 새 URI를 사용해 처음부터 업로드를 시작해야 합니다.
4.1단계: 업로드 상태 확인
중단된 재개 가능한 업로드의 상태를 확인하려면 2단계에서 검색했고 3단계에서도 사용한 업로드 URL에 빈 PUT
요청을 전송합니다. 요청 내에 Content-Range
헤더 값을 bytes */CONTENT_LENGTH
로 설정하며, CONTENT_LENGTH는 업로드하는 파일의 크기입니다.
PUT UPLOAD_URL HTTP/1.1 Authorization: Bearer AUTH_TOKEN Content-Length: 0 Content-Range: bytes */CONTENT_LENGTH
4.2단계: API 응답 처리
업로드가 이미 완료된 경우 업로드 성공 또는 실패 여부에 관계없이 API는 업로드가 처음 완료되었을 때 전송했던 것과 동일한 응답을 반환합니다.
하지만 업로드가 중단되었거나 아직 진행 중인 경우 API 응답에는 HTTP 308
(Resume Incomplete
) 응답 코드가 포함됩니다. 응답에서 Range
헤더는 성공적으로 업로드된 파일의 바이트 수를 지정합니다.
- 헤더 값은
0
에서부터 색인이 생성됩니다. 이에 따라 헤더 값이0-999999
이면 파일의 첫 번째1,000,000
바이트가 업로드되었음을 나타냅니다. - 아직 업로드된 항목이 없는 경우 API 응답에
Range
헤더가 포함되지 않습니다.
아래 샘플 응답은 재개 가능한 업로드와 관련된 API 응답의 형식을 보여줍니다.
308 Resume Incomplete Content-Length: 0 Range: bytes=0-999999
API 응답에 Retry-After
헤더도 포함된 경우 이 헤더 값을 사용하여 업로드 재개 시기를 결정하세요.
4.3단계: 업로드 재개
업로드를 재개하려면 2단계에서 얻은 업로드 URL에 다른 PUT
요청을 전송합니다. 요청 본문을 아직 업로드되지 않은 동영상 파일의 일부분과 관련된 바이너리 코드로 설정합니다.
PUT UPLOAD_URL HTTP/1.1 Authorization: Bearer AUTH_TOKEN Content-Length: REMAINING_CONTENT_LENGTH Content-Range: bytes FIRST_BYTE-LAST_BYTE/TOTAL_CONTENT_LENGTH PARTIAL_BINARY_FILE_DATA
다음과 같은 HTTP 요청 헤더를 설정해야 합니다.
-
Authorization
– 요청에 대한 인증 토큰입니다. -
Content-Length
– 아직 업로드되지 않은 콘텐츠의 크기(바이트)입니다. 파일의 나머지 부분을 업로드하는 경우 이 값을 계산하려면TOTAL_CONTENT_LENGTH
값에서FIRST_BYTE
값을 빼면 됩니다. 두 가지 값 모두Content-Range
헤더에 사용됩니다. -
Content-Range
– 업로드하는 파일의 부분입니다. 헤더 값은 다음 세 가지 값으로 구성됩니다.-
FIRST_BYTE
– 바이트 숫자에 대해 0을 기준으로 표시한 숫자 색인으로 여기서부터 업로드를 재개하게 됩니다. 이 값은 이전 단계에서 검색한Range
헤더에 있는 두 번째 숫자보다 하나 큰 숫자입니다. 이전 예에서Range
헤더의 값은0-999999
였으므로, 이 다음에 재개되는 업로드의 첫 번째 바이트는1000000
이 됩니다. -
LAST_BYTE
– 업로드하는 바이너리 파일의 마지막 바이트와 관련된 0을 기준으로 한 숫자 색인입니다. 일반적으로 이것이 파일의 마지막 바이트입니다. 그러므로 예를 들어 파일 크기가3000000
바이트인 경우 파일의 마지막 바이트에 해당하는 숫자는2999999
가 됩니다. -
TOTAL_CONTENT_LENGTH
– 동영상 파일의 전체 크기(바이트)입니다. 이 값은 원래 업로드 요청에 지정된Content-Length
헤더와 같습니다.
참고: 비연속 바이너리 파일 블록은 업로드할 수 없습니다. 비연속 블록을 업로드하려고 하면 나머지 바이너리 콘텐츠가 전혀 업로드되지 않습니다.
따라서 재개된 업로드에서 업로드되는 첫 번째 바이트는 YouTube에 성공적으로 업로드된 마지막 바이트의 다음 바이트여야 합니다. 4.2단계의Range
헤더와 관련된 설명을 참조하세요.
그러므로Range
헤더의 마지막 바이트가999999
라면 업로드 재개 요청의 첫 번째 바이트는 1000000이 되어야 합니다. (두 가지 숫자 모두 0을 기반으로 한 색인을 사용합니다.) 999999바이트 이하(바이트 중복)에서 또는 1000001바이트 이상(바이트 건너뛰기)에서 업로드 재개를 시도하면 바이너리 콘텐츠가 전혀 업로드되지 않습니다. -
파일을 분할하여 업로드
네트워크 중단이 발생할 때 전체 파일을 업로드하려고 시도하거나 업로드를 재개하려고 시도하는 대신 애플리케이션에서 파일을 청크 단위로 분할하고 일련의 요청을 전송하여 분할된 파일(청크)을 순서대로 업로드할 수 있습니다. 이 방법을 사용해야 하는 경우는 거의 없으며 성능에 영향을 미치는 추가 요청을 필요로 하기 때문에 실제로 권장되지는 않습니다. 하지만 매우 불안정한 네트워크에 진행 상태 표시기를 표시하려는 경우에는 유용할 수도 있습니다.
파일을 분할하여 업로드하는 것과 관련된 지침은 이 가이드의 앞부분에서 설명한 4단계 절차와 거의 동일합니다. 하지만 파일이 분할되어 업로드되면 파일 업로드를 시작하기 위한 요청(위의 3단계) 및 업로드 재개 요청(위의 4.3단계) 모두 Content-Length
및 Content-Range
헤더 값을 다르게 설정합니다.
-
Content-Length
헤더 값은 요청이 전송하는 청크 파일의 크기를 지정합니다. 청크 파일 크기에 적용되는 다음 제한 사항을 참조하세요.-
청크 파일의 크기는 256 KB의 배수여야 합니다. 전체 파일 크기는 256 KB의 배수가 아닐 수도 있기 때문에 마지막 청크 파일에는 이 제한 사항이 적용되지 않습니다. 청크 파일이 클수록 더 효율적입니다.
-
청크 파일 크기는 업로드 순서의 각 요청에 대해 동일해야 하며, 마지막 청크 파일의 크기를 지정하는 마지막 요청은 예외입니다.
-
-
Content-Range
헤더는 요청이 업로드하는 파일의 바이트를 지정합니다. 이 값을 설정할 때 4.3단계의Content-Range
헤더 설정과 관련된 지침을 참조하세요.예를 들어
bytes 0-524287/2000000
값은 요청이 2,000,000바이트인 파일에서 첫 번째 524,288바이트(256 x 2048)를 전송 중임을 나타냅니다.
아래 예는 2,000,000바이트 파일을 분할하여 업로드하는 일련의 요청 중 첫 번째 요청의 형식을 보여줍니다.
PUT UPLOAD_URL HTTP/1.1 Authorization: Bearer AUTH_TOKEN Content-Length: 524888 Content-Type: video/* Content-Range: bytes 0-524287/2000000 {bytes 0-524287}
마지막 요청을 제외한 나머지 요청이 성공하면 API 서버는 308
(Resume Incomplete
) 응답 코드로 응답합니다. 응답 형식은 위의 4.2단계: API 응답 처리에 설명된 것과 같습니다.
API 응답의 Range
헤더에 반환된 위의 값을 사용하여 다음 청크 파일 업로드를 시작할 위치를 결정하세요. 4.3단계: 업로드 재개에서 설명한 대로 계속해서 PUT
요청을 전송하여 전체 파일이 업로드될 때까지 다음 청크 파일 업로드를 반복합니다.
전체 파일이 업로드되면 서버는 201
HTTP 응답 코드(Created
)로 응답하며 새롭게 만들어진 동영상 리소스의 요청 부분을 반환합니다.
요청이 중단되었거나 애플리케이션이 5xx
응답 코드를 수신하면 4단계에 설명된 절차에 따라 업로드를 완료합니다. 하지만 나머지 파일을 업로드하려고 하는 대신 업로드를 재개하는 위치에서부터 청크 파일을 계속 업로드하세요. 파일 업로드를 재개할 위치를 결정하기 위해 업로드 상태를 계속 확인해야 합니다. 서버가 이전 요청에서 전송한 바이트를 모두 받았거나 전혀 받지 않았다고 가정하지 마세요.
참고: 또한 업로드된 청크 파일 간의 활성 업로드 상태를 요청할 수도 있습니다. (업로드 항목은 상태를 검색할 수 있기 전에는 중단되지 않습니다.)