[PYTHON] Ich möchte automatisch hochwertige Teile aus den von mir aufgenommenen Videos finden

Was du machen willst

Ansatz

Beziehung

Quelle

Eingang

Ausgabe (Wenn Sie es tatsächlich verwenden, kombinieren Sie die folgenden zwei Dateien mit ffmpeg oder einer Videobearbeitungssoftware.)

cut_movie.py


import datetime
import os

import cv2
import librosa
import numpy as np
import scipy


#Eine Funktion, die auf nette Weise an die Konsole ausgegeben werden kann. Es muss nicht sein.
def pretty_print_sec(sec):
    int_sec = int(sec)

    hour = int_sec // 3600
    left_sec = int_sec - hour * 3600
    minute = left_sec // 60
    left_sec = left_sec - minute * 60

    hour_str = ("00" + str(hour))[-2:]
    min_str = ("00" + str(minute))[-2:]
    sec_str = ("00" + str(left_sec))[-2:]

    return ":".join([hour_str, min_str, sec_str])


#Funktion zum Überprüfen, ob die Zielanzahl von Sekunden das Ziel des Clippings ist
def is_in(tuple_list, val):
    for tup in tuple_list:
        if tup[0] <= val <= tup[1]:
            return True

    return False


#Verwenden Sie diese Option beim Zuschneiden basierend auf dem Maximalwert
def cut_by_max_rms(rms, percentile):

    is_on = False

    start = 0
    end = 0

    threshold = np.percentile(rms[0], percentile)
    cut_list = []

    #Wenn der vorherige Frame auch zum Zuschneiden ausgewählt wurde, kombinieren Sie die Zuschneidebereiche
    for i, val in enumerate(rms[0]):
        if val >= threshold and is_on:
            pass
        elif val >= threshold and not is_on:
            is_on = True
            start = float(i) * 30
        elif val < threshold and is_on:
            end = float(i) * 30
            is_on = False
            cut_list.append((start, end))
        else:
            pass

    if is_on:
        cut_list.append((start, float(i + 1) * 30))

    return cut_list


#Verwenden Sie dies für die maximale Punktbasis
def cut_by_local_max_rms(rms, max_frame_num):

    cut_list = []

    order = 1
    while True:
        pts = list(scipy.signal.argrelmax(rms[0], order=order)[0])

        if len(pts) < max_frame_num:
            break

        order += 1

    for point in pts:
        cut_list.append((point * 30, (point + 1) * 30))

    return cut_list


#Identifizierung der Aussparungsstelle
#Je nach Lautstärke ausschneiden
def decide_cut_frames(cut_type, voice_file):
    #Laden Sie Audio, um Pflanzen zu identifizieren
    #Ich möchte es so leicht wie möglich machen, also lese ich es mit einer Abtastrate von 8000
    y_voice, sr_voice = librosa.load(voice_file, sr=8000, mono=True)

    #Überprüfen Sie die Lautstärke alle 30 Sekunden
    rms = librosa.feature.rms(
        y=y_voice,
        frame_length=sr_voice * 30,
        hop_length=sr_voice * 30,
        center=True,
        pad_mode="reflect",
    )

    if cut_type == "local_max":
        #Die Lautstärke ist maximal(Wo der Gipfel steht)Wählen Sie bis zu 20 Bilder aus und schneiden Sie sie aus
        cut_list = cut_by_local_max_rms(rms, 20)
    elif cut_type == "max":
        #Top 5 am lautesten%Schneiden Sie den Rahmen aus
        cut_list = cut_by_local_max_rms(rms, 100 - 95)

    return cut_list


#Videoausschnitt
def cut_movie(cut_list, movie_file, output_movie_file):

    movie = cv2.VideoCapture(movie_file)
    fps = movie.get(cv2.CAP_PROP_FPS)
    height = movie.get(cv2.CAP_PROP_FRAME_HEIGHT)
    width = movie.get(cv2.CAP_PROP_FRAME_WIDTH)
    print(fps, int(width), int(height))

    #Format bei der Ausgabe
    #Beachten Sie, dass sich dies je nach Betriebssystem ändern kann
    fourcc = cv2.VideoWriter_fourcc(*"mp4v")

    #Wenn es bereits vorhanden ist, tritt ein Fehler auf. Löschen Sie ihn daher einmal.
    if os.path.exists(output_movie_file):
        os.remove(output_movie_file)

    out = cv2.VideoWriter(
        output_movie_file, fourcc, int(fps), (int(width), int(height))
    )

    for start, end in cut_list:
        i = start * fps
        movie.set(0, start * 1000)

        #Lesen Sie Frame für Frame von Anfang bis Ende, wenn das Ende überschritten wird
        while movie.isOpened():
            sec = float(i / fps)
            if sec % 60 == 0:
                print(pretty_print_sec(sec), datetime.datetime.now(), flush=True)

            ret, frame = movie.read()
            if not ret:
                break

            #Fügen Sie Text für die aktuelle Zeit hinzu
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(
                frame,
                pretty_print_sec(sec),
                (10, int(height * 0.9)),
                font,
                1,
                (0, 255, 0),
                2,
                cv2.LINE_AA,
            )

            if is_in(cut_list, sec):
                out.write(frame)

            i += 1
            if sec > end:
                break

    movie.release()
    out.release()


#Audio-Zuschnitt
def cut_audio(cut_list, voice_file, output_audio_file):

    #Beachten Sie, dass sr 22050 ist, wenn Keine angegeben ist.
    y_full, sr_full = librosa.load(voice_file, sr=None, mono=False)

    output_array = [[], []]
    for start, end in cut_list:
        for i in range(int(start * sr_full), int(end * sr_full) + 1):
            val_0 = y_full[0, i]
            val_1 = y_full[1, i]

            sec = float(i / sr_full)
            if sec % 60 == 0:
                print(pretty_print_sec(sec), datetime.datetime.now(), flush=True)

            if is_in(cut_list, sec):
                output_array[0].append(val_0)
                output_array[1].append(val_1)

            if sec > end:
                break

    #Fallen Sie, wenn Sie kein Fortranarray verwenden
    librosa.output.write_wav(
        output_audio_file, np.asfortranarray(output_array), sr_full
    )


def main():
    audio_file = "full.mp3"  #Extrahiertes Video-Audio
    voice_file = "voice.wav"  #Nur Sprache aus Video extrahiert
    movie_file = "full.mp4"

    output_audio_file = "cut.wav"
    output_movie_file = "cut.mp4"

    cut_type = "local_max"  #Maximalwertbasis
    # cut_type = "max" #Maximalwertbasis

    cut_list = decide_cut_frames(cut_type, voice_file)
    cut_movie(cut_list, movie_file, output_movie_file)
    cut_audio(cut_list, audio_file, output_audio_file)


if __name__ == "__main__":
    main()

Bemerkungen

Recommended Posts

Ich möchte automatisch hochwertige Teile aus den von mir aufgenommenen Videos finden
Ich möchte die zulässige Ausfallzeit aus der Betriebsrate berechnen
Ich möchte Spyder an die Taskleiste anheften
Ich möchte kühl auf die Konsole ausgeben
Ich möchte mit dem Reim Teil1 umgehen
Ich möchte mit dem Reim part3 umgehen
Ich möchte ein Glas aus Python verwenden
Ich möchte den Fortschrittsbalken anzeigen
Ich möchte mit dem Reim part2 umgehen
Ich möchte mit dem Reim part5 umgehen
Ich möchte mit dem Reim part4 umgehen
Ich möchte nur ein Signal vom Sub-Thread zum Haupt-Thread senden
Ich möchte aus verschiedenen Sprachen eine Verbindung zu PostgreSQL herstellen
Ich möchte mit Python eine E-Mail von Google Mail senden.
[Python] Ich möchte 7DaysToDie von Discord aus verwalten! 1/3
Ich möchte mit dem Reim part7 (BOW) umgehen
Ich möchte Passungen aus meinem Kopf machen
Ich möchte Ceres Solver aus Python verwenden
[Python] Ich möchte 7DaysToDie von Discord aus verwalten! 2/3
Ich möchte leicht einen leckeren Laden finden
Ich möchte C ++ - Code aus Python-Code erstellen!
Ich möchte das Erscheinungsbild von zabbix anpassen
Ich möchte die Aktivierungsfunktion Mish verwenden
Ich möchte den Fortschritt in Python anzeigen!
[LINE Messaging API] Ich möchte eine Nachricht vom Programm an alle LINE senden
[Ansible] Ich möchte meine eigene Funktion über das Vorlagenmodul (Makro) aufrufen.
Ich möchte Bilder von Katzen von Instagram erkennen
Ich habe versucht, Iris aus dem Kamerabild zu erkennen
Ich möchte das Ausführungsergebnis von strace erfassen
Ich möchte in der Django-Verschiebungstabelle scrollen, aber ...
[Python] Ich habe ein System erstellt, um "das Rezept, das ich wirklich will" von der Rezeptseite einzuführen!
Ich möchte ein beliebtes Paket auf PyPi finden
Ich wollte die Python-Bibliothek von MATLAB verwenden
Ich möchte mit Python-Datenklasse nach hinten erben
Ich möchte die Grundlagen von Bokeh vollständig verstehen
Ich möchte nur das 95% -Konfidenzintervall des Unterschieds im Bevölkerungsverhältnis in Python ermitteln
Ich möchte in Python schreiben! (3) Verwenden Sie Mock
Ich möchte automatisch eine Unternehmensgründungs-E-Mail senden
Ich möchte mit dem Reim part6 umgehen (einmal organisieren)
Ich möchte ssh mit dem Befehl expected automatisieren!
Ich möchte das Produkt zu den niedrigsten Kosten veröffentlichen
Ich habe die Chainer-Referenz gelesen (von Zeit zu Zeit aktualisiert).
Ich möchte R-Datensatz mit Python verwenden
Ich möchte mit dem Reim part8 umgehen (einmal fertig)
Ich möchte Wake On LAN vollautomatisch ausführen
Ich möchte die Sicherheit der SSH-Verbindung erhöhen
Ich möchte das symbolische Linkziel von / lib64 unter CentOS von / usr / lib64 in / my-lib64 ändern
Ich möchte den Schnittpunkt einer Bezier-Kurve und einer geraden Linie finden (Bezier-Clipping-Methode)
Ich habe ein Tool erstellt, um automatisch ein einfaches ER-Diagramm aus der Anweisung CREATE TABLE zu generieren
[Selenium] Ich möchte den Browser anzeigen, indem ich den Treiber auf dem Host-Betriebssystem von WSL aus drücke
Ich habe versucht, den Trend der Anzahl der Schiffe in der Bucht von Tokio anhand von Satellitenbildern zu ermitteln.
Ich habe versucht, die Umrisse von Big Gorilla herauszufinden
[TensorFlow] Ich möchte die Indizierung für Ragged Tensor beherrschen
Ich möchte das neueste gcc verwenden, auch wenn ich keine Sudo-Berechtigungen habe! !!
Ich möchte die von LINE an S3 gesendeten Fotos speichern
Ich habe versucht, mit TensorFlow den Durchschnitt mehrerer Spalten zu ermitteln