긴 오디오 파일 텍스트 변환: 10분 단위로 나눠 전사하기

API로 긴 오디오를 전사하려면 최대 10분 길이의 조각으로 나눠 조각마다 전사한 뒤, 각 조각의 시작 시각을 그 조각의 타임스탬프에 더하세요.

읽는 시간 6분Sume
전체 글

한 시간짜리 팟캐스트나 강의처럼 긴 녹음을 텍스트로 전사하려면, 전사 API의 요청당 한도에 맞는 조각으로 나눠 조각마다 전사한 뒤, 각 조각의 시작 시각을 그 조각의 단어·문장 타임스탬프에 더해 전체 녹음과 맞추세요. Sume STT 1.0은 요청당 최대 10분을 명시하고 오디오 분당 $0.01로 과금하므로, 한 시간 분량의 오디오에는 요청이 최소 여섯 번 필요하고 비용은 에이전트 수수료 전 $0.60입니다.

STT 1.0은 Sume API 레퍼런스의 바탕이 되는 OpenAPI 문서에 명세되어 있으며, API 레퍼런스 문서 페이지는 정확한 요청·응답 형태의 기준으로 이 문서를 안내합니다. 모두 2026-09-27에 확인했습니다. 분할 명령은 FFmpeg Formats 문서를 따릅니다. 10분 미만의 파일 하나라면 단어별 타임스탬프를 주는 음성 인식 API를 참고하세요.

왜 요청 하나로 파일 전체를 전사할 수 없나요?

문서에 명시된 상한이 10분이기 때문입니다. STT 1.0이 더 긴 파일을 어떻게 처리하는지는 문서화되어 있지 않으므로, 조각을 10분 이하로 계획하세요.

Sume API 레퍼런스와 API 요금 기준 STT 1.0 한도, 2026-09-27 확인.
한도STT 1.0
요청당 오디오duration_seconds 범위는 1–600(“Maximum 10 minutes”). 가격 항목에도 “max 10 minutes”라고 적혀 있음.
입력요청당 공개 HTTPS audio_url 하나.
단어 타이밍항상 반환. words[]의 상한은 20,000개 항목이며, 600초 분량의 전사문은 이 상한에 한참 못 미침.
문장segmentation: { "mode": "sentence" }를 넣으면 빈틈없는 segments[]가 추가됨.
가격오디오 분당 $0.01. duration_seconds를 생략하면 Sume가 1분 기준으로 예약.

긴 오디오 파일은 어떻게 나누나요?

로컬 컴퓨터에서 나눈 뒤, 각 조각을 STT 1.0이 가져올 수 있는 공개 HTTPS URL에 올리세요. FFmpeg의 segment muxer는 “a number of separate files of nearly fixed duration”(거의 일정한 길이의 여러 개별 파일)을 만들고, .csv로 끝나는 목록 파일에는 조각마다 시작 시각과 끝 시각이 초 단위로 기록됩니다. 여유를 두려면 540처럼 600초보다 조금 짧게 지정하세요.

고정된 시간으로 자르면 단어 중간이 잘릴 수 있습니다. 이음매마다 양쪽 단어를 확인하거나, -segment_times로 분할 지점을 직접 넘겨 말이 멈춘 곳에서 자르세요.

녹음이 이미 Sume에 있는 영상의 오디오 트랙이라면, 조각마다 600초 이하의 range를 지정해 오디오 분리를 한 번씩 실행하세요. 문서는 channels: "mono"와 함께 쓰는 sample_rate: 16000을 STT 형태라고 부릅니다. 타임라인 오디오의 split은 Sume에 호스팅된 오디오 파일 하나를 Job 하나에서 최대 20개 구간으로 자릅니다.

ffmpeg -i episode.mp3 -codec copy -map 0 -f segment -segment_time 540 \
  -reset_timestamps 1 -segment_list parts.csv part%03d.mp3

각 조각은 어떻게 전사하나요?

조각마다 별도의 STT 1.0 Job으로 보내고, 사용량 예약이 조각 길이와 맞도록 duration_seconds를 그 조각의 길이로 설정하세요. language_code는 모든 조각에서 같게 두거나, 자동 감지를 쓰려면 생략하세요.

  • Idempotency-Key는 파일과 조각 번호로 만드세요. 같은 키와 본문으로 재시도하면 두 번째 Job을 과금하는 대신 원래 Job을 반환합니다.
  • 모든 조각을 한꺼번에 제출해도 됩니다. 현재 코드에서 STT Job은 각각 생성 동시성 슬롯 하나를 차지하며(슬롯을 차지하는 호출), 워크스페이스 한도를 넘는 Job은 queued 상태로 기다리고, 큐까지 넘는 제출에는 429 queue_full이 반환됩니다.
  • GET /v1/jobs/:id/status를 폴링한 다음 GET /v1/jobs/:id/result를 읽으세요. 이 경로는 Job이 끝날 때까지 409 job_not_completed로 응답합니다.
curl -X POST https://api.sume.com/v1/stt-1.0/transcribe \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: episode-42-part-002" \
  -d '{
    "audio_url": "https://example.com/audio/part002.mp3",
    "language_code": "en",
    "duration_seconds": 540,
    "segmentation": { "mode": "sentence" }
  }'

조각들을 타임스탬프가 있는 전사문 하나로 어떻게 합치나요?

모든 시각을 옮긴 뒤 조각을 순서대로 이으세요. 각 결과의 words[].start와 end, 그리고 각 segments[]의 시작과 끝은 전체 녹음이 아니라 그 조각 오디오의 시작부터 센 초입니다. 여기에 조각의 시작 시각을 더하세요. parts.csv의 두 번째 열, 또는 Sume에서 자른 구간의 start가 그 값입니다.

문장 구간은 한 조각 안에서 빈틈없이 이어지고 index는 조각마다 다시 시작하므로, 합친 뒤 번호를 다시 매기세요. 이음매가 문장 중간에 걸렸다면 한 조각의 마지막 구간과 다음 조각의 첫 구간이 한 문장의 두 반쪽일 수 있습니다.

// parts: [{ offset, result }] in recording order; offset = part start, in seconds
const shift = (offset) => (t) => ({ ...t, start: t.start + offset, end: t.end + offset });

const words = parts.flatMap(({ offset, result }) => result.words.map(shift(offset)));
const segments = parts
  .flatMap(({ offset, result }) => (result.segments ?? []).map(shift(offset)))
  .map((segment, index) => ({ ...segment, index }));
const text = parts.map(({ result }) => result.text.trim()).join(" ");

한 시간 분량의 오디오를 전사하면 비용은 얼마인가요?

$0.60입니다. API 요금에 나온 STT 1.0 요율인 오디오 분당 $0.01로 계산한 금액이며, 기본적으로 5.5% 에이전트 수수료가 더해집니다. 나눠서 보내도 분당 요율은 달라지지 않습니다. Sume는 제출할 때 예상 금액을 예약하며, 잔액이 이를 감당하지 못하면 제출은 402 insufficient_credits를 반환하고 Job은 시작되지 않습니다. 여러 파일을 한꺼번에 처리하려면 일괄 전사 API를 참고하세요.

출처

관련 글

미디어 도구 카테고리의 다른 글

미디어 도구 글 전체 보기

작성자 Sume