

AVAudioRecorderで録音してDocumentフォルダに記録し、AVAudioPlayerで再生しようとしています。問題点だけ要約したプロジェクトをGitHubに置きました。

<https://github.com/ueda-keisuke/AVAudioPlayerTest>

複雑なことに、シミュレータではこのコードは正しく動作します。しかし実機（iPad Air
2）ではDocumentフォルダ内のオーディオが次のエラーになり再生されません。

> Error loading  
>
> file:///var/mobile/Containers/Data/Application/772E3C09-5D23-4153-A11B-125D00582759/Documentsaudio.m4a:  
>  Error Domain=NSOSStatusErrorDomain Code=2003334207 "(null)"

あるいは

> Error loading  
>
> file:///var/mobile/Containers/Data/Application/93108627-9DBE-453E-8D93-746E65DA48EE/Documents/F32D2D55-1978-427F-AF79-4F042C8B51F5/87.m4a:  
>  Error Domain=NSOSStatusErrorDomain Code=1685348671 "(null)"

# 問題点要約アプリの解説

ボタンが3つあります。

  1. Play audio recorded by simulator  
このボタンを押すとBundleにあるオーディオファイルを再生します（手を叩いた音が収録されています）。このオーディオファイルはシミュレータでこのプログラムを実行し、録音し、Documentフォルダから取り出してプロジェクトに登録しました。つまり録音自体は正常にできていると考えます。またAVAudioPlayerがこのファイルを再生できないわけではありません。

  2. Record  
押すと録音開始し、もう一度押すと録音を止めます。ファイルはDocumentフォルダに生成し、既存のファイルがある場合は上書きします。

  3. Play  
Documentフォルダに作ったオーディオを再生します。シミュレータでは録音した音が鳴りますが、実機ではエラーが出て音が鳴りません。

# 今までに調べたこと

  * エラーコード1685348671および2003334207について調べました。
  * "Domain=NSOSStatusErrorDomain Code=2003334207"でも調べました
  * Documentディレクトリの扱いについて調べました

いずれも情報はたくさん出てきますが、解決の役に立つものは見つかりませんでした。

  * Documentディレクトリにあるファイルのリストを取得して、ファイルが存在することは確認しました。

# 要約

  * AVAudioPlayerでDocumentフォルダに作成したファイルを実機で再生できない
  * シミュレータでは再生できる
  * シミュレータで録音したファイルをBundleに移動すれば実機でも再生できる

どなたか解決策をご存じの方がいらっしゃれば教えていただけると幸いです。よろしくお願いします。


CC BY-SA 3.0
2016-04-06T05:30:52.763
23786
2016-04-06T08:03:45.890
14631
question
ios
AVAudioPlayerが実機のDocumentフォルダのオーディオを再生できない


この辺りAppleのドキュメントは必ずしもわかりやすいとは言えない上に、日本語版も提供されていないのですが、`AVAudioRecorder`を用いて録音を行う場合、`AVAudioSession`の設定も必要になるようです。  
[Multimedia Programming
Guide](https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/MultimediaPG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009767)  
\- [Recording with the AVAudioRecorder
Class](https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/MultimediaPG/UsingAudio/UsingAudio.html#//apple_ref/doc/uid/TP40009767-CH2-SW14)

古い記述のままで、ARCを使用しないObjective-Cでコード例が書かれているのですが、要点を抜き出すと:

  * 録音開始前に`AVAudioSession`の`setCategory(_:)`でcategoryを`AVAudioSessionCategoryRecord`に設定しておく。
  * 同じく録音開始前に、`AVAudioSession`の`setActive(_:)`でactiveを`true`に設定しておく。
  * 録音終了後、`AVAudioSession`の`setActive(_:)`でactiveを`false`に変更する。

同ドキュメントでは見つけられませんでしたが、上記の後で`AVAudioPlayer`で録音データを再生する場合:

  * 再生開始前に`AVAudioSession`の`setCategory(_:)`でcategoryを`AVAudioSessionCategoryAmbient`に設定しておく。

と言ったことをしておかないといけないようです。

あなたのGithubのコードですと、  
`record(_:)`メソッド中の`audioRecorder?.stop()`の後:

[code]

            let session = AVAudioSession.sharedInstance()
            try! session.setActive(false)
    
[/code]

(エラーをcatchしたほうが良いかもしれませんが、ここでは概略を示すため簡略化しておきます。)

`setupAudioRecorder()`メソッド中の`audioRecorder = try AVAudioRecorder(URL: url,
settings: recordSettings)`の後:

[code]

            let session = AVAudioSession.sharedInstance()
            try session.setCategory(AVAudioSessionCategoryRecord)
            try session.setActive(true)
    
[/code]

`play(_:)`メソッド中の`audioPlayer = try AVAudioPlayer(contentsOfURL: url)`の前:

[code]

            let audioSession = AVAudioSession.sharedInstance()
            try audioSession.setCategory(AVAudioSessionCategoryAmbient)
    
[/code]

…のような感じで、`AVAudioSession`の操作をするコードを付け足してみてください。

なお、エラーメッセージを見ると試行錯誤の過程で(?)ファイルパスの作成方法をいろいろいじった跡が窺えますが、当然ながら録音用と再生用のファイルパスはDocumentsディレクトリー下の同じファイルを指すようにご注意ください。

こちらの環境では、上記の修正で確実に再生できるようになったのですが、全く同じ環境ではないでしょうから、まだ何かあるかもしれません。お試しの上何かあれば、おしらせください。


CC BY-SA 3.0
2016-04-06T08:03:45.890
23792
2016-04-06T08:03:45.890
13972
23786
answer