[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 時),符合實際需求。
- 動態計算解析度,確保不會放大影片且保持寬高比。
- 高效轉檔,只在必要時改變解析度或幀率。
試試看這個版本,應該能完全符合需求!如果還有其他問題,請隨時告訴我。

留言板
歡迎留下建議與分享!希望一起交流!感恩!