Ansagen erstellen mit Powershell und Text-To-Speech

OpenAI bietet neben (Chat)GPT und Whisper noch einige weitere KI Lösungen an. Darunter auch eine Text-To-Speech (TTS) KI mit der sich u.a. recht einfach (Telefon-) Ansagen erstellen lassen.

Gerade im Umfeld von Telefonanlagen wie der STARFACE kommt es immer wieder zu der Notwendigkeit Ansagen zu erstellen. Oftmals hört man auf den Firmen Mailboxen die Stimmen von Mitarbeitern oder auch professionell erstellte Ansagen werden gerne genommen. Wem die eigenen Ansagen zu unprofessionell und die Beauftragung von Dienstleistern zu aufwendig ist, bekommt durch KI mittlerweile eine gute Alternative.

Ki generiertes, vektorbasiertes Bild eines aufgeschlagenen Buches mit Antennen und Übertragungswellen, welches mit einem stilisierten Gesicht verbunden ist

Es gibt viele Anbieter in diesem Markt, einige wurden von Heise / ct in 2023 mal getestet:

KI-Stimmen: Sieben Anbieter für Text-to-Speech im Vergleich

Noch einfacher geht es mit dem folgenden, von mir erstellten Powershell Skripten – und die Qualität der Stimmen bei deutscher Sprache muss sich vor denen der anderen Anbieter nicht verstecken (teilweise ist ein leichter, amerikanischer Akzent zu hören). Zumindest zum aktuellen Zeitpunt (05/2024). Hervorzuheben sind hierbei die Stimmen onyx, nova und shimmer.

Voraussetzung für die Nutzung ist ein OpenAI API Key. Über die Kosten muss man sich für die Erstellung von ein paar Ansagen keine Sorgen machen. Bei meinen Tests habe ich 62 Anfragen an die API gestellt und dabei wurden fast 16.000 Zeichen synthetisiert – die Kosten beliefen sich auf 0,47 USD.

Der folgende Code ist (in Kürze) auch in unserem Github Repository zu finden.

Um das Skript zu verwenden muss man lediglich den OpenAI API Key, den gewünschten Text ($text) eintragen und das Skript aufrufen. Bei Bedarf kann man noch etwas mit den Variablen für das Model ($model) und die Stimme ($voice) testen.

# Define your OpenAI API key
$apiKey = "openai-api-key"

# Define the endpoint
$endpoint = "https://api.openai.com/v1/audio/speech"

# Define the voice you want to use (replace with actual available voices from OpenAI documentation)
$voice = "shimmer" # Best german: onyx (m), nova (w) und shimmer (w) | alloy (m), echo (m), fable (m), onyx (m), nova (w), and shimmer (w)

$model = "tts-1-hd" # tts-1 (fast for realtime), tts-1-hd (high quality, slower), tts-1-1106, tts-1-hd-1106

# The text to be converted to speech
$text = "Willkommen bei Firma XY! Einen Moment Geduld, wir sind gleich für Sie da!"

$outputName = "willkommen-ansage"

# Create the request body
$headers = @{
    "Authorization" = "Bearer $($apiKey)"
    "Content-Type" = "application/json"
}

$body = @{
    "model" = $model
    "input" = $text
    "voice" = $voice
    "speed" = 1.0
} | ConvertTo-Json

# Convert the JSON body to a byte array with UTF-8 encoding
$utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($body)

$outputFile = "$($voice)-$($outputName).wav"

$response = Invoke-WebRequest -Uri $endpoint -Method Post -Headers $headers -Body $utf8Bytes -OutFile $outputFile

Write-Host "Audio file $($outputFile) generated"
Code-Sprache: PowerShell (powershell)

Batch-Verarbeitung

Das vorstehende Skript ist ganz nett zum testen oder zur Erzeugung von einzelnen Audiodateien. Wenn man aber mehrere Ansagen oder Texte umwandeln möchte, kann das recht lästig werden. Daher habe ich das Skript entsprechend erweitert. Im Skript muss der Ordner-Pfad für die Textdateien und das Speicherverzeichnis für die Audiodateien angepasst werden (beide Ordnerpfade können auch gleich sein).

Da das OpenAI TTS Model mit der hohen Qualität (tts-1-hd) ein RateLimit von 3 Anfragen pro Minute hat, wartet das Skript nach jeder Konvertierung 20 Sekunden. Daher dauert die Verarbeitung von vielen Dateien entsprechend lange. Verwendet man das Model mit der niedrigeren Qualität (tts1) geht es wesentlich schneller, da nur eine Sekunde Wartezeit zwischen den Anfragen eingestellt ist.

# Define your OpenAI API key
$apiKey = "openai-api-key"

# Define the endpoint
$endpoint = "https://api.openai.com/v1/audio/speech"

# Define the voice you want to use (replace with actual available voices from OpenAI documentation)
$voice = "shimmer" # Best german: onyx (m), nova (w) und shimmer (w) | alloy (m), echo (m), fable (m), onyx (m), nova (w), and shimmer (w)

$model = "tts-1-hd"  # tts-1 (fast for realtime), tts-1-hd (high quality, slower), tts-1-1106, tts-1-hd-1106

# Define the folder containing the text files
$textFilesFolder = "\\server\daten\ansagen"

# Get all text files in the folder
$textFiles = Get-ChildItem -Path $textFilesFolder -Filter *.txt

# Define the output folder for the audio files
$outputFolder = "\\server\daten\ansagen"

# Ensure the output folder exists
if (-not (Test-Path -Path $outputFolder)) {
    New-Item -ItemType Directory -Path $outputFolder
}

foreach ($textFile in $textFiles) {
    # Read the content of the text file
    $text = Get-Content -Path $textFile.FullName -Raw

    # Create the request body
    $headers = @{
        "Authorization" = "Bearer $($apiKey)"
        "Content-Type" = "application/json"
    }

    $body = @{
        "model" = $model
        "input" = $text
        "voice" = $voice
        "speed" = 1.0
    } | ConvertTo-Json

    # Convert the JSON body to a byte array with UTF-8 encoding
    $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($body)

    # Define the output file name based on the text file name
    $originalFilename = [System.IO.Path]::GetFileNameWithoutExtension($textFile.Name)
    $outputFile = "$outputFolder\$originalFilename - $($voice).wav"

    # Send the request and save the output to the file
    $response = Invoke-WebRequest -Uri $endpoint -Method Post -Headers $headers -Body $utf8Bytes -OutFile $outputFile

    Write-Host "Audio file $($outputFile) generated in folder $($outputFolder)"

    # Add a delay to respect the rate limit
    $rateLimit = "unknown"
    $delay = 5
    if ($model -eq "tts-1-hd") {
        $rateLimit = "3 RPM"
        $delay = 20
    } elseif ($model -eq "tts-1") {
        $rateLimit = "50 RPM"
        $delay = 1
    }

    Write-Host "Respecting API rate limit ($($rateLimit)) of model $($model), waiting $($delay) seconds"
    Start-Sleep -Seconds $delay
}

Code-Sprache: PowerShell (powershell)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert