質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • Swift

    8754questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iOS10のSpeech frameworkを使ってリアルタイムに音声認識を1分以上続けたいです.

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,598

前提・実現したいこと

ここに質問したいことを詳細に書いてください
iOS10のSpeech frameworkを使ってリアルタイムに音声認識を1分以上続けたいです.

発生している問題・エラーメッセージ

2016-12-15 20:23:06.133449 ARCamera[1274:294599] [central] 54:   ERROR:    [0x1a6a16c40] >avae> AVAudioNode.mm:565: CreateRecordingTap: required condition is false: _recordingTap == nil
2016-12-15 20:23:06.134303 ARCamera[1274:294599] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: _recordingTap == nil'
*** First throw call stack:
(0x181db41c0 0x1807ec55c 0x181db4094 0x19b31778c 0x19b38cdb0 0x19b38aa8c 0x1000776f4 0x10007634c 0x1000765f8 0x18289b988 0x181d628f4 0x181d62608 0x181d61ec4 0x181d5fac0 0x181c8e048 0x183711198 0x187c68628 0x187c63360 0x10007ed8c 0x180c705b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

該当のソースコード

private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier:"ja_JP"))!

    private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?

    private var recognitionTask: SFSpeechRecognitionTask?

    private var audioEngine = AVAudioEngine()

    var timer:Timer!


override func viewDidLoad() {
        super.viewDidLoad()

        // カメラを準備
        if initilize() {
            mySession.startRunning()

            operate()

            timer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(self.operate), userInfo: nil, repeats: true)

        }
    }


    func operate(){
        audioEngine.stop()
        recognitionRequest?.endAudio()
        print("Stopping")
        try! startRecording()
        print("Start recording")

    }


private func startRecording() throws {

        // Cancel the previous task if it's running.
        if let recognitionTask = recognitionTask {
            recognitionTask.cancel()
            self.recognitionTask = nil
        }

        recognitionRequest = SFSpeechAudioBufferRecognitionRequest()

        guard let inputNode = audioEngine.inputNode else { fatalError("Audio engine has no input node") }
        guard let recognitionRequest = recognitionRequest else { fatalError("Unable to created a SFSpeechAudioBufferRecognitionRequest object") }

        // オーディオ録音が完了する前に結果が返されるようにリクエストを設定する
        recognitionRequest.shouldReportPartialResults = true

        recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in
            var isFinal = false

            if let result = result {
                self.myTextField.setContentOffset(CGPoint(x:0, y:self.myTextField.contentSize.height - self.myTextField.frame.size.height),animated: false);

                self.myTextField.text = result.bestTranscription.formattedString
                isFinal = result.isFinal

            }

            if error != nil || isFinal {
                self.audioEngine.stop()
                inputNode.removeTap(onBus: 0)
                self.recognitionRequest = nil
                self.recognitionTask = nil
            }
        }

        let recordingFormat = inputNode.outputFormat(forBus: 0)
        inputNode.installTap(onBus: 0, bufferSize: 2048, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in

            self.recognitionRequest?.append(buffer)
        }


        audioEngine.prepare()
        try audioEngine.start()

    }

試したこと

Speech Frameworkの連続認識が60秒なので,
startRecodingメソッドを60秒ごとに呼べば永遠に認識できると思い,Timerで定期的に呼び出してます.

ここら辺かなと思ったところを抜粋したので,必要な部分が欠けてましたら,教えてください.

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

60秒のタイマーが経過した時に、今認識中の処理をきちんとキャンセルしてから
改めて認識処理を再開させればうまくいくと思いますが、多分のその制御の方が難しくて、
それよりは、認識処理が60秒経過したらエラーで通知されるので、
そのエラー通知を受けたら認識処理を再スタートさせるだけでいいと思います。
自分でタイマーをかける必要ないです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Swift

    8754questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています