[ffmpeg影片壓縮] 如何取得原本影片寬高,不放大影片,最大不超過1920,FPS不超過60?
如果希望在影片的幀率超過 60 FPS 時才限制為 60,否則保留原始幀率,可以先使用 ffprobe
提取影片的幀率,然後根據結果動態設置 FFmpeg 命令。
以下是更新的程式碼:
完整程式碼
import subprocess import json import os import re def get_video_info(input_file): """取得影片的解析度和幀率""" command = [ "ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=width,height,r_frame_rate", "-of", "json", input_file ] result = subprocess.run(command, capture_output=True, text=True, check=True) video_info = json.loads(result.stdout) width = video_info['streams'][0]['width'] height = video_info['streams'][0]['height'] # 計算幀率(轉換分數形式) frame_rate = video_info['streams'][0]['r_frame_rate'] num, den = map(int, frame_rate.split('/')) fps = num / den return width, height, fps def calculate_new_resolution(width, height, max_resolution): """計算新的解析度,僅縮小,不放大""" if max(width, height) > max_resolution: if width > height: new_width = max_resolution new_height = int(height * max_resolution / width) else: new_height = max_resolution new_width = int(width * max_resolution / height) # 確保寬高是偶數 new_width = (new_width // 2) * 2 new_height = (new_height // 2) * 2 return new_width, new_height else: # 不縮放,保持原解析度 return width, height def convert_mov_to_mp4_with_dynamic_fps(input_file, output_file, max_resolution=1920, max_fps=60): """轉檔並根據條件限制解析度和幀率""" if not os.path.exists(input_file): raise FileNotFoundError(f"Input file not found: {input_file}") # 取得影片資訊 original_width, original_height, original_fps = get_video_info(input_file) new_width, new_height = calculate_new_resolution(original_width, original_height, max_resolution) # 決定幀率參數 fps_option = f"-r {max_fps}" if original_fps > max_fps else "" # 使用 FFmpeg 轉檔 command = [ "ffmpeg", "-i", input_file, # 輸入檔案 "-vf", f"scale={new_width}:{new_height}", # 指定解析度 ] if fps_option: command.extend(fps_option.split()) # 添加幀率限制 command.extend([ "-c:v", "libx264", # 重新編碼視訊為 H.264 "-preset", "fast", # 編碼速度與壓縮率平衡 "-crf", "23", # 視訊品質控制 "-c:a", "aac", # 音訊重新編碼為 AAC "-b:a", "128k", # 音訊比特率 "-map_metadata", "0", # 保留所有元數據 output_file # 輸出檔案 ]) try: subprocess.run(command, check=True) print(f"Conversion successful! Output saved to: {output_file}") except subprocess.CalledProcessError as e: print(f"Error during conversion: {e}") # 使用範例 input_mov = "example.mov" output_mp4 = "example_dynamic_fps.mp4" convert_mov_to_mp4_with_dynamic_fps(input_mov, output_mp4)
程式說明
-
取得幀率:
- 使用
ffprobe
提取r_frame_rate
,計算出實際幀率。 - 例如,
r_frame_rate
可能是30000/1001
,轉換後得到29.97 FPS
。
- 使用
-
動態設定幀率:
- 如果原始幀率超過
60 FPS
,使用-r 60
限制。 - 如果幀率小於或等於
60 FPS
,則不添加-r
,保留原始幀率。
- 如果原始幀率超過
-
解析度不放大:
- 如果原始寬高小於
1920
,直接保留原解析度。 - 確保解析度的寬高為偶數,避免解碼器問題。
- 如果原始寬高小於
-
轉檔流程:
- 幀率條件和解析度條件分別處理,動態生成 FFmpeg 指令。
優點
- 保留原始幀率(低於 60 FPS 時),符合實際需求。
- 動態計算解析度,確保不會放大影片且保持寬高比。
- 高效轉檔,只在必要時改變解析度或幀率。
試試看這個版本,應該能完全符合需求!如果還有其他問題,請隨時告訴我。
留言板
歡迎留下建議與分享!希望一起交流!感恩!