Zobrazují se příspěvky se štítkempython3. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkempython3. Zobrazit všechny příspěvky

neděle 10. srpna 2025

Program na vykreslení disonančních frekvencí (matplotlab)

Python 3


import librosa
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from dissonant import dissonance

# Načtení zvuku
y, sr = librosa.load("akord.wav")
freqs = librosa.fft_frequencies(sr=sr)
amps = np.abs(librosa.stft(y))

# Výpočet disonance (použijeme max pro lepší detekci vrcholů)
d = dissonance(freqs, amps.max(axis=1), model='sethares1993')

# Přizpůsobení dat pro 3D graf
x, y = np.meshgrid(freqs, freqs)
z = np.zeros_like(x)  # Inicializace nulovou maticí
num_elements = min(len(d), z.size)  # Omezit na dostupné prvky
z.flat[:num_elements] = d[:num_elements]  # Naplnění disonančními hodnotami

# Vytvoření 3D grafu
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(x, y, z, cmap='coolwarm')
ax.set_xlabel('Frekvence (Hz)')
ax.set_ylabel('Frekvence (Hz)')
ax.set_zlabel('Disonance')
plt.title("Disonance akordu")
plt.show()
 
Níže je upravený kód, který umožňuje přidat více akordů (zvukových souborů WAV) do seznamu, iteruje přes a vykresluje je jako oddělené vrstvy v 3D grafu. Každý akord bude mít jinou barvu nebo průhlednost pro rozlišení.
 
 
import librosa
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from dissonant import dissonance

# Seznam souborů s akordy
chord_files = ["akord1.wav", "akord2.wav", "akord3.wav", "akord4.wav"]  # Přidejte své soubory

# Inicializace grafu
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# Iterace přes všechny akordy
for i, file in enumerate(chord_files):
    # Načtení zvuku
    y, sr = librosa.load(file)
    freqs = librosa.fft_frequencies(sr=sr)
    amps = np.abs(librosa.stft(y))

    # Výpočet disonance
    d = dissonance(freqs, amps.max(axis=1), model='sethares1993')

    # Přizpůsobení dat pro 3D graf
    x, y = np.meshgrid(freqs, freqs)
    z = np.zeros_like(x)
    num_elements = min(len(d), z.size)
    z.flat[:num_elements] = d[:num_elements]

    # Vykreslení povrchu s různou barvou a průhledností
    surf = ax.plot_surface(x, y, z, cmap='coolwarm', alpha=0.5 - 0.1 * i, label=f'Akord {i+1}')
    ax.legend()

# Nastavení os a titulu
ax.set_xlabel('Frekvence (Hz)')
ax.set_ylabel('Frekvence (Hz)')
ax.set_zlabel('Disonance')
plt.title("Disonance více akordů")
plt.show()
 
 

pondělí 30. června 2025

Jak sloučit dva seznamy v Pythonu pomocí zip a +

Tenhle kód slouží ke sloučení dvou samostatně získaných seznamů výsledků („autorská jména“ a „slova týkající se studií“) do jednoho seznamu pro každou zprávu. Podívejme se krok po kroku:

combined = []
for authors_list, studies_list in zip(raw_authors, raw_studies):
    combined.append(authors_list + studies_list)
  1. raw_authors a raw_studies jsou oba seznamy, kde každá položka odpovídá jedné zprávě:

    • raw_authors[i] je seznam autorů, které jsme našli v i‑té zprávě.

    • raw_studies[i] jsou klíčová slova „studie/analýza“ z téže i‑té zprávy.

  2. zip(raw_authors, raw_studies):

    • zip vezme dva (nebo více) seznamy a vrátí iterátor, který postupně dává dvojice prvků z každého seznamu se stejným indexem.

    • První iterace: vezme raw_authors[0] a raw_studies[0]

    • Druhá iterace: vezme raw_authors[1] a raw_studies[1]

    • A tak dále, až do konce kratšího z těch dvou původních seznamů.

  3. for authors_list, studies_list in zip(...):

    • V každém kroku smyčky se authors_list rovná seznamu autorů z jedné zprávy a studies_list seznamu studií z té samé zprávy.

  4. authors_list + studies_list:

    • V Pythonu se dva seznamy dájí sloučit operátorem +. Výsledkem je nový seznam, který obsahuje všechny položky z authors_list, a za ně všechny položky z studies_list.

  5. combined.append(...):

    • Tento sloučený seznam (autoři i studie v jedné zprávě) se přidá jako další položka do seznamu combined.

Výsledek

  • combined je seznam seznamů:

    combined = [
      ['Joshua Harris', 'Leslie Ludy', 'Studie'],
      ['John Alexander Dowie', 'Analýza'],
      ['Frank Sandford', 'Studie', 'Metaanalýza'],
      ...
    ]
    

    Každý vnitřní seznam obsahuje nejprve jména autorů a potom klíčová slova studií z jedné zprávy.

  • Tyto sloučené položky pak můžeš naformátovat (format_message_results) a deduplikovat (deduplicate), aby ses v exportu vždy dozvěděl, kteří autoři a studie se v dané zprávě vyskytly.

Proč se to nemůže zapsat takto

for authors_list, studies_list in (raw_authors, raw_studies)?

Výborná otázka! 🔍

Krátká odpověď:
for authors_list, studies_list in (raw_authors, raw_studies) nejde použít, protože (raw_authors, raw_studies) je dvojice (tuple) dvou seznamů, ne dvojice položek.


📌 Co se opravdu děje ve dvou případech:

❌ Špatná verze:

for authors_list, studies_list in (raw_authors, raw_studies):
  • (raw_authors, raw_studies) je n-tice dvou seznamů – tedy:

    ([...], [...])  # tuple
    
  • Cyklus se pokusí iterovat přes tu n-tici, která má jen dvě položky:

    • První průchod: authors_list = raw_authors, ale studies_list = ??? – chybí!

    • Dojde k chybě: ValueError: not enough values to unpack (expected 2, got 1)

✅ Správná verze:

for authors_list, studies_list in zip(raw_authors, raw_studies):
  • zip(raw_authors, raw_studies) vytvoří iterátor dvojic:

    [ (raw_authors[0], raw_studies[0]),
      (raw_authors[1], raw_studies[1]),
      ... ]
    
  • Tohle je přesně to, co for authors_list, studies_list in ... očekává – dvojice na každém řádku smyčky.


🔎 Shrnutí:

Konstrukce Co to znamená Funkční?
(raw_authors, raw_studies) Tuple dvou seznamů ❌ Ne
zip(raw_authors, raw_studies) Iterátor dvojic (každá dvojice odpovídá indexu) ✅ Ano

Chceš-li, mohu ti to ukázat na mini příkladu s výpisem.

 

pondělí 23. června 2025

Python: Rozdíl mezi přidáním a rozšířením pole - append vs extend'!

 

Výborná otázka – pojďme si vysvětlit rozdíl mezi append() a extend() a proč je v tomto konkrétním případě správné použít extend().


🔍 append() vs extend():

Funkce Co dělá Příklad
append(x) Přidá celý objekt x jako jeden prvek [1, 2].append([3, 4]) → [1, 2, [3, 4]]
extend(x) Přidá všechny prvky ze sekvence x jednotlivě [1, 2].extend([3, 4]) → [1, 2, 3, 4]

📘 Co přesně děláš ve funkci?

Ve funkci získáváš children ze node:

children = node.get("children", [])

Hodnota children je seznam ID potomků daného uzlu (např. ["abc123", "def456"]). Tím pádem:

❌ Pokud bys použil:

root_chat.append(children)

Výsledek bude:

root_chat = [["abc123", "def456"]]  # špatně – seznam v seznamu

✅ Ale pokud použiješ:

root_chat.extend(children)

Výsledek bude:

root_chat = ["abc123", "def456"]  # správně – seznam ID

🔧 Shrnutí:

Použij extend() pokud chceš slít obsah seznamu do jiného seznamu, nikoli vnořit seznam jako prvek. Ve tvém případě pracuješ s ID uzlů a očekáváš plochý seznam všech potomků určitého typu (root_chat, user_chat, assistant_chat).


Můj příklad pro json:

        for idx, session in enumerate(data, 1):
            title = session.get("title", "<bez názvu>")
            ct = session.get("create_time")
            if isinstance(ct, (int, float)):
                dt = datetime.fromtimestamp(ct)
                ct_str = dt.strftime("%Y-%m-%d %H:%M:%S")
            else:
                ct_str = str(ct)

            #  root
            #   └── node A (system message)
            #         └── node B (user message)  <--- tu chceš najít
            #               └── node C (assistant)

            mapping = session.get("mapping", {})
            root = next((nid for nid,node in mapping.items() if node.get("parent") is None), None)
            children = mapping.get(root, {}).get("children", [])
            root_first_id = None
            user = None
            root_chat = []
            user_chat = []
            assistant_chat = []
            for nid, node in mapping.items():
                if root is None and node.get("parent") is None:
                    root_first_id = nid
                role = node.get("author").get("role")
                children = node.get("children", [])  # children obsahuje seznamy ideček
                if role == "system":
                    root_chat.extend(children) else:
                if role == "user":
                    user_chat.extend(children) else:
                if role == "assistant":
                    assistant_chat.extend(children)


sobota 14. června 2025

Test5 - Volání ve skriptu + popis volání a resize po implementaci simulace draw

process_images()
 └─ for each image:
     ├─ create_thumbnail_with_regions()
     │   ├─ binarize_shadow() → bl_bw, tr_bw
     │   ├─ locate_region_and_source()
     │   │   └─ project_and_find_shadow_ranges()
     │   │       ├─ normalize_projection_manual(row_proj)
     │   │       ├─ find_intervals(vals, ShadowType)
     │   │       ├─ normalize_projection_manual(col_proj)
     │   │       └─ find_intervals(vals, ShadowType)
     │   └─ return bl_small, bl_crop, tr_small, tr_crop, thumbnail, bl_box, tr_box
     ├─ locate_region_and_source(bl_bw, tr_bw, bl_crop, tr_crop, …)
     └─ detect_angle_from_crops(bl_small, bl_crop, tr_small, tr_crop, thumbnail, full_img, bl_box, tr_box)

 

Pipeline volání

  1. create_thumbnail_with_regions(img, output_path, regions, estimated_dpi, debug_simulate_shadow)
    └─ best_divisor(width, height, estimated_dpi)
    └─ resize → thumbnail
    └─ get_dimensions_for_cropped_areas(regions, thumbnail_size, divisor)bl_box, tr_box
    └─ crop → bl_crop, tr_crop
    └─ compute_small_image_and_divisor(bl_crop, est_shadow_thumb_px)bl_small, bl_div
    └─ compute_small_image_and_divisor(tr_crop, est_shadow_thumb_px)tr_small, tr_div
    └─ binarize_shadow(bl_small)bl_bw
    └─ binarize_shadow(tr_small)tr_bw
    └─ if debug_simulate_shadow: simulate_and_measure_thresholds(region_size, debug_folder, label, best_divisor, div_factor, orientations)

  2. locate_region_and_source(bl_bw, tr_bw, bl_crop, tr_crop, thumbnail, full_img, bl_box, tr_box, bl_div, tr_div, small_capacity_bl, small_capacity_tr, est_shadow_thumb_px, output_path)
    └─ project_and_find_shadow_ranges(bl_bw, tr_bw, …, output_path)
    │ └─ for ("small_bl", bl_bw) and ("small_tr", tr_bw):
    │ └─ resize → row_proj, col_proj
    │ └─ normalize_projection_manual(row_proj, w)img_norm, scale, offset
    │ └─ find_intervals(vals, ShadowType.DARK|GRAY)*_dark_row, *_gray_row
    │ └─ normalize_projection_manual(col_proj, h)img_norm, scale, offset
    │ └─ find_intervals(vals, ShadowType.DARK|GRAY)*_dark_col, *_gray_col
    │ └─ intersect_intervals(row_intervals, col_intervals, ShadowType.DARK|GRAY)*_regions_dark, *_regions_gray
    │ └─ save regions in debugging_bl / debugging_tr
    │ └─ return results
    └─ compute kapacita_small_bl, kapacita_small_tr, kapacita_thumbnail
    └─ append candidates in order small_bl, small_tr, crop_bl, crop_tr, thumbnail, full
    └─ return {"candidates": …}, resolution_info

  3. detect_angle_from_crops(bl_small, bl_crop, tr_small, tr_crop, thumbnail, full_img, bl_box, tr_box)
    └─ compute capacities
    └─ in order small_bl → small_tr → crop_bl → crop_tr → thumbnail → full:
    │ └─ measure_angle_and_length(crop_img, threshold_px)angle, length
    │ └─ if angle found → compute regionreturn result dict
    └─ return last result or fallback with angle=None

 TABULKA S VYSVĚTLENÍM

 

Proměnná Vypočítává/definuje se v Používá se v Vysvětlení použití Vazba a konzistence
divisor create_thumbnail_with_regions tamtéž Dělí originální rozměry (width, height) pro zmenšení na thumbnail. Volí se tak, aby výsledný DPI thumbnailu byl blízko cílových 300 dpi → ovlivňuje všechny další úrovně.
scale_factor create_thumbnail_with_regions tamtéž Poměr new_width/width = 1/divisor; škáluje souřadnice regionů z originálu do thumbnailu. Je přesně obrácenou hodnotou divisor (v reálných pixelech) → zajišťuje korektní překlad oblastí.
bl_div / tr_div create_thumbnail_with_regions tamtéž + simulate_and_measure_thresholds Dělí bl_crop a tr_crop pro vytvoření „small“ obrázků (bl_small, tr_small). bl_div, tr_div by měly být stejné řády jako divisor (např. ∼10) pro konzistentní zmenšování věrné DPI.
scale (normalizace) normalize_projection_manual project_and_find_shadow_ranges, simulate_and_measure_thresholds Kompenzuje jak intenzitu (255/(mx–mn)), tak zředění (original_length/L_proj) po projekci. Závisí na poměru původní délky řady/sloupce k délce po resize → zajišťuje konzistentní prahování stínu.
offset (normalizace) normalize_projection_manual project_and_find_shadow_ranges, simulate_and_measure_thresholds Posun původního minima, které bylo „odečteno“ při normalizaci. Společně se scale vytváří konzistentní mapování původních intenzit na [0–255] i napříč různými velikostmi.

POZNÁMKY:

"Zředění" - zředění je zjednodušující výraz pro vedlejší efekt projekce, kdy se intenzity šedi při zmenšení na jednorozměrné pole zprůměrují, a šedá nebo černá vybledne.

Normalizace (po projekci do 1D obrazu): Míra zesílení intenzit v obrazu je závislá na tom jak moc se původní strana zmenšila a taky na tom jaká je minimální a maximální hodnota intenzity v tom obrazu.

Normalizace pak dvoufázově kompenzuje:
1. intenzitu – škála = 255/(max–min), aby nejtmavší byl → 0 a nejsvětlejší byl → 255,
2. zředění – násobek = (původní délka)/(délka projekce), čímž se vyrovná efekt průměrování přes různý počet pixelů.

Společně scale = (255/(mx–mn)) × (original_length/L_proj) a offset = mn zajistí, že 1D obraz vrátí správné relativní rozložení stínu nezávisle na tom, jak moc byl zmenšený.

Úskalí po normalizaci

Poté co byla provedena normalizace 1D obrazu, už neplatí, že by barvy stínu, které byly vizuálně přečteny z původního small náhledu (např. v grafickém editoru), byly totožné s nově vygenerovaným stínem normalizovaného souboru. K tomu by bylo nutné provést přepočet nebo test. Takže pro nalezení hranic šedi jak definuje třída:

class ShadowRanges(Enum):
    DARK_MAX = 188
    GRAY_MIN = 189
    GRAY_MAX = 232
    BLACK = 0
    WHITE = 255

by bylo nutné použít přepočet. Pro ověření funkce pro přepočet a doladění nastavení scriptu vzniká funkce pro simulaci.


 



pátek 30. května 2025

Kód pro opravu barev na nascanovaném dokumentu

Kód má mírně stáhnout modrou barvu (což není přesně co jsem chtěl - na původním obrázku se trochu odráží modré LED světlo, tak jsem to chtěl stáhnout). Nicméně to by bylo třeba vybrat jen ty pixely kde je ta modrá barva a neaplikovat to na celý dokument. Nastavení kontrastu je pro dokument, který má nízký kontrast.

 

from PIL import Image, ImageEnhance
import os
import glob

# Funkce pro úpravu obrázku
def adjust_image(image_path, output_path):
    # Otevření obrázku
    img = Image.open(image_path).convert("RGB")
    
    # 1. Odstranění modrého nádechu (snížení modrého kanálu)
    r, g, b = img.split()
    # Snížíme intenzitu modrého kanálu (např. o 20 %)
    b = b.point(lambda x: int(x * 0.8))
    img = Image.merge("RGB", (r, g, b))
    
    # 2. Zesvětlení pozadí a zvýšení kontrastu pro tmavší text
    # Převod na šedotón (pro OCR je lepší černobílé zobrazení)
    img = img.convert("L")
    
    # Úprava jasu (zesvětlení středních tónů)
    enhancer = ImageEnhance.Brightness(img)
    img = enhancer.enhance(1.2)  # Mírné zesvětlení (1.2 je jemná úprava)

    # Úprava kontrastu
    enhancer = ImageEnhance.Contrast(img)
    img = enhancer.enhance(2.0)  # Zvýšíme kontrast (hodnota 2.0 je dobrý základ)
    
    # Úprava jasu (zesvětlení středních tónů)
    enhancer = ImageEnhance.Brightness(img)
    img = enhancer.enhance(1.4)  # Mírné zesvětlení (1.2 je jemná úprava)
    
    # Uložení upraveného obrázku
    img.save(output_path, "JPEG")
    print(f"Upravený obrázek uložen jako: {output_path}")

# Hlavní funkce pro zpracování všech obrázků v adresáři
def process_images(input_folder, output_folder):
    # Vytvoření výstupní složky, pokud neexistuje
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    # Najdeme všechny JPG soubory v input složce
    image_files = glob.glob(os.path.join(input_folder, "*.jpg"))
    
    # Zpracujeme každý obrázek
    for image_path in image_files:
        # Vytvoříme název výstupního souboru
        filename = os.path.basename(image_path)
        output_path = os.path.join(output_folder, f"adjusted_{filename}")
        
        # Upravíme obrázek
        adjust_image(image_path, output_path)

# Spuštění skriptu
if __name__ == "__main__":
    # Nastavte cestu k adresáři s vyextrahovanými obrázky a výstupní složku
    input_folder = "/home/user/Dokumenty/Knihy/scan music theory 1/test"  # Nahraďte cestou k vašim obrázkům
    output_folder = "/home/user/Dokumenty/Knihy/scan music theory 1/output"  # Nahraďte cestou k výstupní složce
    
    # Zpracujeme obrázky
    process_images(input_folder, output_folder)




Kód pro extrakci nascanovaných obrázků z poškozeného .pdf

Soubor byl poškozen ve smyslu, že nebyl dokončen zápis .pdf pro nedostatek místa na disku. První skript najde začátky streamů se značkou JFIF a druhý provádí extrakci těch fotek.

# Import potřebných knihoven
import re

# Otevření PDF souboru v binárním režimu
with open('music theory part 3.pdf', 'rb') as file:
    content = file.read()  # Načtení obsahu souboru

# Vyhledání pozic řetězce "stream"
positions = [m.start() for m in re.finditer(b'stream', content)]

# Tisk prvních dvaceti bajtů od každé nalezené pozice
for pos in positions:
    start = pos  # Pozice začátku řetězce "stream"
    end = start + 20  # Konec prvních dvaceti bajtů
    print(f'Pozice: {pos}, Prvních 20 bajtů: {content[start:end]}')


EXTRAKCE

import re

# Funkce pro extrakci obrázků
def extract_images(pdf_file):
    with open(pdf_file, 'rb') as file:
        content = file.read()  # Načtení obsahu souboru

    # Procházení všech výskytů "stream"
    for match in re.finditer(b'stream', content):
        start = match.start()  # Pozice začátku "stream"
        
        # Tisk pozice a prvních 20 bajtů od "stream"
        print(f'Pozice: {start}, Prvních 20 bajtů: {content[start:start + 20]}')
        
        # Hledání konce streamu (použijeme "endstream" místo "endobj" pro přesnost)
        endstream_match = re.search(b'endstream', content[start:])
        if endstream_match:
            # Začátek obrazových dat je po "stream\n"
            newline_pos = content.find(b'\n', start)
            if newline_pos == -1:
                continue  # Pokud není newline, přeskočíme
            data_start = newline_pos + 1
            data_end = start + endstream_match.start()  # Konec před "endstream"
            image_data = content[data_start:data_end]
            
            # Kontrola, zda je to platný JPEG (začíná \xff\xd8)
            if image_data.startswith(b'\xff\xd8'):
                # Uložení obrázku
                with open(f'image_{start}.jpg', 'wb') as img_file:
                    img_file.write(image_data)
                print(f'Obrázek uložen: image_{start}.jpg')

# Spuštění funkce s vaším PDF souborem
extract_images('music theory 2 - chordsn rhytms.pdf')



 

čtvrtek 8. května 2025

Zrychlení videa mp4 se zachováním původního pitch / tóniny

TENTO KOD JSEM OVĚŘIL A SKUTEČNĚ FUNGUJE.

import subprocess

# Vstupní video a seznam požadovaných rychlostí
input_file = '/home/user/Videa/LOOP-tremolo-song-training-200-120-bpm.mp4'
bpm_speeds = {
    '350_BPM': 2.92,
    '352_BPM': 2.93,
    '354_BPM': 2.95,
    '357_BPM': 2.975,
    '356_BPM': 2.967,
    '358_BPM': 2.983
}

for label, ratio in bpm_speeds.items():
    output_file = f'/home/user/Videa/LOOP-tremolo-song-training-{label}.mp4'
    
    cmd = [
        'ffmpeg', '-y', '-i', input_file,
        '-filter_complex',
          # zrychlíme obraz i zvuk najednou
          f"[0:v]setpts=PTS/{ratio}[v];"
          f"[0:a]rubberband=tempo={ratio}[a]",
        '-map', '[v]', '-map', '[a]',
        '-c:v', 'libx264', '-preset', 'fast', '-crf', '23',
        '-c:a', 'aac', '-b:a', '192k',
        output_file
    ]
    
    print(f"Spouštím zpracování {label} (faktor {ratio})…")
    subprocess.run(cmd, check=True)
    print(f"✔ Hotovo: {output_file}\n")

sobota 24. srpna 2024

Skript na export částí videa a jejich zpomalení - obsahuje vadu (copyright Radek Šimánek)

Tento kod vychází ze skriptu pro zpomalení videa a zachování tónů

Původní kód je zde (autor Radek Šimánek)

Tento kód jsem otestoval a je funkční. Zpomalil jsem videa s extrémně rychlým finger-pickingem.

# 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 = "/Flamenco-finger-picking-rhythm"
input_dir = os.path.join("/media/toshiba/home/user/Videa", default_path)

file = 'Paola Hermosin a melodie od Aurelio Almonte 5 04 a 5 23-5 30.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, 3, 4, 5, 6, 8, 10]

# 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 = [
    ("5:04", "5:08.75"),
    ("5:11.75", "5:17.00"),
    ("5:23.40", "5:31.27")
]

# 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}"')

Nápověda 

Změny a funkce skriptu:

  1. Deaktivace RAM disku: Použil jsem proměnnou ramdisk_disable, která když je nastavena na True, neprovádí operace související s RAM diskem.

  2. Vyexportování a spojení časových úseků: Skript nyní používá funkci subclip() z moviepy, aby vybral specifikované časové úseky z videa. Tyto úseky jsou následně spojeny pomocí concatenate_videoclips(), a vytvoří se dočasný sloučený soubor temp_joined.avi.

  3. Zpomalení videa: Po vytvoření dočasného sloučeného souboru jsou použity zpomalovací faktory k vytvoření výsledných videí.

  4. Uzavírání streamů: Každý otevřený klip (vstupní i dočasné) je správně uzavřen pomocí close(), aby se předešlo konfliktům při čtení a zápisu do souborů.

automad je dobrý cms na vytváření flat-file blokových prezentací

 automad je dobrý cms na vytváření flat-file blokových prezentací

Š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 automad automatizace 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 cms 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 editace 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 flat-file 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 kytara 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 melodie memory měření meta MFCC MFCC koeficienty mint Mint 21.3 Mint xFce míry mlt modules moralizace morphologie MOSFET mount moviepy multimedia mysql náběhový proud napěťová ochrana nastavení šablony návod návrh nel Network Error Logging NLP normalizace šedi po resize not Notifications noty 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í 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 redakční systém 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 karta 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 TS ttf tuple tvorba otázek TVS typografie ubuntu účiník udiskd udisks unconfined underrun unity-greeter update usb 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 webovka 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