[PYTHON] Mit Amazon Transcribe erstellte Untertiteldaten

Auslösen

Ich kaufte eine DVD-Box mit dem Titel "Mayday !: Die Wahrheit und Wahrheit von Flugzeugunfällen" (englischer Titel Air Crash Investigation). Es ist eine englische Version, aber ich dachte, es würde Untertitel geben, aber ich hatte nicht einmal englische Untertitel ...

Glücklicherweise wurde die Zugriffskontrolle durch CSS (Content Scramble System) nicht angewendet, also habe ich versucht, irgendwie Untertitel zu erstellen.

Was ich getan habe

  1. Extrahieren Sie nur Audio aus Videodaten (ffmpeg)
  2. Transkribieren Sie aus Sprachdaten (Amazon Transcribe)
  3. Konvertieren Sie das Transkriptionsergebnis in SubRip-Untertiteldaten (Python).
  4. Untertiteldaten in Videodaten einbetten (mkvmerge)

Installation der notwendigen Werkzeuge

Für macOS können Sie es mit Homebrew installieren. Voraussetzung ist auch, dass Sie Python 3 und pip verwenden können.

brew install ffmpeg mkvtoolnix
pip3 install boto3

1. Extrahieren Sie nur Audio aus Videodaten

Mit ffmpeg können Sie einfach in eine Datei kopieren, die nur Audiodaten enthält.

ffmpeg -i original.m4v -acodec copy -vn output.m4a

2. Transkription von Sprachdaten

Um Amazon Transcribe verwenden zu können, müssen Sie Audiodaten in S3 hochladen. Dieses Mal habe ich der Einfachheit halber ein einfaches Skript in Python geschrieben, das nur in S3 hochgeladen und einen Auftrag an Amazon Transcribe gesendet wird.

Der Code, der danach herauskommt, ist ein Code, den ich in etwas mehr als 10 Minuten geschrieben habe, also ist er insgesamt ziemlich rau ...

01-transcribe.py


from boto3 import client, resource
import os
import sys

AWS_ACCESS_KEY = "hogehoge"
AWS_SECRET_ACCESS_KEY = "fugafuga"
BUCKET = "somebucket"

def upload(filepath):
    basename = os.path.basename(filepath)

    s3_client = resource(
        "s3",
        region_name="ap-northeast-1",
        aws_access_key_id=AWS_ACCESS_KEY,
        aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
    )
    s3_client.Bucket(BUCKET).upload_file(filepath, basename)


def transcribe(filename):

    url = "s3://{}/{}".format(BUCKET, filename)

    transcribe_client = client(
            "transcribe",
            region_name="ap-northeast-1",
            aws_access_key_id=AWS_ACCESS_KEY,
            aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
    )
    response = transcribe_client.start_transcription_job(
            TranscriptionJobName=filename,
            LanguageCode="en-US",
            MediaFormat="mp4",
            Media={
                    "MediaFileUri": url
            },
            OutputBucketName=BUCKET,
    )

def main():
    filepath = sys.argv[1]
    upload(filepath)
    transcribe(os.path.basename(filepath))


if __name__ == "__main__":
    main()

Übergeben Sie die vorherige Datei als Argument und führen Sie sie aus.

python 01-transcribe.py output.m4a

Laden Sie die resultierende JSON-Datei von der Webkonsole herunter. (Unterlassung)

3. Konvertieren Sie das Transkriptionsergebnis in SubRip-Untertiteldaten

Der resultierende JSON enthält ein Array erkannter Wörter sowie deren Start- und Endzeiten. Wenn Sie jedes Wort so wie es ist als Untertitel anzeigen, ist es zu schwer zu lesen.

Daher habe ich beschlossen, Untertiteldaten (srt) zu generieren, indem ich den Anzeigebereich nach bestimmten Regeln festlegte.

Diese Regel wird angemessen festgelegt. Spielen Sie also bitte damit, wie Sie möchten.

02-makesrt.py


import json
import sys


def sec2time(sec):
    h = int(sec/3600)
    m = int((sec%3600) / 60)
    s = int(sec % 60)
    mils = int((sec%1)*1000)
    return "{:02d}:{:02d}:{:02d},{:03d}".format(h, m, s, mils)

def convert2srt(filepath):
    with open(filepath, "r") as f:
        data = json.load(f)

    start_time = 0
    end_time = 0
    s = ""
    index = 0
    for item in data["results"]["items"]:
        is_output = False

        if "start_time" in item:
            item["start_time"] = float(item["start_time"])
            item["end_time"] = float(item["end_time"])

            if item["start_time"] - end_time > 3:
                #Hattest du zeit
                is_output = True

            elif len(s) >= 110:
                #Wenn es länger wird
                is_output = True
            
            if s != "":
                if len(s)>1 and s[-2].isupper():
                    pass
                else:
                    last = s[-1]
                    if last in (".", "?", "!"):
                        is_output = True
                    
                    if last == "," and len(s) > 80:
                        is_output = True

        if is_output:

            end_time = min(item["start_time"], end_time+2.0)

            if s != "":
                print(index)
                index += 1
                print("{0} --> {1}".format(sec2time(start_time), sec2time(end_time)))
                print(s)
                print("")

            start_time = 0
            end_time = 0
            s = ""

        if "start_time" in item:
            if start_time == 0:
                start_time = item["start_time"]
            end_time = item["end_time"]
            if s and (len(item["alternatives"][0]["content"])>1 or s[-1] != "."):
                s += " " + item["alternatives"][0]["content"]
            else:
                s += item["alternatives"][0]["content"]
        else:
            s += item["alternatives"][0]["content"]

    if s != "":
        print(index)
        index += 1
        print("{0} --> {1}".format(sec2time(start_time), sec2time(end_time+2.0)))
        print(s)
        print("")

def main():
    filepath = sys.argv[1]
    convert2srt(filepath)

if __name__ == "__main__":
    main()

Geben Sie eine JSON-Datei als Argument an und speichern Sie das Ergebnis durch Umleitung in einer Textdatei.

python 02-makesrt.py result.json > result.srt

Die Ausgabe sollte so aussehen

output


64
00:06:00,139 --> 00:06:16,839
Then the next Nano second, it was pure, unadulterated pandemonium Way number three going down.

65
00:06:16,839 --> 00:06:18,720
It looks like we lost number three engine.

66
00:06:18,720 --> 00:06:23,149
We're descending rapidly coming back.

4. Betten Sie Untertiteldaten in Videodaten ein

Mit mkvmerge können Sie Untertiteldaten einfach in mkv-Dateien einbetten.

mkvmerge -o output.mkv original.m4v --language 0:eng --track-name 0:English result.srt

Die eingebetteten Untertitel können bei der Wiedergabe in VLC angezeigt werden.

Ergebnis

Nun, ich denke, dass es fast ohne Unbehagen angezeigt wird.

vlcsnap-2020-03-03-00h47m23s630.png

vlcsnap-2020-03-03-00h50m06s662.png

Der eigentliche Nervenkitzel beim Programmieren besteht darin, dass Sie in solchen Zeiten schnell Werkzeuge erstellen können.

Recommended Posts

Mit Amazon Transcribe erstellte Untertiteldaten
Mit Python erstellte Beispieldaten
Holen Sie sich Lebensmitteldaten mit Amazon API (Python)
Datenanalyse mit Python 2
Daten mit TensorFlow lesen
Datenmanipulation mit Pandas!
Daten mit Pandas mischen
Datenerweiterung mit openCV
Daten mit Scipy normieren
Datenanalyse mit Python
LADEN SIE DATEN mit PyMysql
Mit den Daten von COVID-19 wurde ein Netzwerkdiagramm erstellt.
Betten Sie Audiodaten in Jupyter ein
Zeichnen Sie Excel-Daten mit matplotlib (1)
Künstliche Datengenerierung mit Numpy
Extrahieren Sie Twitter-Daten mit CSV
Holen Sie sich Youtube-Daten mit Python
Gesichtserkennung durch Amazon Rekognition
Lernen Sie neue Daten mit PaintsChainer
Binarisieren Sie Fotodaten mit OpenCV
Zeichnen Sie Excel-Daten mit matplotlib (2)
Verwenden Sie Django, um Tweet-Daten zu speichern
Erreiche "Bals" mit Amazon Echo
Datenverarbeitungstipps mit Pandas
Lesen von JSON-Daten mit Python