Předchozí skript obsahoval vážnou chybu. Zvuk byl příliš opožděn za obrazem asi o 35% a ve výsledku se tam vešla jen 1/2 z původního segmentu.
Nový skript vypadá dobře. Testováno jen pro zpomalení 8x.
# TENTO SKRIPT S librosou vypadá opravdu správně
# ALE TESTOVAL JSEM TO ZATÍM JEN NA 8X ZPOMALENÍ
# REQUIRES: moviepy, librosa, soundfile
import os
from moviepy.editor import VideoFileClip, concatenate_videoclips, vfx, AudioFileClip
import librosa
import soundfile as sf
import time
# Cesty ke složkám
home_dir = os.path.expanduser("~")
default_path = "/TUTORIALS"
input_dir = os.path.join("/media/toshiba/home/user/Videa", default_path)
file = 'TUTORIAL DRŽENÍ ZÁPĚSTÍ A PRSTY PRAVÉ RUKY -5 cosas que NO debes hacer tocando la guitarra.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 = [2, 4, 6, 8, 10, 15, 20, 25]
slowdowns = [8]
# 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 pitchu pomocí ffmpeg
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)
# Funkce pro změnu rychlosti zvuku pomocí librosa
def change_audio_speed(input_audio_path, output_audio_path, speed_factor, target_duration):
# Načtěte původní zvukový soubor
y, sr = librosa.load(input_audio_path, sr=None)
# Získejte a vytiskněte délku původního zvuku
original_duration = librosa.get_duration(y=y, sr=sr)
print(f"Audio duration before stretching: {original_duration} seconds")
# Zrychlete/zpomalte zvuk tak, aby odpovídal nové délce videa
y_stretched = librosa.effects.time_stretch(y, rate=original_duration / target_duration)
# Získejte a vytiskněte délku zvuku po zpracování
stretched_duration = librosa.get_duration(y=y_stretched, sr=sr)
print(f"Audio duration after stretching: {stretched_duration} seconds")
time.sleep(2)
# Uložte zpracovaný zvuk do nového souboru
sf.write(output_audio_path, y_stretched, sr)
# 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:0.0", "0:03.20") # krátká ukázka základní techniky fingerpickingu když zpomalila
]
# 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')
# Změna pitchu zvuku
new_audio_path = os.path.join(ramdisk_path, "new_temp_audio.wav")
audio_pitchup_ffmpeg(temp_audio_path, new_audio_path, factor)
# Změna rychlosti upravené audio stopy tak, aby odpovídala nové délce videa
final_audio_path = os.path.join(ramdisk_path, "final_audio.wav")
change_audio_speed(new_audio_path, final_audio_path, factor, edited_clip.duration)
new_audio_clip = AudioFileClip(final_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(final_audio_path):
os.remove(final_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}"')
Žádné komentáře:
Okomentovat