실행 목적
api 미사용(과금 가능성)으로 영상 파일을 대상으로 음성 대본(.srt) 추출
실제 경로 내 파일

실행 자체는 로컬환경 리소스 절약을 위해 Google Colab을 사용 (로컬환경에서도 실행 가능)
선행 조건
- 구글 코랩 또는 로컬 등 구동 가능한 환경
- 구글 드라이브 (경로 생성은 자동)
실행 순서

- 기본 모듈 설치 및 마운트
- .srt 파일 추출
- 추가 프롬프트 입력 (추출 전 프롬프트 질문 有, 고유명사 등을 입력 권장)
작성 내용
- 기본 모듈 설치 및 마운트
# @title 1. 초기 설정(라이브러리 설치) 및 마운트
# 필수 패키지 설치 (ffmpeg, whisper, tqdm)
!apt -y install ffmpeg > /dev/null
!pip -q install git+https://github.com/openai/whisper.git tqdm
# 구글 드라이브 마운트
from google.colab import drive
drive.mount('/content/drive')
import os
import torch
import whisper
import subprocess
from pathlib import Path
from tqdm.notebook import tqdm
# GPU 사용 가능 여부 확인
device_check = "cuda" if torch.cuda.is_available() else "cpu"
print(f"\n✅ 설정 완료. (현재 디바이스: {device_check.upper()})")
- .srt 파일 추출 (메인 실행)
# @title 2. Whisper 자막 추출 실행
# ==========================================
# A. 설정 및 경로 정의
# ==========================================
BASE_DIR = Path("/content/drive/MyDrive/whisper")
INPUT_DIR = BASE_DIR / "whisper_input"
OUTPUT_DIR = BASE_DIR / "whisper_output"
TMP_DIR = Path("/content/whisper_tmp")
for p in (INPUT_DIR, OUTPUT_DIR, TMP_DIR):
p.mkdir(parents=True, exist_ok=True)
MODEL_SIZE = "medium"
VIDEO_EXTS = {".mp4", ".mov", ".mkv", ".m4v", ".avi", ".mp3", ".wav", ".m4a", ".flac", ".wma"}
USE_PREPROCESS = False
PREPROCESS_FILTER = "loudnorm,highpass=f=100"
# ==========================================
# B. 프롬프트 및 디바이스 설정
# ==========================================
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
FP16 = (DEVICE == "cuda")
print(f"🚀 작업 시작 (디바이스: {DEVICE.upper()})")
# 사용자 키워드 입력
print("\n" + "-"*40)
print("💡 [힌트] 영상의 주제, 고유명사, 전문용어를 입력하세요 (없으면 Enter)")
user_hint = input("키워드 입력 > ").strip()
# ▼ [수정됨] 인사말 제거 및 효율성 위주의 지시형 프롬프트
base_prompt = "한국어 자막을 생성합니다. 문장의 끝에는 반드시 마침표를 찍고, 문맥에 맞는 정확한 띄어쓰기와 맞춤법을 준수하세요."
final_prompt = base_prompt
if user_hint:
final_prompt += f" 특히 다음 전문 용어의 표기를 정확히 지키세요: {user_hint}"
print(f"📋 적용된 프롬프트: \"{final_prompt}\"")
print("-"*40 + "\n")
# ==========================================
# C. 내부 처리 함수
# ==========================================
def format_timestamp(seconds: float):
ms = int((seconds % 1) * 1000)
seconds = int(seconds)
hrs = seconds // 3600
mins = (seconds % 3600) // 60
secs = seconds % 60
return f"{hrs:02d}:{mins:02d}:{secs:02d},{ms:03d}"
def write_srt(segments, file_path):
with open(file_path, "w", encoding="utf-8") as f:
for i, seg in enumerate(segments, start=1):
start = format_timestamp(seg['start'])
end = format_timestamp(seg['end'])
text = seg['text'].strip()
f.write(f"{i}\n{start} --> {end}\n{text}\n\n")
def preprocess_audio(src, dst):
cmd = [
"ffmpeg", "-y", "-i", str(src),
"-vn", "-ac", "1", "-ar", "16000",
"-af", PREPROCESS_FILTER,
str(dst)
]
subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# ==========================================
# D. 배치 실행 로직
# ==========================================
def run_batch():
files = []
for root, _, names in os.walk(INPUT_DIR):
for n in names:
if n.startswith(".") or n.endswith(".part"): continue
if Path(n).suffix.lower() in VIDEO_EXTS:
files.append(Path(root) / n)
files.sort()
if not files:
print(f"❌ '{INPUT_DIR}' 폴더에 처리할 파일이 없습니다.")
return
print(f"⏳ 모델 로딩 중... ({MODEL_SIZE})")
try:
model = whisper.load_model(MODEL_SIZE, device=DEVICE)
except Exception as e:
print(f"❌ 모델 로드 실패: {e}")
return
print("✅ 모델 로드 완료.")
for f in tqdm(files, desc="전체 진행률"):
srt_out = OUTPUT_DIR / f"{f.stem}.srt"
if srt_out.exists() and srt_out.stat().st_size > 100:
print(f"⏩ 스킵: {f.name}")
continue
print(f"🎬 처리 중: {f.name}")
src_file = f
tmp_wav = None
try:
if USE_PREPROCESS:
tmp_wav = TMP_DIR / f"{f.stem}_temp.wav"
preprocess_audio(f, tmp_wav)
src_file = tmp_wav
# Whisper 추론 실행
result = model.transcribe(
str(src_file),
language="ko",
fp16=FP16,
initial_prompt=final_prompt, # 수정된 프롬프트 적용
verbose=False,
condition_on_previous_text=False,
temperature=(0.0, 0.2, 0.4, 0.6, 0.8, 1.0),
compression_ratio_threshold=2.4,
logprob_threshold=-1.0,
no_speech_threshold=0.6
)
write_srt(result["segments"], srt_out)
print(f" -> 💾 저장 완료")
except Exception as e:
print(f" -> ❌ 에러 발생: {e}")
finally:
if tmp_wav and tmp_wav.exists():
try: tmp_wav.unlink()
except: pass
print("\n🎉 모든 작업이 완료되었습니다.")
if __name__ == "__main__":
run_batch()
실행 결과

