유튜브 API 상태는 uploaded 인데, 공개된 영상의 길이는 0이었습니다
자사 영상 콘텐츠 프로젝트는 영상을 API 로 올리고 공개 시각을 예약해 둡니다. 그렇게 공개된 영상 한 편이 이틀 동안 재생할 내용이 없는 채로 올라가 있었습니다.
API 의 상태값은 uploaded 였습니다. 영상이 비어 있다는 사실은 길이 값을 보고서야 알 수 있었습니다.
왜 끊겼는지는 지금도 모릅니다. 이 글은 무엇을 봐야 했는지, 그리고 두 편을 어떻게 복구했는지를 적은 기록입니다.
스튜디오 목록에 '업로드 중'이 두 개 남아 있었습니다
알아챈 것은 사람이었습니다. 유튜브 스튜디오 목록을 보다가 '업로드 중'으로 남아 있는 영상 두 개를 발견했습니다. 한 편은 이틀 전에 공개된 영상이었고, 다른 한 편은 며칠 뒤 공개로 예약된 영상이었습니다.
API 로 조회하니 두 편 모두 길이가 P0D 였습니다. 유튜브 API 의 contentDetails.duration(영상 길이를 ISO 8601 기간 표기로 주는 값)에서 P0D 는 길이 0을 뜻합니다. 길이가 11분 19초인 영상은 PT11M19S 로 표시됩니다.
구분 | 공개된 편 | 예약된 편 |
|---|---|---|
발견 당시 상태 | 이틀 전 공개 | 공개 예약 유지 중 |
길이 | P0D | P0D |
끊긴 지점 | 업로드 48% | 업로드 40% |
스튜디오 목록 표시 | 업로드 중 | 업로드 중 |
공개된 편은 이틀 동안 시청자에게 보여 줄 내용이 없었고, 조회는 0이었습니다.

uploaded 라는 값으로는 고장을 구분할 수 없었습니다
이름만 보면 uploadStatus 는 업로드가 끝났는지 알려 주는 값입니다. 그런데 이 값이 uploaded 인 영상이 비어 있었습니다.
온전한 영상도 끊긴 영상도 uploaded 로 나온다면, 이 값으로는 둘을 구분할 수 없습니다. 정상일 때와 고장 났을 때 똑같이 보이는 값은 확인 수단이 되지 못합니다. 이번에 영상이 비어 있는지 판단할 수 있었던 값은 길이였습니다.
믿을 수 없었던 값 uploadStatus = uploaded
판단에 쓴 값 contentDetails.duration = P0D 인가같은 방법을 썼는데 결과가 달랐습니다
예약된 편부터 복구했습니다. '이어 올리기'(끊긴 업로드를 기존 업로드 주소로 계속 보내는 방식)를 썼습니다.
기존 업로드 주소에 같은 파일을 넣으니 길이가 PT11M19S(11분 19초)가 됐고 succeeded 로 끝났습니다. 영상 주소도 공개 예약 시각도 그대로 유지됐습니다.
공개된 편도 같은 방식으로 이어 올렸습니다. 이번에는 '대기 중'에서 멈췄습니다.
그래서 같은 파일로 새 업로드를 시도했습니다. 유튜브는 이 업로드를 옛 영상으로 되돌려 보냈습니다. 같은 파일을 두 번 받지 않는 동작으로 보였습니다.
마지막으로 ffmpeg -c copy(다시 인코딩하지 않고 영상과 소리 데이터를 그대로 복사하는 옵션)로 크기만 다른 사본을 만들어 올렸습니다. 화면과 소리는 그대로입니다. 새 영상이 바로 공개됐고 길이는 PT7M46S(7분 46초)였습니다.
새 영상이 공개된 뒤 옛 영상은 API 로 삭제했습니다. 조회가 0이어서 삭제로 잃은 조회 수는 없었습니다.

복구 방법마다 따라오는 일이 달랐습니다
복구 방법 | 결과 | 영상 주소 | 따라온 일 |
|---|---|---|---|
이어 올리기 | 예약된 편은 복구, 공개된 편은 멈춤 | 유지 | 없음 |
같은 파일로 새 업로드 | 옛 영상으로 되돌려 보내짐 | 해당 없음 | 선택지가 되지 못함 |
크기만 다른 사본으로 새 업로드 | 새 영상 바로 공개 | 바뀜 | 주소가 쓰인 자리를 전부 다시 연결 |
비용 차이는 영상 주소에서 나왔습니다. 이어 올리기는 주소가 그대로여서 따라오는 작업이 없었습니다. 공개된 편은 주소가 바뀌어서 아래 일을 새 영상 기준으로 다시 해야 했습니다.
쇼츠 4개의 설명란 링크
쇼츠의 관련 동영상 연결
썸네일 A/B 비교
알아챈 뒤 두 편을 모두 고치는 데 60분이 들었습니다. 이 경험으로 복구 순서가 정해졌습니다. 주소가 유지되는 방법부터 시도하고, 주소가 바뀌는 방법은 마지막에 씁니다. 옛 영상 삭제는 새 영상이 공개된 뒤에 합니다.
판단 기준과 성적 처리를 고쳤습니다
영상이 비어 있는지는 이제 uploadStatus 가 아니라 contentDetails.duration 이 P0D 인지로 판단합니다. 이 내용을 제작 작업 지시문의 '틀린 사례' 목록에 넣었습니다.
성적 처리도 고쳤습니다. 공개된 편의 공개 3일째 성적에는 영상이 비어 있던 이틀이 섞여 있습니다. 그 숫자를 그대로 쓰면 영상의 성적이 아니라 업로드 사고를 측정한 값이 됩니다.
그래서 3일째 성적을 판단 재료에서 뺐고, 전략 담당 세션에도 그렇게 알렸습니다. 영상을 고친 뒤에도 그 숫자는 남으므로, 뺐다는 사실까지 기록해 둡니다.
상태값은 시스템의 보고이고, 결과물은 따로 확인합니다
'끝났다'는 표시와 실제로 끝난 것은 서로 다른 사실입니다. 월간 검수 배치가 매달 성공으로 끝났는데 판정 범위 밖의 누락은 한 번도 보지 않았던 일도 모양이 같았습니다.
그래서 결과물 자체의 값을 따로 봅니다. 무엇을 볼지는 결과물마다 다릅니다.
영상은 길이
파일은 크기와 내용
데이터 이관은 건수
확인 항목을 고를 때는 '고장 나면 이 값이 달라지나'를 먼저 묻습니다. 달라지지 않는 값이면 몇 번을 조회해도 같은 답이 나옵니다.
재시도 절차에서도 알게 된 것이 있습니다. 같은 파일을 두 번 받지 않는 동작은 평소엔 고마운 기능입니다. 앞선 업로드가 비어 있을 때는 그 동작이 재시도를 가로막았습니다. 재시도 절차를 만들 때는 같은 입력을 다시 넣으면 시스템이 어떻게 받는지까지 봅니다.

이 글이 답하지 못하는 것
이번 일에서 확인하지 못한 것이 많습니다. 두 건을 관찰한 기록이어서 유튜브의 공식 동작이라고 단정할 수 없습니다.
업로드가 40%대에서 멈춘 원인은 기록에 없습니다. 그때 알아채지 못한 이유도 알지 못합니다
이어 올리기가 한 건은 되고 한 건은 멈춘 이유도 확인하지 못했습니다. '공개 상태라서 안 된다'고 말할 근거는 없습니다
유튜브가 무엇으로 같은 파일이라고 판단하는지 모릅니다. 크기가 다른 사본이 통과했다는 사실만 있고, 앞으로도 이 방법이 통한다는 보장은 없습니다
P0D 가 끊긴 업로드만 뜻하는지도 확인하지 않았습니다. 업로드 직후 처리 중인 영상도 같은 값일 수 있습니다(추정). 올린 직후 한 번 보고 고장으로 판단하지 않고, 시간을 두고 다시 봅니다
삭제가 쉬웠던 것은 조회가 0이었기 때문입니다. 조회와 댓글이 쌓인 영상이었다면 옛 영상을 지우는 부담이 훨씬 컸을 겁니다
영상 업로드를 자동화했다면 점검할 것
업로드가 끝났는지를 상태값만으로 판단하지 않고, 길이처럼 고장 나면 달라지는 결과물의 값을 함께 보는가
올린 직후 한 번으로 끝내지 않고, 시간을 두고 다시 확인하는가
복구 순서를 영상 주소가 유지되는 방법부터 정해 두었는가
영상 주소가 바뀔 때 다시 연결할 자리(링크·관련 동영상·비교 실험)를 목록으로 갖고 있는가
고장 난 기간의 성적을 판단에서 빼고, 뺐다는 사실을 기록하는가
두 편은 복구했고, 원인은 아직 모릅니다
공개된 편은 새 영상으로 바뀌었고, 예약된 편은 예약 시각을 그대로 지켰습니다. 끊긴 원인은 여전히 알지 못합니다. 바뀐 것은 업로드가 끝났는지를 판단하는 값입니다. 지금은 상태값 대신 영상 길이를 봅니다.