ffmpeg_wrapper.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import subprocess
  2. import os
  3. from typing import Optional
  4. class FFmpegWrapper:
  5. """FFmpeg命令行包装工具"""
  6. def __init__(self):
  7. self.ffmpeg_path = "ffmpeg" # 假设ffmpeg已在系统PATH中
  8. def extract_audio(self, video_path: str, output_audio_path: str) -> bool:
  9. """
  10. 从视频中提取音频轨道
  11. Args:
  12. video_path: 视频文件路径
  13. output_audio_path: 输出音频文件路径
  14. Returns:
  15. bool: 操作是否成功
  16. """
  17. try:
  18. cmd = [
  19. self.ffmpeg_path,
  20. "-i", video_path,
  21. "-vn", # 禁用视频
  22. "-acodec", "pcm_s16le", # 16位PCM
  23. "-ar", "16000", # 16kHz采样率
  24. "-ac", "1", # 单声道
  25. "-y", # 覆盖输出文件
  26. output_audio_path
  27. ]
  28. subprocess.run(cmd, check=True, capture_output=True, text=True)
  29. return True
  30. except subprocess.CalledProcessError as e:
  31. raise Exception(f"音频提取失败: {e.stderr}")
  32. def convert_audio(self, input_audio_path: str, output_audio_path: str) -> bool:
  33. """
  34. 转换音频格式为16k/16bit/mono wav
  35. Args:
  36. input_audio_path: 输入音频文件路径
  37. output_audio_path: 输出音频文件路径
  38. Returns:
  39. bool: 操作是否成功
  40. """
  41. try:
  42. cmd = [
  43. self.ffmpeg_path,
  44. "-i", input_audio_path,
  45. "-acodec", "pcm_s16le",
  46. "-ar", "16000",
  47. "-ac", "1",
  48. "-y",
  49. output_audio_path
  50. ]
  51. subprocess.run(cmd, check=True, capture_output=True, text=True)
  52. return True
  53. except subprocess.CalledProcessError as e:
  54. raise Exception(f"音频转换失败: {e.stderr}")
  55. def extract_keyframes(self, video_path: str, output_dir: str, interval: int = 60) -> list:
  56. """
  57. 从视频中提取关键帧
  58. Args:
  59. video_path: 视频文件路径
  60. output_dir: 输出目录
  61. interval: 提取间隔(秒)
  62. Returns:
  63. list: 提取的关键帧文件路径列表
  64. """
  65. try:
  66. # 确保输出目录存在
  67. os.makedirs(output_dir, exist_ok=True)
  68. # 提取关键帧
  69. output_pattern = os.path.join(output_dir, "frame_%06d.jpg")
  70. cmd = [
  71. self.ffmpeg_path,
  72. "-i", video_path,
  73. "-vf", f"fps=1/{interval}", # 每分钟一张
  74. "-y",
  75. output_pattern
  76. ]
  77. subprocess.run(cmd, check=True, capture_output=True, text=True)
  78. # 收集提取的关键帧
  79. keyframes = []
  80. for file in os.listdir(output_dir):
  81. if file.startswith("frame_") and file.endswith(".jpg"):
  82. keyframes.append(os.path.join(output_dir, file))
  83. return sorted(keyframes)
  84. except subprocess.CalledProcessError as e:
  85. raise Exception(f"关键帧提取失败: {e.stderr}")