[chatGPT 測試]寫一隻 Windows環境下的Python,調用ffmepg調整解析度為1080

寫一隻python 符合下面功能需求
1.本程式運行平台為Windows
2.調用ffmpeg.exe進行解析度調整
3.使用 ffmpeg 中的scale 參數,設定最大長寬為1080
6.指定路徑進行儲存
7.檔案已存在測略過
8.目標的格式為mp4
9.目標的fps為30
10.編碼方式為x265
11.ffmpeg.exe 已安裝於指定的路徑

以下是符合您需求的 Python 程式碼,適用於 Windows 環境。這個程式會掃描指定來源路徑下的所有影片檔案,使用 ffmpeg.exe 進行解析度調整,使用 ffmpeg 中的 scale 參數將影片的解析度調整為最大長寬為1080,目標格式為 MP4,FPS 設定為 30,並使用 x265 編碼方式,最後將處理後的影片儲存到指定目標路徑。如果目標檔案已存在,則會略過該檔案。

import os
import subprocess

def resize_video(ffmpeg_path, input_path, output_path, target_fps=30, max_resolution=1080):
    if not os.path.exists(output_path):
        os.makedirs(output_path)

    for root, dirs, files in os.walk(input_path):
        for file in files:
            if file.endswith(('.mp4', '.avi', '.mkv', '.mov')):
                input_file = os.path.join(root, file)
                output_file = os.path.join(output_path, os.path.splitext(file)[0] + '.mp4')
                
                if os.path.exists(output_file):
                    print(f"Skipping existing file: {output_file}")
                    continue
                
                ffmpeg_command = [
                    os.path.join(ffmpeg_path, 'ffmpeg.exe'), '-i', input_file,
                    '-vf', f'scale=min(iw\,{max_resolution}):min(ih\,{max_resolution}):force_original_aspect_ratio=decrease',
                    '-r', str(target_fps),  # Set the target FPS
                    '-c:v', 'libx265',  # Use x265 codec for encoding
                    '-c:a', 'copy', output_file
                ]

                subprocess.run(ffmpeg_command, shell=True)
                print(f"Converted {input_file} to {output_file} with maximum resolution {max_resolution}, fps {target_fps}, and x265 encoding")

if __name__ == "__main__":
    ffmpeg_directory = r"C:\path\to\ffmpeg"
    input_directory = r"C:\path\to\input"
    output_directory = r"C:\path\to\output"
    resize_video(ffmpeg_directory, input_directory, output_directory)

關於最大解析度的解法,我用了很多個問句去試,多少都有問題,後來看到ffmepg scale參數,爬了一下官方網站
可以做到使用scale指定最高解析度,所以改了問法,就跑出來可以正常縮小的的語法
轉檔只要一隻是FFMPEG.EXE這隻是負責轉檔。另一隻是FFProbe.exe用來偵測長寬編碼等資料的程式是用不到的

比起傳統的做法簡單許多(ffprobe.exe抓最大高寬,等比縮小另一個小的高寬)
為了省資源,使用mp4輸出,編碼是x265
音源取樣,我沒有動

下載了4k影片,電視機上合或是電視棒播放卡頓,可以用這個方式來處理

20240520 本程式再做一個修改,已轉檔過的,先略過
寫一隻python 符合下面功能需求
1.本程式運行平台為Windows
2.調用ffmpeg.exe進行解析度調整
3.使用 ffmpeg 中的scale 參數,設定最大寬高為1080
4.指定路徑儲存轉檔過的檔案
5.檔案已存在測略過
6.目標的格式為mp4
7.目標的fps為30
8.編碼方式為x265
9.略過已轉換過格式的檔案
10.ffmpeg.exe 已安裝於指定的路徑

會多調用一隻ffprobe偵測檔案的格式,如果已經轉過,則自動略過,就是透過ffprobe
—-
import os
import subprocess

def is_converted(ffmpeg_path, file_path, target_fps=30):
ffprobe_command = [
os.path.join(ffmpeg_path, ‘ffprobe.exe’), ‘-v’, ‘error’, ‘-select_streams’, ‘v:0’,
‘-show_entries’, ‘stream=codec_name,r_frame_rate’,
‘-of’, ‘default=noprint_wrappers=1:nokey=1’, file_path
]
result = subprocess.run(ffprobe_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True)
if result.returncode != 0:
print(f”Failed to get video info for {file_path}: {result.stderr}”)
return False

output = result.stdout.split()
codec_name = output[0]
fps = eval(output[1])

return codec_name == ‘hevc’ and fps == target_fps

def resize_video(ffmpeg_path, input_path, output_path, target_fps=30, max_resolution=1080):
if not os.path.exists(output_path):
os.makedirs(output_path)

for root, dirs, files in os.walk(input_path):
for file in files:
if file.endswith((‘.mp4’, ‘.avi’, ‘.mkv’, ‘.mov’)):
input_file = os.path.join(root, file)
output_file = os.path.join(output_path, os.path.splitext(file)[0] + ‘.mp4’)

if os.path.exists(output_file):
print(f”Skipping existing file: {output_file}”)
continue

if is_converted(ffmpeg_path, input_file, target_fps):
print(f”Skipping already converted file: {input_file}”)
continue

ffmpeg_command = [
os.path.join(ffmpeg_path, ‘ffmpeg.exe’), ‘-i’, input_file,
‘-vf’, f’scale=\’min({max_resolution},iw)\’:\’min({max_resolution},ih)\’:force_original_aspect_ratio=decrease’,
‘-r’, str(target_fps), # Set the target FPS
‘-c:v’, ‘libx265’, # Use x265 codec for encoding
‘-c:a’, ‘copy’, output_file
]

subprocess.run(ffmpeg_command, shell=True)
print(f”Converted {input_file} to {output_file} with maximum resolution {max_resolution}, fps {target_fps}, and x265 encoding”)

if __name__ == “__main__”:
ffmpeg_directory = r”C:\path\to\ffmpeg” # 修改为您的ffmpeg路径
input_directory = r”C:\path\to\input” # 修改为您的输入路径
output_directory = r”C:\path\to\output” # 修改为您的输出路径
resize_video(ffmpeg_directory, input_directory, output_directory)

 


寫一隻python 符合下面功能需求
1.本程式運行平台為linux
2.調用ffmpeg進行解析度調整
3.ffmpeg已安裝於指定的路徑
4.掃瞄來源路徑下包含子目錄中的影片檔
5.使用原檔名加上”x265_”在檔名的開頭為新檔名
6.新檔儲存在原路徑下
7.使用ffmpeg 中的scale 參數,設定最大寬高為1920
8.目標的格式為mp4 / fps為30 / 編碼方式為x265
9.已轉影片檔案若已存在則略過
10.略過已轉換過格式的檔案
11.在指定的時間運行,不在指定的時間內,結束程式

import os
import subprocess
import datetime

# 設定ffmpeg路徑
ffmpeg_path = “/usr/local/bin/ffmpeg” # 替換成你的ffmpeg路徑

# 設定來源路徑
source_path = “/path/to/your/videos” # 替換成你的來源路徑

# 設定允許的運行時間(24小時制)
start_time = datetime.time(1, 0) # 開始時間,例如1:00 AM
end_time = datetime.time(5, 0) # 結束時間,例如5:00 AM

# 支援的影片格式
video_extensions = [‘.mp4’, ‘.mkv’, ‘.avi’, ‘.mov’, ‘.flv’, ‘.wmv’]

def is_video_file(filename):
return any(filename.lower().endswith(ext) for ext in video_extensions)

def get_all_video_files(path):
video_files = []
for root, _, files in os.walk(path):
for file in files:
if is_video_file(file):
video_files.append(os.path.join(root, file))
return video_files

def convert_video(file_path):
file_dir, file_name = os.path.split(file_path)
file_base, file_ext = os.path.splitext(file_name)

# 檢查是否已經轉換過
target_file_name = f”x265_{file_base}.mp4″
target_file_path = os.path.join(file_dir, target_file_name)

if os.path.exists(target_file_path):
print(f”已存在轉換後的文件,跳過: {target_file_path}”)
return

# ffmpeg 轉換命令
command = [
ffmpeg_path,
‘-i’, file_path,
‘-vf’, ‘scale=w=1920:h=1920:force_original_aspect_ratio=decrease’,
‘-c:v’, ‘libx265’,
‘-crf’, ’28’,
‘-preset’, ‘medium’,
‘-r’, ’30’,
target_file_path
]

try:
print(f”轉換中: {file_path}”)
subprocess.run(command, check=True)
print(f”轉換成功: {target_file_path}”)
except subprocess.CalledProcessError as e:
print(f”轉換失敗: {file_path}, 錯誤: {e}”)

def within_allowed_time():
current_time = datetime.datetime.now().time()
if start_time <= end_time:
return start_time <= current_time <= end_time
else: # 跨午夜
return current_time >= start_time or current_time <= end_time

def main():
if not within_allowed_time():
print(“不在允許的時間內,程式關閉”)
return

video_files = get_all_video_files(source_path)
for video_file in video_files:
if ‘x265_’ in os.path.basename(video_file):
print(f”已轉換過格式的檔案,跳過: {video_file}”)
continue
convert_video(video_file)

if __name__ == “__main__”:
main()

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *