středa 21. ledna 2026

Python: Zpomalení videí (.akv) ve složkách - pro moviepy vs 1.0.3

Pracuje s malými segmenty, které by měl kopírovat na ramdisk a pak je sloučí do jednoho zpomaleného videa. Zvuk jsem se snažil zachovat v původních tonech. Je možné dát tam více zpomalovacích faktorů.

#!/usr/bin/env python3
import os

# MoviePy 1.x importuje moduly takto:
from moviepy.editor import VideoFileClip, AudioFileClip, concatenate_videoclips, vfx


"""
MoviePy 2.x importuje moduly takto:
from moviepy import VideoFileClip, concatenate_videoclips
from moviepy.video.fx import all as vfx
from moviepy.audio.io import AudioFileClip
"""
import librosa
import soundfile as sf
import time



# Definice zdrojových a cílových adresářů
source_dirs = [
    "./Jan Kudelka",
    "./Zpěvník Znam i gram - T Stachak"
]

source_ext = "mkv"

# Faktory zpomalení
slowdowns = [4]

# Vytvoření RAM disku (bez skutečného připojení, pokud je ramdisk_disable = True)
ramdisk_disable = True  # Deaktivuje vytvoření RAM disku
ramdisk_path = "./ramdisk"  # Globální RAM disk pro všechny
log_file = "./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):
    y, sr = librosa.load(input_audio_path, sr=None)
    original_duration = librosa.get_duration(y=y, sr=sr)
    print(f"Audio duration before stretching: {original_duration} seconds")
    
    y_stretched = librosa.effects.time_stretch(y, rate=original_duration / target_duration)
    stretched_duration = librosa.get_duration(y=y_stretched, sr=sr)
    print(f"Audio duration after stretching: {stretched_duration} seconds")
    time.sleep(2)
    
    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ů – automaticky po 20 sekundách
def generate_time_ranges(duration, segment_len=10.0):
    ranges = []
    start = 0.0
    while start < duration:
        end = min(start + segment_len, duration)
        # Formát jako máš v kódu
        start_str = f"{int(start // 60)}:{start % 60:05.2f}"
        end_str   = f"{int(end // 60)}:{end % 60:05.2f}"
        ranges.append((start_str, end_str))
        start = end
    return ranges

# Definice časových rozsahů k vyexportování - nahrazeno funkcí generate_time_ranges()
time_ranges = [
    ("0:0.0", "0:10.00"),
    ("0:10.0", "0:20.00"),
    ("0:20.0", "0:30.00"),
    ("0:30.0", "0:40.00"),
    ("0:40.0", "0:50.00"),
    ("0:50.0", "0:60.00"),
    ("1:00.0", "1:10.00"),
    ("1:10.0", "1:20.00")
]

# Zpracování všech souborů v každém zdrojovém adresáři
for source_dir in source_dirs:
    # Vytvoření výstupních složek dynamicky na základě faktorů zpomalení
    output_dirs = [os.path.join(source_dir, str(factor)) for factor in slowdowns]
    for dir in output_dirs:
        os.makedirs(dir, exist_ok=True)
    
    # Získání všech MP4 souborů ve zdrojovém adresáři
    original_files = [f for f in os.listdir(source_dir) if f.endswith(f".{source_ext}")]
    
    for file in original_files:
        video_path = os.path.join(source_dir, file)
        if os.path.isfile(video_path):
            video_clip = VideoFileClip(video_path)
            video_duration = video_clip.duration
            print(f"Video {file}: délka {video_duration:.1f} s")

            time_ranges = generate_time_ranges(video_duration, segment_len=10.0)
            
            # Pro každý faktor zpomalení
            for i, factor in enumerate(slowdowns):
                segment_paths = []
                
                # Zpracování jednotlivých segmentů
                for j, (start_time, end_time) in enumerate(time_ranges):
                    start_seconds = convert_to_seconds(start_time)
                    end_seconds = convert_to_seconds(end_time)
                    # Kontrola, zda rozsah nepřesahuje délku videa
                    if start_seconds >= video_clip.duration:
                        continue
                    end_seconds = min(end_seconds, video_clip.duration)
                    # v 2.0
                    seg_clip = video_clip.subclip(start_seconds, end_seconds)
                    
                    output_segment_path = os.path.join(ramdisk_path, f"segment_{j+1}_slow_{factor}.mp4")
                    
                    # Zpracování zpomalení a pitch pro každý segment
                    segment_audio_path = os.path.join(ramdisk_path, f"segment_{j+1}_temp_audio.wav")
                    seg_clip.audio.write_audiofile(segment_audio_path, codec='pcm_s16le')

                    pitched_audio_path = os.path.join(ramdisk_path, f"segment_{j+1}_new_temp_audio.wav")
                    audio_pitchup_ffmpeg(segment_audio_path, pitched_audio_path, factor)
                    
                    final_audio_path = os.path.join(ramdisk_path, f"segment_{j+1}_final_audio.wav")
                    change_audio_speed(pitched_audio_path, final_audio_path, factor, seg_clip.duration)
                    
                    new_audio_clip = AudioFileClip(final_audio_path)
                    edited_clip = seg_clip.set_audio(new_audio_clip)
                    edited_clip = edited_clip.fx(vfx.speedx, 1.0 / factor)
                    edited_clip.set_duration(edited_clip.duration)

                    print(f"Processing segment {j+1} with slowdown factor {factor} for file {file}. Saving to {output_segment_path}")
                    edited_clip.write_videofile(output_segment_path, codec="libx264", audio_codec="aac")
                    
                    segment_paths.append(output_segment_path)
                    edited_clip.close()
                    new_audio_clip.close()
                    
                    # Odstranění dočasných souborů
                    os.remove(segment_audio_path)
                    os.remove(pitched_audio_path)
                    os.remove(final_audio_path)
                
                # Sloučení zpracovaných segmentů do jednoho videa
                if segment_paths:
                    output_path = os.path.join(output_dirs[i], file)
                    final_clip = concatenate_videoclips([VideoFileClip(seg) for seg in segment_paths])
                    final_clip.write_videofile(output_path, codec="libx264", audio_codec="aac")
                    final_clip.close()

                    # Odstranění dočasných segmentů
                    for segment_path in segment_paths:
                        os.remove(segment_path)

print("Job done.")
if not ramdisk_disable:
    os.system(f'sudo umount "{ramdisk_path}"')

Žádné komentáře:

Okomentovat

Python: Mapování polských souborů pomocí českého překladu, vytvoření playlistu pro nalezený soubor

- Mapování polských souborů pomocí mapy s českým překladem. - fuzzywuzzy najde v českém překladu podobný název. - Následně se vybere správný...

Štítky

.profile adm administrace Adobe Aho-Corasick AI akcelerace alfa transparence analýza AND any aplikace apt ar archiv asociativní pole atomicity audacity audio audio redirect autentifikace awk balíčkovací systém bash beacon beacon_hint benchmark Bézierovy křivky bezpečnost biblehub BJT blogger boolean Braessův paradox brainstorming BRE buffer buffering bufferované čtení Cache-Conrol Cloudflare code Collector Cut-off ColorManager colorpicker common compare config cookies CPU CPU pipe crop css CSS3 curl current code cut čas data loss data lost data transfer reliability datasheet datetime.strptime deb deb-systemd-helper debian debián depricated development dict dioda diody disonance doprava dpkg dpkg -S dpkg-deb drivers EBO efekt Emitter Cut-off Current eps ETag evtest exclude exec Expires extrakce jediného extrakce názvu balíčku souboru extrakce obrázků extrakce souboru .deb fflock fflush ffmpeg FIFO file read file write file_get_contents file_get_contents/file_put_contents file_put_contents filter find first_install.sh flock Fly-back dioda font-face fonty fóra formant-preserving morphing fotorezistor fread functions funkce FuzzyWuzzy fwrite gate gate drive GDVfs gedit gedit-common geolokace getdata Ghostscript GIO glib gnome gnome settings GNU Privacy Guard gnupg gpg gradient-background grafika grep grep -v groupadd grub grub update gs gsettings gtk gtk.css gtk+ hebrejština history hlavičky HS html html 5 https hudba hunspell charakterizace chatGPT chroot chyba ICES IGBT Image img sizes img srcset impedance implementace imshow inference inkscape inrush current install IQ jalový výkon javascript javescript jednocení seznamů js jsonData kapacita součástek klávesnice koeficient zesílení komponenty xFce komunikace se serverem koncept konfigurace kontejner korekce barev Krita KSF kvantifikátor Last-Modified lazy caching led LEFT JOIN librosa ligatury light-locker lightdm linux list log m3u maják manuál map mapování maskování maskování hlasu maskování služby masky matplotlib Max-Age measure memory měření meta MFCC MFCC koeficienty mint Mint 21.3 Mint xFce míry modules moralizace morphologie MOSFET mount moviepy multimedia mysql náběhový proud napěťová ochrana nastavení šablony návod nel Network Error Logging NLP normalizace šedi po resize not Notifications NTFS nth-child oblasti oblékání ochrana okruhy přátel OpenVINO IR formát oprava oprava balíčku optočlen org.gnome.desktop.screensaver org.gnome.nm-applet ořezové masky OSHB otázky otázky_jazyky otázky_moralismu_řešení overlay ovladače panely parsování path pdf personifikace photorec php php 4 php 5 php 6 php 7 php 8 phpbb phpBB3 PipeWire pitch plus PN přechody pnp pole Policykit postscript práva profilování program prune průraz přeinstalování překlad přepěťová ochrana přepolování příkazy připojení k síti připojení k wifi pseudokódd pstoedit pulse PulseAudio PWM regulátory pydub python python3 pytorch ramdisk RBE RDSon read reaktance rectifier regex regulace vstupního napětí reinstall relyability remount replace restore reverzní geolokace RIGHT JOIN rm robotický hlas role rozvržení disků pro OS linux a data databází řešení samba scan scroll sdílení sdílení souborů Sec-Fetch-Dest Sec-Fetch-Mode Sec-Fetch-Site Sec-Fetch-User Secure Shell sed Set Cookie show-manual-login show-remote-login shunt schemas schémata schottka signal morphing sink skript skupiny sledovanost sloupce slučování seznamů služby small song sort soubory soundfile spínané zdroje spínání splines split spojování správa diskových zařízení SQL ssh stabilizace napětí stahování stíny stream stream redirect string strojové učení stropové učení subprocess.call supplicant svg syntax systemctl systemd-logind T5 tabulka tabulky Tangentové úsečky tar témata tepelná ztráta terminologie test text-shadow themes thermal runaway time timestamp tkinter tr transformace transistor transition transpose tranzistor tranzistory ttf tuple tvorba otázek TVS typografie ubuntu účiník udiskd udisks unconfined underrun unity-greeter update usermod uživatelé va charakteristika vala věda vektorová grafika Vgs video virtual devices vocoder Vth vyhledávání vyhledávání soborů výkon vynechání adresářů vytvoření playlistu vývoj while wpa wpa_supplicant wrapovací funkce x xandr xapp-watt xargs -I xed xed-common xfdesktop xml xmp XOR Xorg Xorg Thumbnails xrandr závislosti zdánlivý výkon zdroj zenerka zenerovo napětí zip zip archiv zkratky zpomalení zpracování textu zrychlení zvuk Žalmy