Last active
May 27, 2020 09:09
-
-
Save artpi/e237373eec789beebaca6b8dc9c53de1 to your computer and use it in GitHub Desktop.
Use Google Speech API to transcribe recordings in your Evernote Notes: https://piszek.com/2020/05/27/evernote-transcriber/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// https://piszek.com/2020/05/27/evernote-transcriber/ | |
function transcribe_audio_file_in_a_note( $evernoteClient, $note ) { | |
// This will find the place where file is embedded, so we can display the transcription underneath. | |
if( preg_match( '#<en-media hash="([a-z0-9]+)"[^>]+>#is', $note->content, $res ) ) { | |
$id = hex2bin($res[1] ); | |
$resources = array_filter( $note->resources, function( $resource ) use ( $id ) { | |
return $resource->data->bodyHash === $id; | |
} ); | |
if( $resources ) { | |
$resource = array_shift( $resources ); | |
} | |
} | |
if ( isset( $resource->mime ) && $resource->mime === 'audio/x-m4a' ) { | |
// Only audio files | |
if ( isset( $resource->attributes->applicationData->keysOnly['transcribed'] ) ) { | |
$this->log( LOG_INFO, 'This resource is already transcribed.' ); | |
return; | |
} | |
// Set for the future | |
$evernoteClient->client->getNoteStore()->setResourceApplicationDataEntry( $resource->guid, 'transcribed', 'true' ); | |
// this is your Google Speech API token | |
$token = "tsrtrastr8astars8tras8t"; | |
$in = tempnam(sys_get_temp_dir(), 'evernote_transcript') . '.mp4'; | |
$out = tempnam(sys_get_temp_dir(), 'evernote_transcript') . '.wav'; | |
$data = $evernoteClient->client->getNoteStore()->getResourceData( $resource->guid ); | |
file_put_contents( $in, $data ); | |
// Because Google Speech API is crap and cannot deal with other formats, we have to recode it. | |
system( "ffmpeg -i $in $out" ); | |
$data = file_get_contents( $out ); | |
$payload = array( | |
"audio" => array( "content" => base64_encode( $data ) ), | |
"config" => array( | |
"languageCode" => "en-US", | |
"alternativeLanguageCodes" => [ "pl-PL" ], // I only use English or Polish. Your mileage may vary. | |
"encoding" => "LINEAR16", | |
"sampleRateHertz" => 44100, | |
"maxAlternatives" => 1, | |
"enableAutomaticPunctuation" => true | |
) | |
); | |
$payload = json_encode( $payload ); | |
$context = stream_context_create( array( | |
'http' => array( | |
'ignore_errors' => true, | |
'header' => "Content-Type: application/json\r\n", | |
'method' => 'POST', | |
'content' => $payload | |
) | |
) ); | |
// Wondering about the v1p1beta1 here? You have to use this version to have alternativeLanguageCodes. This of course is not in documentation. | |
$result = file_get_contents( "https://speech.googleapis.com/v1p1beta1/speech:recognize?fields=results&key=$token", false, $context ); | |
$result = json_decode( $result, true ); | |
if ( ! isset ( $result['results'][0]['alternatives'][0]['transcript'] ) ) { | |
$this->log( LOG_WARNING, 'Empty transcript. ' . print_r( $result, true ) ); | |
return; | |
} | |
$text = $result['results'][0]['alternatives'][0]['transcript']; | |
$this->log( LOG_INFO, 'Transcript OK: ' . $text ); | |
$new_body = str_replace( $res[0], $res[0] . "<div style='font-style: italic'>$text</div>",$note->content ); | |
$note->content = $new_body; | |
$evernoteClient->client->getNoteStore()->updateNote( $note ); | |
} | |
return $note->content; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment