| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- import subprocess
- import os
- from typing import Optional
- class FFmpegWrapper:
- """FFmpeg命令行包装工具"""
-
- def __init__(self):
- self.ffmpeg_path = "ffmpeg" # 假设ffmpeg已在系统PATH中
-
- def extract_audio(self, video_path: str, output_audio_path: str) -> bool:
- """
- 从视频中提取音频轨道
-
- Args:
- video_path: 视频文件路径
- output_audio_path: 输出音频文件路径
-
- Returns:
- bool: 操作是否成功
- """
- try:
- cmd = [
- self.ffmpeg_path,
- "-i", video_path,
- "-vn", # 禁用视频
- "-acodec", "pcm_s16le", # 16位PCM
- "-ar", "16000", # 16kHz采样率
- "-ac", "1", # 单声道
- "-y", # 覆盖输出文件
- output_audio_path
- ]
-
- subprocess.run(cmd, check=True, capture_output=True, text=True)
- return True
- except subprocess.CalledProcessError as e:
- raise Exception(f"音频提取失败: {e.stderr}")
-
- def convert_audio(self, input_audio_path: str, output_audio_path: str) -> bool:
- """
- 转换音频格式为16k/16bit/mono wav
-
- Args:
- input_audio_path: 输入音频文件路径
- output_audio_path: 输出音频文件路径
-
- Returns:
- bool: 操作是否成功
- """
- try:
- cmd = [
- self.ffmpeg_path,
- "-i", input_audio_path,
- "-acodec", "pcm_s16le",
- "-ar", "16000",
- "-ac", "1",
- "-y",
- output_audio_path
- ]
-
- subprocess.run(cmd, check=True, capture_output=True, text=True)
- return True
- except subprocess.CalledProcessError as e:
- raise Exception(f"音频转换失败: {e.stderr}")
-
- def extract_keyframes(self, video_path: str, output_dir: str, interval: int = 60) -> list:
- """
- 从视频中提取关键帧
-
- Args:
- video_path: 视频文件路径
- output_dir: 输出目录
- interval: 提取间隔(秒)
-
- Returns:
- list: 提取的关键帧文件路径列表
- """
- try:
- # 确保输出目录存在
- os.makedirs(output_dir, exist_ok=True)
-
- # 提取关键帧
- output_pattern = os.path.join(output_dir, "frame_%06d.jpg")
- cmd = [
- self.ffmpeg_path,
- "-i", video_path,
- "-vf", f"fps=1/{interval}", # 每分钟一张
- "-y",
- output_pattern
- ]
-
- subprocess.run(cmd, check=True, capture_output=True, text=True)
-
- # 收集提取的关键帧
- keyframes = []
- for file in os.listdir(output_dir):
- if file.startswith("frame_") and file.endswith(".jpg"):
- keyframes.append(os.path.join(output_dir, file))
-
- return sorted(keyframes)
- except subprocess.CalledProcessError as e:
- raise Exception(f"关键帧提取失败: {e.stderr}")
|