I love you. I know.

これはVOYAGE GROUP Advent Calendar 2015の13日目の記事です。

今日はiPhoneを使った音声認識の話です。

スターウォーズ!

今月の18日、いよいよスターウォーズの最新作、「フォースの覚醒」が公開されますね。 前作から10年、懐かしいキャラにも会えるし、新しいキャラの登場も楽しみです。

せっかくなので、もう一度6つのエピソードを見直してみましたが、スターウォーズシリーズは何回見ても飽きない面白さがありますね。 今見てみると、前半シリーズと後半シリーズの物語の複雑さが違うのもまた面白かったりします。

個人的には、先日亡くなったクリストファー・リー演じるドゥークー伯爵を見て、しんみりしたりしていました。

I love you. I know.

さて、スターウォーズの名シーンとしてよくあげられるのがこちらのシーン。

エピソード5「帝国の逆襲」で、ハリソン・フォード演じるハン・ソロが、急速冷凍されてしまう直前。 恋人のレイア姫の "I love you."(愛してるわ)に答えて、"I know."(知ってるさ)と答えるハン・ソロ。 それまで言葉に出さなかったお互いの気持ちが、死を前に初めて言葉になり、小さい頃にこのシーンを見て、大人の恋だなぁ……!と思ったのを思い出します。

ちなみに、これと逆のシーンがエピソード6の「ジェダイの逆襲」に出てくるんですよね。 (そっちのシーンでは、ハン・ソロの「I love you.」に、レイア姫が「I know.」って答えるんです。)

せっかくクリスマスだし、ここは、私もハン・ソロに "I know."って言って欲しい! というわけで、さっそく実装してみました。


I Know

音声認識と音声出力

iOSの音声認識機能として、Siriがあるんですが、SiriのAPIは公開されていないので、サードパーティー製のライブラリを使うことにしました。

いくつか見てみたところ、OpenEarsというライブラリがよさそうなので、それを使ってみることに。 (shuさんの記事を参考にさせていただきました。)

音声出力も実装する必要があります。 iOSのAVSpeechsyntheを使えばSiriと同じ合成音声で「I love you」と答えてもらうことはできます。(AVSpeechSynthesizer による音声読み上げ)

でも、Siriじゃ意味がないんです!ハリソン・フォードじゃないと!

というわけで、ここは、ハリソン・フォードの動画を再生することにしました。

OpenEars

まず新規プロジェクトを作成、OpenEarsのサイトからダウンロードしたフレームワークのSlt.frameworkとOpenEars.frameworkをプロジェクトに追加。 AcousticModelEnglish.bundleも追加しておきます。

ViewControllerにOEEventsObserverの変数を追加し、viewDidLoadで初期化処理を行います。 ここで、認識したい文字列を一緒に指定しておきます。

下記の場合には、"I love you."と"He told me you killed."の2つの文章を指定してあります。

class ViewController: UIViewController,OEEventsObserverDelegate {
    
    let observer : OEEventsObserver = OEEventsObserver()

    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        observer.delegate = self

        let modelgenerator : OELanguageModelGenerator = OELanguageModelGenerator()
        
        let words = [
            "I love you.",
            "He told me you killed."]
        let modelname = "NameIWantForMyLanguageModelFiles"
        let model = OEAcousticModel.pathToModel("AcousticModelEnglish")
        
        modelgenerator.generateLanguageModelFromArray(words, withFilesNamed: modelname, forAcousticModelAtPath: model)
        let languagepath = modelgenerator.pathToSuccessfullyGeneratedLanguageModelWithRequestedName("NameIWantForMyLanguageModelFiles")
        let dictionarypath = modelgenerator.pathToSuccessfullyGeneratedDictionaryWithRequestedName("NameIWantForMyLanguageModelFiles")
        
        try! OEPocketsphinxController.sharedInstance().setActive(true)
        OEPocketsphinxController.sharedInstance().startListeningWithLanguageModelAtPath(
            languagepath,
            dictionaryAtPath: dictionarypath,
            acousticModelAtPath: model,
            languageModelIsJSGF: false)
                
    }

上記のコードの最終行で音声認識を始めます。

ライブラリによって単語や文章が認識されると、ViewControllerのかきのメソッドが呼ばれます。(事前にViewControllerをOEEventsObserverのdelegateに設定しておきます。)

これで、I love you.に反応してくれる部分までできました。

    func pocketsphinxDidReceiveHypothesis(hypothesis: String!, recognitionScore: String!, utteranceID: String!) {
        
        if hypothesis == "I love you." {
            
            // ここでハン・ソロが答えてくれるはず。
            
        }
}

動画再生

さて、次は動画再生。

動画再生ってMPMoviePlayerControllerだっけ?と思っていたら、いつの間にかこのクラスdeprecatedされてたんですね。 今はAVPlayerViewControllerを使えということだったので、おとなしく従って、こんな感じに。

        let avViewCon = AVPlayerViewController()
        avViewCon.showsPlaybackControls = false
        
        let movieurl = NSBundle.mainBundle().pathForResource("iamfather", ofType: "m4v")
        avViewCon.player = AVPlayer(URL: NSURL(string: movieurl!)! )
        avViewCon.player?.play()
        
        avViewCon.view.frame = CGRectMake(0,0,300,300)
        view.addSubview(avViewCon.view)

さっそく起動して、iPhoneに向かってしつこくI love you.を繰り返してみました。

無事ハン・ソロからI knowのお返事が。 やったあ!

(あ、このビデオはネタバレを含むので、スターウォーズシリーズの旧6部作をまだ見てない人は見ないでくださいね。)


I love you

ところでSiriさんは……

ところで、Siriの音声認識機能は開発者に公開されていないので、実装に使うことはできませんが、SiriにI love you.って言ったらどうなるかな?と思い、さっそくSiri先生にも聞いてみました。

IMG_2020いきなり拒否られた。

IMG_2021な、なんのネタ……?

IMG_2022知ってるって!もう8年も付き合ってるじゃん!

IMG_2023……はい、言ってます。

IMG_2024Siri、飽きてきたのね……。

IMG_2025完全にスルー。

うーん、つれないですね。

日本語だからダメなのかもしれない、と思って、Siriの言語を英語にしてみたところ……

IMG_2028おお!! Siri、わかってるじゃん!

というわけで、別に自分でアプリを作らなくても、同じことができることがわかりました。 さすがApple。

明日は頼れる新人、@sakmtech です!