Ahoj, sdílím skript co jsem napsal. Když máte situaci, kdy vás zajímá nějaká část videa, ale potřebujete ji hodně zpomalit nebo vygenerovat části toho videa, které se sloučí do jednoho videa a chcete je zpomalit, abyste si je mohly přehrát, ale zároveň chcete, aby zvuk zachoval tóny. Do výstupní složky Output tedy vytvoří složky s čísly o vyjadřující faktor zpomalení a do složky vygenerované výsledky. Pozor je tam uvedená absolutní cesta, takže pro opakované změny je třeba původní soubor přejmenovat ať se vám nepřepíšou hotové videa. Toto jsem používal pro práci s hudbou. Definici časových úseků si můžete přidat podle libosti.
Vložím to sem jako surový kód protože mi přestala fungovat myš. Kdo máte myš, prosím o zformátování.
# REQUIRES: moviepy a pydub
import os
from moviepy.editor import VideoFileClip, concatenate_videoclips, vfx, AudioFileClip
from pydub import AudioSegment
# Cesty ke složkám
home_dir = os.path.expanduser("~")
default_path = "/Samba-Bossa Nova"
input_dir = os.path.join("/media/toshiba/home/user/Videa", default_path)
file = 'Mas, que nada! de Jorge Ben - Paola Hermosín - 2nd minute.mp4'
input_path = os.path.join(input_dir, file)
ramdisk_disable = True # Deaktivuje vytvoření RAM disku
user_choice = input("Chcete použít aktuální složku (.) nebo přednastavenou složku? Zadejte '.' pro aktuální složku nebo 'default' pro přednastavenou složku: ")
if user_choice == '.':
input_dir = os.path.abspath('.')
input_path = os.path.join(input_dir, file)
# Faktory zpomalení
slowdowns = [4,6,8,10,15,20,25,30,40]
# Vytvoření výstupních složek dynamicky na základě faktorů zpomalení
output_dirs = [os.path.join(input_dir, f"Output/{factor}") for factor in slowdowns]
for dir in output_dirs:
os.makedirs(dir, exist_ok=True)
# Vytvoření RAM disku (bez skutečného připojení, pokud je ramdisk_disable = True)
ramdisk_path = os.path.join(input_dir, "ramdisk")
log_file = os.path.join(input_dir, "ramdisk.log")
if not os.path.exists(ramdisk_path):
os.makedirs(ramdisk_path)
if not ramdisk_disable:
with open(log_file, "w") as log:
os.system(f'sudo mount -t tmpfs -o size={ramdisk_size}M tmpfs "{ramdisk_path}"')
os.system(f'df "{ramdisk_path}" > "{log_file}"')
with open(log_file, "r") as log:
log_content = log.read()
if ramdisk_path in log_content:
print(f"RAM disk is correctly mounted.")
else:
print(f"RAM disk is not found")
# Funkce pro změnu pitch audia bez změny rychlosti
def audio_pitchup_ffmpeg(input_audio_path, output_audio_path, factor):
command = f'ffmpeg -i "{input_audio_path}" -filter_complex "rubberband=pitch={factor}" "{output_audio_path}"'
os.system(command)
# Převod času na sekundy
def convert_to_seconds(time_str):
parts = time_str.split(':')
minutes = int(parts[0])
seconds = float(parts[1])
return minutes * 60 + seconds
# Definice časových rozsahů k vyexportování
time_ranges = [
# ("0:50.40", "0:56.00")
# ("0:56.00", "0:56.02")
("1:27.00", "2:27.00") # První minuta
# ("1:27.00", "4:37")
]
# Zpracování jednoho videa file
video_path = input_path
if os.path.isfile(video_path) and video_path.endswith(".mp4"): # Upravte podle formátu vašich videí
video_clip = VideoFileClip(video_path)
# Exportování specifikovaných časových úseků jako dočasné soubory
temp_clips = []
for start_time, end_time in time_ranges:
start_seconds = convert_to_seconds(start_time)
end_seconds = convert_to_seconds(end_time)
temp_clip = video_clip.subclip(start_seconds, end_seconds)
temp_clips.append(temp_clip)
# Sloučení úseků do jednoho videa
temp_joined_path = os.path.join(input_dir, "temp_joined.avi")
joined_clip = concatenate_videoclips(temp_clips)
joined_clip.write_videofile(temp_joined_path, codec="libx264", audio_codec="aac")
# Uzavření všech klipů
for clip in temp_clips:
clip.close()
video_clip.close()
joined_clip.close()
# Zpomalení videí a korekce pitch v audio stopách
for i, factor in enumerate(slowdowns):
output_path = os.path.join(output_dirs[i], file)
edited_clip = VideoFileClip(temp_joined_path)
# Extrakce a úprava audio stopy
temp_audio_path = os.path.join(ramdisk_path, "temp_audio.wav")
edited_clip.audio.write_audiofile(temp_audio_path, codec='pcm_s16le')
new_audio_path = os.path.join(ramdisk_path, "new_temp_audio.wav")
audio_pitchup_ffmpeg(temp_audio_path, new_audio_path, factor)
new_audio_clip = AudioFileClip(new_audio_path)
# Vytvoření nového video klipu s upravenou audio stopou
edited_clip = edited_clip.set_audio(new_audio_clip)
temp_video_name = os.path.join(ramdisk_path, "temp-final-video.m4a")
edited_clip.write_videofile(
temp_video_name,
codec="libx264",
audio_codec="aac",
temp_audiofile=os.path.join(ramdisk_path, 'temp-audio-1.m4a'),
remove_temp=True,
threads=4,
preset='ultrafast'
)
# Uzavření dočasných klipů
edited_clip.close()
new_audio_clip.close()
# Znovu otevření video klipu pro zpomalení
edited_clip = VideoFileClip(temp_video_name)
edited_clip = edited_clip.fx(vfx.speedx, 1.0 / factor)
edited_clip.set_duration(edited_clip.duration)
print(f"Processing {file} with slowdown factor {factor}. Saving to {output_path}")
edited_clip.write_videofile(
output_path,
codec="libx264",
audio_codec="aac",
temp_audiofile=os.path.join(ramdisk_path,'temp-audio-2.m4a'),
remove_temp=True,
threads=4,
preset='ultrafast'
)
# Uzavření všech klipů
edited_clip.close()
# Odstranění dočasných souborů
if os.path.exists(temp_audio_path):
os.remove(temp_audio_path)
if os.path.exists(new_audio_path):
os.remove(new_audio_path)
if os.path.exists(temp_video_name):
os.remove(temp_video_name)
# Odstranění dočasného sloučeného videa
if os.path.exists(temp_joined_path):
os.remove(temp_joined_path)
print("Job done.")
if not ramdisk_disable:
os.system(f'sudo umount "{ramdisk_path}"')