Amazon Transcribeで文字起こし:続

こんにちは、松田です。

前回は、AWSコンソール上で文字起こしを行いましたが、今回はLambdaからTranscribeを呼び出し操作します。

xp-cloud.jp

Lambdaの作成

lambdaではカスタム語彙の更新、transcribeJobの作成、状態の読み取り、変換されたテキストの出力を行っています。

Lambdaの設定は設定>一般設定>タイムアウトを一分にします。

Lambdaで使用するロールにはS3とTranscribeのアクセス権限を付与しましょう。

const AWS = require('aws-sdk');
const transcribeservice = new AWS.TranscribeService({apiVersion: '2017-10-26'});

exports.handler = async (event) => {
  const params = {
    LanguageCode: "ja-JP",
    Media: {
      MediaFileUri: "s3://*********************/Soundfiles/Rashomon.mp3"
    },
    TranscriptionJobName: 'lambdaTranscribe',
    MediaFormat: "mp3",
    Settings :{
      VocabularyName: "Rashomon"
    },
    OutputBucketName: "*********************",
    OutputKey: "Transcribetexts/"
  };
  
  const vocabParams = {
    "LanguageCode": "ja-JP",
    "VocabularyFileUri": "s3://*********************/Vocabularyfiles/custom-vocabulary.txt",
    "VocabularyName": "Rashomon"}
  
  
  try {
    //カスタム語彙を更新
    await transcribeservice.updateVocabulary(vocabParams).promise()
    let vocabRes = await transcribeservice.getVocabulary({"VocabularyName": "Rashomon"}).promise()
    while(vocabRes.VocabularyState !== "READY" && vocabRes.VocabularyState !== "FAILED"){
      vocabRes = await transcribeservice.getVocabulary({"VocabularyName": "Rashomon"}).promise()
      await sleep()
    }
  } catch (e) {
    console.log(e)
  }
 
  
  try {
    //すでにTranscriptionJobが作成されているか確認
    //作成されていれば削除
    await transcribeservice.getTranscriptionJob({TranscriptionJobName: 'lambdaTranscribe'}).promise()
    await transcribeservice.deleteTranscriptionJob({"TranscriptionJobName": "lambdaTranscribe"}).promise()
  } catch (e) {
    console.log(e)
  }
  
  try{
    const response = await transcribeservice.startTranscriptionJob(params).promise()
    console.log(response)
    
    let res = await transcribeservice.getTranscriptionJob({TranscriptionJobName: 'lambdaTranscribe'}).promise()
    
    //失敗もしくは完了までステータスを取得する
    while (res.TranscriptionJob.TranscriptionJobStatus !== "COMPLETED" && res.TranscriptionJob.TranscriptionJobStatus !== "FAILED"){
      await sleep()
      res = await transcribeservice.getTranscriptionJob({TranscriptionJobName: 'lambdaTranscribe'}).promise()
      console.log("transcribing")
    } 
    
    return res.TranscriptionJob.TranscriptionJobStatus
  }catch(error){
    console.log(error)
  }
}

function sleep() {
   return new Promise(function(resolve) {
      setTimeout(function() {resolve()}, 5000);
   })
}

S3ファイルアップロードをトリガーにする場合の注意点

S3トリガーの対象バケットとTranscribe apiで使用するOutputBucketNameは別のバケットにしましょう。

バケットが同一だった場合S3トリガーが再帰呼び出しをされて無限にLambdaがトリガーされてしまいます。

回避方法としてS3トリガー設定画面でプレフィックスサフィックスを設定するなどがありますが、注意書きに「入力と出力の両方に同じ S3 バケットを使用することは推奨されておらず」とあるので同一バケットを使用する目的では控えておきましょう

まとめ

今回は、transcribeをコンソールではなくlambdaから呼び出す方法を記載しました。

今回は、音声ファイルを文字起こししましたが、Transcribeにはリアルタイムで文字起こしを行うサービスもあるようです。

状況によって使い分けることができるので議事録作成など効率化を図りたいという場面で使用する機会はあるのではないでしょうか。