영상 파일의 정보창에 AAC 오디오가 표시되어도, 그 안에 확인하려던 대사나 효과음이 들어 있다는 뜻은 아닙니다. 합성 영상에 소리를 붙였다고 생각했는데 재생하면 조용한 경우라면, 먼저 오디오 트랙의 존재와 신호 검사를 나누는 편이 좋습니다. 이 글은 두 검사가 무엇을 각각 알려주는지, 같은 영상으로 만든 세 파일을 측정해 보여줍니다.
2026년 10월 14일 저녁, 오늘 공개를 마친 우리 소유의 AI 캐릭터 영상 파일 하나를 새로 분석했습니다. 원본의 영상과 효과음은 우리 제작물입니다. 원본은 그대로 보존하고, 영상 데이터를 다시 압축하지 않은 파생본 두 개를 로컬에서 만들었습니다. 하나는 오디오를 제거했고, 다른 하나는 값이 0인 디지털 샘플을 AAC로 압축해 붙였습니다. 영상이나 소리 파일은 이 글에 올리지 않습니다. 아래 결과는 오늘 새 명령으로 얻은 파일 검사이며, 이전 작품 검수나 새 청취 결과를 가져온 것이 아닙니다.
무엇을 바꿨고, 무엇을 측정했나요?
원본, 오디오 제거본, 무음 AAC 대조군 모두 영상 스트림은 같은 367프레임입니다. 파일에 표시된 길이는 약 15.292초입니다. 오디오 제거본에는 음성 스트림이 없고, 무음 대조군에는 48,000Hz 스테레오 AAC 스트림이 있습니다. 대조군은 조용하게 들렸다는 감상으로 만든 것이 아니라, 처음부터 0인 샘플을 생성한 실험 조건입니다. 원본 오디오는 모노이므로 대조군과 채널 수까지 동일한 실험은 아닙니다.
첫 검사는 ffprobe의 -show_streams로 스트림 정보를 읽는 것입니다. 두 번째 검사는 실제로 디코딩한 오디오를 기준으로 했습니다. 오디오가 있는 두 파일을 16,000Hz 모노, 부호 있는 16비트 PCM으로 바꿔 샘플 수와 무음 구간을 확인했습니다. 파일에 표시된 시간과 디코딩 후 샘플 수를 각각 읽었고, 이번 원본에서는 두 길이가 일치하지 않았습니다. 그래서 무음 비율의 분모는 컨테이너 시간이 아닌 실제 디코딩 길이로 정했습니다. 길이가 달라진 원인을 별도로 분리해 시험한 것은 아닙니다.
무음 검출 설정은 silencedetect=noise=-45dB:d=0.1입니다. 소리가 지정한 기준 이하로 0.1초 이상 이어진 구간을 무음으로 검출합니다. 이 값은 이번 비교의 검사 설정일 뿐, 유튜브나 인스타그램의 합격 기준이 아닙니다. 다른 기준이나 최소 시간을 쓰면 검출 구간도 달라질 수 있습니다.
오디오 스트림은 같아도 결과는 달랐습니다
| 파일 조건 | 오디오 스트림 | 파일 표시 길이 | 디코딩 길이 | 검출된 무음 합계 | 검출 무음에 포함되지 않은 시간 |
|---|---|---|---|---|---|
| 원본 | AAC 1개 | 15.292초 | 15.283초 | 12.217초 | 3.066초 |
| 오디오 제거 | 없음 | 15.292초 | 해당 없음 | 해당 없음 | 해당 없음 |
| 0 샘플로 만든 AAC 대조군 | AAC 1개 | 15.292초 | 15.292초 | 15.292초 | 0.000초 |
표는 소수 셋째 자리까지 반올림했습니다. 세 파일의 컨테이너 표시 길이는 15.291667초입니다. 원본의 PCM은 244,533개 샘플이며, 16,000Hz에서 디코딩 길이는 15.2833125초, 무음 합계는 12.216936초이고, 그 차이는 3.0663765초입니다. 무음 대조군의 디코딩 길이는 15.2916875초였습니다. 오디오가 없는 파일은 무음을 0초로 측정한 것이 아닙니다. 검사할 음성 스트림 자체가 없기 때문에 해당 없음으로 표시했습니다.
원본과 무음 대조군은 둘 다 AAC 스트림 한 개를 갖고 있었습니다. 그러나 대조군을 16비트 PCM으로 디코딩했을 때 전체 244,667개 샘플이 0이었고, 위 설정에서는 전 구간이 무음으로 검출됐습니다. 이 대조군은 만들어진 0 샘플을 검출하는지 확인한 조건입니다. 원본과 같은 AAC 인코더 동작이나 사람에게 들리는 정도를 비교한 대조군은 아닙니다. 오디오 스트림 정보만으로는 이 신호 차이까지 알 수 없습니다.
3.066초를 ‘소리가 들린 시간’이라고 부르면 안 되는 이유
표의 마지막 열은 디코딩한 전체 길이에서 검출된 무음 구간의 합집합을 뺀 값입니다. 겹치는 구간은 합치고, 구간 끝은 실제 디코딩 길이에 맞췄습니다. 하지만 최소 길이인 0.1초보다 짧은 조용한 부분은 무음 구간으로 잡히지 않을 수 있습니다. 따라서 남은 시간을 모두 사람이 분명히 들은 시간이라고 확정할 수 없습니다.
이 차이는 별도 파이썬 샘플 계산에서도 나타났습니다. 무음 검출기에 넣었던 바로 그 원본 PCM 파일을 읽었지만, 이 계산은 필터의 내부 통계를 추출한 것이 아닙니다. 16비트 최대 범위 32,768을 기준으로 계산한 −45dBFS의 진폭은 약 184.27입니다. 절댓값이 이 기준을 넘은 샘플은 43,718개였고, 16,000Hz에서 2.732375초에 해당합니다. 이 값도 청취 결과는 아닙니다. 샘플별 기준 초과 시간을 합한 값과, 최소 구간 길이를 적용한 무음 검출의 나머지는 서로 다른 계산이라는 뜻입니다.
이번에 다룬 파일은 한 원본과 의도적으로 만든 두 대조군뿐입니다. 새로 전편을 듣고 대사 명료도나 효과음의 적합성을 평가하지 않았습니다. 작은 잡음이 기준을 넘는 경우, 좌우 채널을 합치면서 신호가 달라지는 경우, 조용하지만 필요한 효과음이 있는 경우까지 한 수치로 판정할 수 없습니다. 무음 비율이 높다는 이유만으로 작품이 나쁘다고 하거나, 무음이 적다는 이유로 좋은 소리라고 말하지 않습니다.
내보낸 파일에서 같은 문제를 확인하는 순서
- 최종 파일의 스트림부터 확인합니다. 편집기 프로젝트에 음성이 있어도 내보낸 MP4에 오디오가 남았는지는 별개입니다. 오디오가 없다면 내보내기 설정을 먼저 살펴보세요.
- 스트림이 있으면 디코딩한 신호를 확인합니다. 원하는 검사 기준과 최소 무음 길이를 함께 기록합니다. ‘무음 몇 초’라는 숫자만 남기면 설정이 다른 파일과 잘못 비교하기 쉽습니다.
- 마지막으로 실제 소리를 듣고 내용과 맞는지 확인합니다. 숫자 검사는 대사 누락, 발음, 효과음의 의미, 배경음과 목소리의 균형을 대신 판단하지 못합니다. 필요한 소리가 빠졌다면 그 내용을 복구해야 합니다. 통계만 바꾸려고 짧은 소리를 붙이는 방식을 해결책으로 추천하지 않습니다. 이는 필요한 내용을 복구해야 한다는 작성자의 실무 판단이며, 이번 대조군 실험으로 그 방법의 좋고 나쁨을 평가한 결과는 아닙니다.
로컬 파일에서 명령을 재현할 때는 경로와 파일명을 바꿔 사용하세요. 이 명령은 파일을 원격 서비스에 업로드하지 않습니다. 첫 명령은 스트림 정보만 읽습니다. 두 번째 명령은 첫 번째 오디오 스트림을 위 비교와 같은 PCM 조건으로 바꿔 검사하며, 오디오가 없는 파일에는 적용할 수 없습니다.
ffprobe -v error -show_streams -of json "my-video.mp4"
ffmpeg -nostdin -n -i "my-video.mp4" -map 0:a:0 -ar 16000 -ac 1 -c:a pcm_s16le "check-audio.wav"
ffmpeg -i "check-audio.wav" -af "silencedetect=noise=-45dB:d=0.1" -f null -
위 세 명령만으로 샘플별 개수까지 계산되지는 않습니다. 표의 샘플 수와 43,718개라는 추가 수치는 다음과 같은 별도 계산으로 얻었습니다. 같은 이름의 파일을 덮어쓰지 않고 검사 대상마다 다른 PCM 파일명을 사용하세요. 아래 코드는 16,000Hz·모노·16비트 파일만 받습니다.
import array, math, sys, wave
with wave.open("check-audio.wav", "rb") as wav:
assert (wav.getnchannels(), wav.getsampwidth(), wav.getframerate()) == (1, 2, 16000)
frames = wav.getnframes()
samples = array.array("h", wav.readframes(frames))
if sys.byteorder != "little":
samples.byteswap()
limit = 32768 * 10 ** (-45 / 20)
above = sum(abs(x) > limit for x in samples)
print("total samples:", frames, "decoded seconds:", frames / 16000)
print("nonzero:", sum(x != 0 for x in samples))
print("above threshold:", above, "samplewise seconds:", above / 16000)
자주 찾는 질문
AAC가 있으면 음성 합성이 성공한 건가요? 파일에 스트림이 있다는 사실까지 확인한 것입니다. 대본을 제대로 읽었는지, 원하는 소리가 담겼는지까지 확인한 결과는 아닙니다.
검출 무음 밖 시간이 길면 게시해도 되나요? 이 실험은 플랫폼 게시 승인이나 통과 여부를 검사하지 않았습니다. 최종 청취와 내용·권리·표시사항 검수는 따로 필요합니다. 채널이나 플랫폼 사이에 검사 기준을 옮겨 적용하지 마세요.
무음 AAC를 붙이면 영상이 개선되나요? 이번에는 오디오 스트림이 있는 완전한 무음 대조군을 만들기 위해 붙였습니다. 원하는 대사나 효과음을 복구하는 방법을 시험한 것이 아닙니다.
참고 자료와 함께 읽을 글
- FFmpeg 공식 무음 검출 문서: 기준과 최소 길이의 의미.
- ffprobe 공식 문서: 스트림 정보 읽기.
- 오늘 공개를 마친 기존 소유 AI 캐릭터 영상: 새 검사에 쓴 로컬 원본의 공개 출처. 이번 검사에서 영상을 새로 게시하지 않았습니다.
- 같은 한국어 대본에서 빠진 내용 확인하기
- 소유 이미지로 만든 영상의 실측 범위 읽기
AI 고지: 원자료의 캐릭터 영상과 효과음은 AI 제작 과정 및 자체 합성으로 만든 콘텐츠입니다. 글의 기획·문장 정리에 AI 도구를 사용했습니다. 표는 오늘 실제 로컬 명령 결과와 대조했습니다. 전편 청취 평가, 다른 영상의 품질 순위, 플랫폼 통과 또는 수익을 입증하는 글은 아닙니다.