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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

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

Q&A

1回答

4318閲覧

[Swift]ExtAudioFileOpenURL実行時のエラーを解決したい

退会済みユーザー

退会済みユーザー

総合スコア0

Swift

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

0グッド

1クリップ

投稿2017/11/10 15:55

編集2017/11/12 02:01

###背景

SwiftでiPhoneアプリを開発中です。

アプリ内で、m4aからwavへの音声変換を行おうとしています。

以下の記事を参考にしています。

Swift3でCore Audioを使用した音声ファイル変換 - Voicy Tech Blog
audio - iOS Code to Convert m4a to WAV - Stack Overflow
avAudioPlayer OSStatus error 2003334207 | Apple Developer Forums

###実現したいこと

convertAudioメソッドを上手く動作させて、音声変換を行いたいです。

###該当のソースコード

  • 音声変換メソッド

swift

1import AVKit 2import AVFoundation 3import AudioToolbox 4import CoreAudioKit 5 6/* m4a -> wav の音声変換 */ 7 func convertAudio(_ inFileUrl: URL, _ outFileUrl: URL) { 8 9 // ステータス 10 var status: OSStatus = noErr 11 12 // 変換元のm4aファイルを開く 13 var inFile: ExtAudioFileRef? 14 status = ExtAudioFileOpenURL(inFileUrl as CFURL, &inFile) 15 print("---> 01") 16 print(status) 17 print("<--- 01") 18 19 // 変換先のwavファイルを開く 20 var outFile: ExtAudioFileRef? 21 status = ExtAudioFileOpenURL(outFileUrl as CFURL, &outFile) 22 print("---> 02") 23 print(status) 24 print("<--- 02") 25 26 // 出力するwavファイルの情報を取得 27 var inASBDSize = UInt32(MemoryLayout<AudioStreamBasicDescription>.size) 28 var inFormat = AudioStreamBasicDescription() 29 30 /* *** ERROR!! *** */ 31 status = ExtAudioFileGetProperty(inFile!, kExtAudioFileProperty_FileDataFormat, &inASBDSize, &inFormat) 32 print("---> 03") 33 print(status) 34 print("<--- 03") 35 36 37 // wavファイル情報 38 var outASBDSize = UInt32(MemoryLayout<AudioStreamBasicDescription>.size) 39 var wavFormat = AudioStreamBasicDescription() 40 wavFormat.mFormatID = kAudioFormatLinearPCM 41 wavFormat.mSampleRate = 44100.0 42 wavFormat.mChannelsPerFrame = 1 43 AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, nil, &outASBDSize, &wavFormat) 44 45 // wavファイルファイルを開く 46 status = ExtAudioFileCreateWithURL(outFileUrl as CFURL, 47 kAudioFormatLinearPCM, 48 &wavFormat, 49 nil, 50 AudioFileFlags.eraseFile.rawValue, 51 &outFile) 52 print("---> 04") 53 print(status) 54 print("<--- 04") 55 56 57 58 /// MARK: 変換ルールの指定 59 60 // 書き込みプロパティ設定 61 status = ExtAudioFileSetProperty(outFile!, 62 kExtAudioFileProperty_ClientDataFormat, 63 inASBDSize, 64 &inFormat) 65 print("---> 05") 66 print(status) 67 print("<--- 05") 68 69 70 /// MARK: 変換処理 71 72 // バッファ作成 73 var readFrameSize: UInt32 = 1024 // 一度に読み込むフレーム数 74 var bufferSize = readFrameSize * inFormat.mBytesPerPacket 75 var buffer: UnsafeMutableRawPointer = malloc(Int(bufferSize)) 76 defer { free(buffer) } 77 78 var audioBuffer = AudioBufferList() 79 audioBuffer.mNumberBuffers = 1 80 audioBuffer.mBuffers.mNumberChannels = inFormat.mChannelsPerFrame 81 audioBuffer.mBuffers.mDataByteSize = bufferSize 82 audioBuffer.mBuffers.mData = buffer 83 84 // ファイルを読み込んで出力 85 while (true) { 86 // WAVファイル読み込み 87 ExtAudioFileRead(inFile!, &readFrameSize, &audioBuffer) 88 // 読み込むデータがなくなれば終了 89 if readFrameSize <= 0 { break } 90 // AACファイル書き込み 91 ExtAudioFileWrite(outFile!, readFrameSize, &audioBuffer) 92 } 93 94 95 /// MARK: ファイルを閉じる 96 97 ExtAudioFileDispose(inFile!) 98 ExtAudioFileDispose(outFile!) 99 }
  • 呼び出し元

swift

1//audioM4aURL: URL? // result: file:///Users/Polaris/Library/Developer/CoreSimulator/Devices/7A5A0C5B-AB28-4582-86D8-652072416B1F/data/Containers/Data/Application/62BAB05E-D169-4886-9327-7F8B041E397A/Documents/2017-11-10-13-45-28.m4a 2 3// audioWavURL: URL? // result: "file:///Users/Polaris/Library/Developer/CoreSimulator/Devices/7A5A0C5B-AB28-4582-86D8-652072416B1F/data/Containers/Data/Application/63026CA3-FABA-474B-8FF6-10C819A00CBC/Documents/2017-11-10-15-45-45.wav" 4 5convertAudio(audioM4aURL!, audioWavURL!) 6

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

convertAudioメソッドのExtAudioFileGetProperty(inFile!, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat)にて、

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

というエラーが表示され、アプリが落ちます。

inFilenilが入っていることが原因のエラーだということはわかっています。

  • コンソール
2017-11-11 01:17:00.088640+0900 enPiT2SUProduct[34488:655917] 231: EXCEPTION (2003334207): "open audio file" ---> 01 2003334207 <--- 01 2017-11-11 01:17:00.089532+0900 enPiT2SUProduct[34488:655917] 231: EXCEPTION (2003334207): "open audio file" ---> 02 2003334207 <--- 02 // ここでアプリが落ちる

###考えたこと
音声変換の途中で、 ExtAudioFileOpenURL(url as CFURL, &inFile)という処理を行ったときに、urlが指す音声ファイルをinFileにセットすれば、とりあえず、次の処理に進めるのではないかと考えました。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t_obara

2017/11/22 06:55

アプリから、当該ファイルへの参照権限があるか否かをご確認されることがポイントになるかと。そういう意味で、fuzzballさんが示した方法で存在確認をすべきかと。
guest

回答1

0

ファイル(inFileUrl、outFileUrl)が存在していないのでは?

投稿2017/11/13 06:20

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/14 04:17

ファイルの存在はどのようにして確認すれば良いでしょうか?
fuzzball

2017/11/14 04:28

FileManagerのfileExists(atPath:)で確認できそうです。 https://developer.apple.com/documentation/foundation/filemanager/1415645-fileexists というか、確認するもなにも、inの方はどこからか読み込んだ or アプリ内で作成したファイルで、存在している前提で convertAudio() を呼んでいるのではないのですか? また、outの方は生成前だから存在しなくて当たり前のような気がします。
退会済みユーザー

退会済みユーザー

2017/11/14 05:46

convertAudioメソッドにinFileUrlとして渡すaudioM4aURLは、呼び出し元ソースコードに書いた通りデバッガでパスを確認済みです。もちろん、音声ファイルの再生も確認済みです。 よって、inの方のファイルは存在しているはずです。
fuzzball

2017/11/14 05:54

そのパスのファイルが実際に存在することは確認したのでしょうか?(なんか話がループしていますが) そのパスはどうやって生成(もしくは取得)したのでしょうか?
退会済みユーザー

退会済みユーザー

2017/11/16 13:33

audioM4aURLはデバッガでパスを確認し、そのパスのm4aファイルをターミナルからひらいて確認しました。空のファイルということでもなく、iTunesでm4aファイルを再生できています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問