Moin zusammen,
ich habe die letzten Jahre meine Sprachausgaben immer mit Google Translate erstellt, so wie es ja einige hier im Forum auch machen. Die Sprachqualität war ja auch in Ordnung. Nur leider hat Google den Dienst ja abgekündigt und er ist aktuell nur noch mit Krücken (im Ansatz) nutzbar.
Deshalb habe ich nun eine andere Lösung gesucht und bei Ivona(.com) - einer Amazon Tochter - gefunden. Wie ich gelesen habe nutzen ja einige von Euch schon deren Stimmen in der Windows Sprachausgabe. Ivona bietet aber auch eine Web-API an mit der man die Sprach-MP3s aus der Cloud holen kann. In der kostenlosen Version lassen sich bis zu 50.000 Sprachdateien von 200 Zeichen länge pro Monat erstellen. Das sollte für die meisten hier reichen
Man benötigt einen kostenlosen Developer-Account, den man sich auf deren Seite klicken kann. Danach erstellt man sich dort noch einen Satz Credentials, die in der nachfolgenden Klasse benötigt werden. Der Download einer MP3-Sprachausgabe lässt sich dann folgendermaßen anstoßen:
$a = new IVONA_TTS();
$a->save_mp3("Fischers Fritze fischt frische Fische", PFAD_ZUR_DATEI);
So, hier nun die Klasse:
<?
///////////////////////////////////////////////////////////////////////////////////////
// IVONA_TTS ////////////////////////////////////////////////////////////
// by Titus 15.10.2015 ////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
class IVONA_TTS
{
static $utc_tz;
const ACCESS_KEY = 'AAA'; // HIER DEINEN ACCESS KEY EINTRAGEN!!
const SECRET_KEY = 'BBB'; // HIER DEINEN SECRET KEY EINTRAGEN!!
function save_mp3($text, $filename, $language="de-DE", $voice="Marlene", $rate="medium", $volume="loud") {
$payload['Input'] = array();
$payload['Input']['Data'] = utf8_encode($text);//{"Input":{"Data":"Hello world"}}'
$payload['Parameters']['Rate'] = $rate;
$payload['Parameters']['Volume'] = $volume;
$payload['Voice']['Name'] = $voice;
$payload['Voice']['Language'] = $language;
$payload = json_encode($payload);
$mp3 = $this->get_mp3($payload);
file_put_contents($filename, $mp3);
}
function get_mp3( $payload )
{
if( !self::$utc_tz ) {
self::$utc_tz = new \DateTimeZone( 'UTC' );
}
$datestamp = new \DateTime( "now", self::$utc_tz );
$longdate = $datestamp->format( "Ymd\\THis\\Z");
$shortdate = $datestamp->format( "Ymd" );
// establish the signing key
{
$ksecret = 'AWS4' . self::SECRET_KEY;
$kdate = hash_hmac( 'sha256', $shortdate, $ksecret, true );
$kregion = hash_hmac( 'sha256', 'eu-west-1', $kdate, true );
$kservice = hash_hmac( 'sha256', 'tts', $kregion, true );
$ksigning = hash_hmac( 'sha256', 'aws4_request', $kservice, true );
}
// command parameters
$params = array(
'host' => 'tts.eu-west-1.ivonacloud.com',
'content-type' => 'application/json',
'x-amz-content-sha256' => hash( 'sha256', $payload ),
'x-amz-date' => $longdate,
);
$canonical_request = $this->createCanonicalRequest( $params, $payload );
$signed_request = hash( 'sha256', $canonical_request );
$sign_string = "AWS4-HMAC-SHA256
{$longdate}
$shortdate/eu-west-1/tts/aws4_request
" . $signed_request;
$signature = hash_hmac( 'sha256', $sign_string, $ksigning );
$params['Authorization'] = "AWS4-HMAC-SHA256 Credential=" . self::ACCESS_KEY . "/$shortdate/eu-west-1/tts/aws4_request, " .
"SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, " .
"Signature=$signature";
$params['content-length'] = strlen( $payload ) ;
/*
* Execute Crafted Request
*/
$url = "https://tts.eu-west-1.ivonacloud.com/CreateSpeech";
$ch = curl_init();
$curl_headers = array();
foreach( $params as $p => $k )
$curl_headers[] = $p . ": " . $k;
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TCP_NODELAY, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false );
// debug opts
{
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'rw+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
$result = curl_exec($ch); // raw result
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
#echo "Verbose information:
<pre>", htmlspecialchars($verboseLog), "</pre>
";
}
return $result;
}
private function createCanonicalRequest( Array $params, $payload )
{
$canonical_request = array();
$canonical_request[] = 'POST';
$canonical_request[] = '/CreateSpeech';
$canonical_request[] = '';
$can_headers = array(
'host' => 'tts.eu-west-1.ivonacloud.com'
);
foreach( $params as $k => $v )
$can_headers[ strtolower( $k ) ] = trim( $v );
uksort( $can_headers, 'strcmp' );
foreach ( $can_headers as $k => $v )
$canonical_request[] = $k . ':' . $v;
$canonical_request[] = '';
$canonical_request[] = implode( ';', array_keys( $can_headers ) );
$canonical_request[] = hash( 'sha256', $payload );
$canonical_request = implode( "
", $canonical_request );
return $canonical_request;
}
}
?>
Ich hoffe das ist für den einen oder anderen hier nützlich. Zudem ist auch die Qualität der Sprachausgaben bei Ivona um Welten besser als bei Google!
Wer noch was verbessern kann ist natürlich herzlich eingeladen