見出し画像

Speechフレームワークで音声認識→動画に自動で字幕をつける

やりたいこと:

Speechフレームワークで(日本語の)音声認識を行い、その結果を使って動画に字幕を自動でつける。

画像1

(このスクショは記事用に参考として適用してみただけです。映像と期待すべき認識結果が画像だけで伝わるかなということで。)

Speechフレームワークで音声認識を行う記事は多々あるのでそのへんは省略。動画との連動をどうやるか、認識がなかなかうまくいかないのをどうするか諸々検討したことについて書き留めておく。

動画から音声を抽出

SFSpeechRecognizerはバッファを渡してリアルタイムに認識する方法と、音声ファイルを渡してオフライン(※ネットワークの話ではなくて非リアルタイムの意味)で認識する方法がある。今回の用途だと再生のたびに音声認識を回すのはCPUの無駄なので、後者で処理する。

そのために動画から音声データをファイルとして抜き出す。実装方法としては動画のAVAssetオブジェクトから、AVAssetExportSessionを用いてこんな感じでファイルにexportするだけ。

   let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetAppleM4A)!
   if FileManager.default.fileExists(atPath: url.path) {
       try! FileManager.default.removeItem(at: url)
   }
   exportSession.canPerformMultiplePassesOverSourceMediaData = true
   exportSession.outputURL = url
   exportSession.outputFileType = .m4a
   exportSession.exportAsynchronously(completionHandler: handler)

1分の制約への対処

SFSpeechRecognizerは1分までしか音声認識してくれないという制約がある。

Plan for a one-minute limit on audio duration. Speech recognition can place a relatively high burden on battery life and network usage. In iOS 10, utterance audio duration is limited to about one minute, which is similar to the limit for keyboard-related dictation.

これを回避するために、AVAssetExportSessionのtimeRangeプロパティを使って音声ファイルを1分以内に切り出してexportすればよさそう。

// 参考記事のコード。Swiftバージョン/iOSバージョンが古いかも
let startTime = CMTimeMake(0, 1)
let stopTime = CMTimeMake(5, 1)
let exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime)
exporter.timeRange = exportTimeRange

ファイルの切れ目のところにちょうど音声がまたがる可能性があるので、多少オーバーラップさせて切らないといけない。ので認識結果の処理が面倒そう。(※今回は自分ではここまでやっていない)

認識結果のタイムスタンプ

ここから先は

2,733字
文章やサンプルコードは多少荒削りかもしれませんが、ブログや書籍にはまだ書いていないことを日々大量に載せています。たったの400円で、すぐに購読解除してもその月は過去記事もさかのぼって読めるので、少しでも気になる内容がある方にはオトクかと思います。

技術的なメモやサンプルコード、思いついたアイデア、考えたこと、お金の話等々、頭をよぎった諸々を気軽に垂れ流しています。

最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/