質問編集履歴
4
title
CHANGED
File without changes
|
body
CHANGED
File without changes
|
3
参考リンク追加
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
[Swift]
|
1
|
+
[Swift]ExtAudioFileOpenURL実行時のエラーを解決したい
|
body
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
|
9
9
|
[Swift3でCore Audioを使用した音声ファイル変換 - Voicy Tech Blog](http://voicetech.hatenablog.com/entry/2017/06/07/225127)
|
10
10
|
[audio - iOS Code to Convert m4a to WAV - Stack Overflow](https://stackoverflow.com/questions/35738133/ios-code-to-convert-m4a-to-wav/36001262#36001262)
|
11
|
+
[avAudioPlayer OSStatus error 2003334207 | Apple Developer Forums](https://forums.developer.apple.com/thread/5278)
|
11
12
|
|
12
13
|
###実現したいこと
|
13
14
|
|
@@ -55,26 +56,21 @@
|
|
55
56
|
print("<--- 03")
|
56
57
|
|
57
58
|
|
58
|
-
/// MARK: 変換先wavファイルをひらく
|
59
|
-
|
60
|
-
// 変換先のoutput.wavを指すURL
|
61
|
-
let toUrl = URL(fileURLWithPath: (NSTemporaryDirectory() as NSString).appendingPathComponent("output.wav"))
|
62
|
-
|
63
59
|
// wavファイル情報
|
64
60
|
var outASBDSize = UInt32(MemoryLayout<AudioStreamBasicDescription>.size)
|
65
61
|
var wavFormat = AudioStreamBasicDescription()
|
66
|
-
wavFormat.mFormatID =
|
62
|
+
wavFormat.mFormatID = kAudioFormatLinearPCM
|
67
63
|
wavFormat.mSampleRate = 44100.0
|
68
64
|
wavFormat.mChannelsPerFrame = 1
|
69
65
|
AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, nil, &outASBDSize, &wavFormat)
|
70
66
|
|
71
67
|
// wavファイルファイルを開く
|
72
68
|
status = ExtAudioFileCreateWithURL(outFileUrl as CFURL,
|
73
|
-
|
69
|
+
kAudioFormatLinearPCM,
|
74
|
-
|
70
|
+
&wavFormat,
|
75
|
-
|
71
|
+
nil,
|
76
|
-
|
72
|
+
AudioFileFlags.eraseFile.rawValue,
|
77
|
-
|
73
|
+
&outFile)
|
78
74
|
print("---> 04")
|
79
75
|
print(status)
|
80
76
|
print("<--- 04")
|
@@ -85,9 +81,9 @@
|
|
85
81
|
|
86
82
|
// 書き込みプロパティ設定
|
87
83
|
status = ExtAudioFileSetProperty(outFile!,
|
88
|
-
|
84
|
+
kExtAudioFileProperty_ClientDataFormat,
|
89
|
-
|
85
|
+
inASBDSize,
|
90
|
-
|
86
|
+
&inFormat)
|
91
87
|
print("---> 05")
|
92
88
|
print(status)
|
93
89
|
print("<--- 05")
|
2
参考URLの追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -4,8 +4,10 @@
|
|
4
4
|
|
5
5
|
アプリ内で、`m4a`から`wav`への音声変換を行おうとしています。
|
6
6
|
|
7
|
-
|
7
|
+
以下の記事を参考にしています。
|
8
8
|
|
9
|
+
[Swift3でCore Audioを使用した音声ファイル変換 - Voicy Tech Blog](http://voicetech.hatenablog.com/entry/2017/06/07/225127)
|
10
|
+
[audio - iOS Code to Convert m4a to WAV - Stack Overflow](https://stackoverflow.com/questions/35738133/ios-code-to-convert-m4a-to-wav/36001262#36001262)
|
9
11
|
|
10
12
|
###実現したいこと
|
11
13
|
|
1
モジュールの追加、ソースコード修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -7,17 +7,6 @@
|
|
7
7
|
[Stack Overflowの@MScottWaller氏の投稿](https://stackoverflow.com/questions/35738133/ios-code-to-convert-m4a-to-wav/36001262#36001262)を参考にしています。
|
8
8
|
|
9
9
|
|
10
|
-
###発生している問題・エラーメッセージ
|
11
|
-
|
12
|
-
`convertAudio`メソッドの`ExtAudioFileGetProperty(inFile!, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat)`にて、
|
13
|
-
|
14
|
-
**Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value**
|
15
|
-
|
16
|
-
というエラーが表示され、アプリが落ちます。
|
17
|
-
|
18
|
-
`inFile`に`nil`が入っていることが原因のエラーだということはわかっています。
|
19
|
-
|
20
|
-
|
21
10
|
###実現したいこと
|
22
11
|
|
23
12
|
`convertAudio`メソッドを上手く動作させて、音声変換を行いたいです。
|
@@ -28,89 +17,109 @@
|
|
28
17
|
- 音声変換メソッド
|
29
18
|
|
30
19
|
```swift
|
20
|
+
import AVKit
|
21
|
+
import AVFoundation
|
22
|
+
import AudioToolbox
|
23
|
+
import CoreAudioKit
|
24
|
+
|
25
|
+
/* m4a -> wav の音声変換 */
|
31
|
-
func convertAudio(_
|
26
|
+
func convertAudio(_ inFileUrl: URL, _ outFileUrl: URL) {
|
32
|
-
var error : OSStatus = noErr
|
33
|
-
var outFile: ExtAudioFileRef? = nil
|
34
|
-
var inFile : ExtAudioFileRef? = nil
|
35
27
|
|
36
|
-
|
28
|
+
// ステータス
|
37
|
-
var
|
29
|
+
var status: OSStatus = noErr
|
38
30
|
|
31
|
+
// 変換元のm4aファイルを開く
|
32
|
+
var inFile: ExtAudioFileRef?
|
39
|
-
ExtAudioFileOpenURL(
|
33
|
+
status = ExtAudioFileOpenURL(inFileUrl as CFURL, &inFile)
|
34
|
+
print("---> 01")
|
35
|
+
print(status)
|
36
|
+
print("<--- 01")
|
40
37
|
|
41
|
-
var thePropertySize: UInt32 = UInt32(MemoryLayout.stride(ofValue: srcFormat))
|
42
|
-
|
43
|
-
/
|
38
|
+
// 変換先のwavファイルを開く
|
39
|
+
var outFile: ExtAudioFileRef?
|
44
|
-
|
40
|
+
status = ExtAudioFileOpenURL(outFileUrl as CFURL, &outFile)
|
41
|
+
print("---> 02")
|
42
|
+
print(status)
|
43
|
+
print("<--- 02")
|
45
44
|
|
45
|
+
// 出力するwavファイルの情報を取得
|
46
|
-
|
46
|
+
var inASBDSize = UInt32(MemoryLayout<AudioStreamBasicDescription>.size)
|
47
|
-
|
47
|
+
var inFormat = AudioStreamBasicDescription()
|
48
|
-
dstFormat.mChannelsPerFrame = 1
|
49
|
-
dstFormat.mBitsPerChannel = 16
|
50
|
-
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame
|
51
|
-
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame
|
52
|
-
dstFormat.mFramesPerPacket = 1
|
53
|
-
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked |
|
54
|
-
kAudioFormatFlagIsSignedInteger
|
55
48
|
|
56
|
-
/
|
49
|
+
/* *** ERROR!! *** */
|
50
|
+
status = ExtAudioFileGetProperty(inFile!, kExtAudioFileProperty_FileDataFormat, &inASBDSize, &inFormat)
|
57
|
-
|
51
|
+
print("---> 03")
|
58
|
-
outputURL as CFURL,
|
59
|
-
kAudioFileWAVEType,
|
60
|
-
&dstFormat,
|
61
|
-
nil,
|
62
|
-
AudioFileFlags.eraseFile.rawValue,
|
63
|
-
|
52
|
+
print(status)
|
64
|
-
print("
|
53
|
+
print("<--- 03")
|
65
54
|
|
66
|
-
error = ExtAudioFileSetProperty(inFile!,
|
67
|
-
kExtAudioFileProperty_ClientDataFormat,
|
68
|
-
thePropertySize,
|
69
|
-
&dstFormat)
|
70
|
-
print("Error 2 in convertAudio: (error.description)")
|
71
55
|
|
72
|
-
error = ExtAudioFileSetProperty(outFile!,
|
73
|
-
|
56
|
+
/// MARK: 変換先wavファイルをひらく
|
74
|
-
thePropertySize,
|
75
|
-
&dstFormat)
|
76
|
-
print("Error 3 in convertAudio: (error.description)")
|
77
57
|
|
78
|
-
let bufferByteSize : UInt32 = 32768
|
79
|
-
var srcBuffer = [UInt8](repeating: 0, count: 32768)
|
80
|
-
|
58
|
+
// 変換先のoutput.wavを指すURL
|
59
|
+
let toUrl = URL(fileURLWithPath: (NSTemporaryDirectory() as NSString).appendingPathComponent("output.wav"))
|
81
60
|
|
61
|
+
// wavファイル情報
|
62
|
+
var outASBDSize = UInt32(MemoryLayout<AudioStreamBasicDescription>.size)
|
63
|
+
var wavFormat = AudioStreamBasicDescription()
|
64
|
+
wavFormat.mFormatID = kAudioFormatMPEG4AAC
|
65
|
+
wavFormat.mSampleRate = 44100.0
|
66
|
+
wavFormat.mChannelsPerFrame = 1
|
67
|
+
AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, nil, &outASBDSize, &wavFormat)
|
68
|
+
|
69
|
+
// wavファイルファイルを開く
|
70
|
+
status = ExtAudioFileCreateWithURL(outFileUrl as CFURL,
|
71
|
+
kAudioFileM4AType,
|
72
|
+
&wavFormat,
|
73
|
+
nil,
|
74
|
+
AudioFileFlags.eraseFile.rawValue,
|
75
|
+
&outFile)
|
76
|
+
print("---> 04")
|
77
|
+
print(status)
|
78
|
+
print("<--- 04")
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
/// MARK: 変換ルールの指定
|
83
|
+
|
84
|
+
// 書き込みプロパティ設定
|
85
|
+
status = ExtAudioFileSetProperty(outFile!,
|
86
|
+
kExtAudioFileProperty_ClientDataFormat,
|
87
|
+
inASBDSize,
|
88
|
+
&inFormat)
|
89
|
+
print("---> 05")
|
90
|
+
print(status)
|
91
|
+
print("<--- 05")
|
92
|
+
|
93
|
+
|
94
|
+
/// MARK: 変換処理
|
95
|
+
|
96
|
+
// バッファ作成
|
97
|
+
var readFrameSize: UInt32 = 1024 // 一度に読み込むフレーム数
|
98
|
+
var bufferSize = readFrameSize * inFormat.mBytesPerPacket
|
99
|
+
var buffer: UnsafeMutableRawPointer = malloc(Int(bufferSize))
|
100
|
+
defer { free(buffer) }
|
101
|
+
|
102
|
+
var audioBuffer = AudioBufferList()
|
103
|
+
audioBuffer.mNumberBuffers = 1
|
104
|
+
audioBuffer.mBuffers.mNumberChannels = inFormat.mChannelsPerFrame
|
105
|
+
audioBuffer.mBuffers.mDataByteSize = bufferSize
|
106
|
+
audioBuffer.mBuffers.mData = buffer
|
107
|
+
|
108
|
+
// ファイルを読み込んで出力
|
82
|
-
while(true){
|
109
|
+
while (true) {
|
83
|
-
var fillBufList = AudioBufferList(
|
84
|
-
mNumberBuffers: 1,
|
85
|
-
mBuffers: AudioBuffer(
|
86
|
-
mNumberChannels: 2,
|
87
|
-
mDataByteSize: UInt32(srcBuffer.count),
|
88
|
-
mData: &srcBuffer
|
89
|
-
)
|
90
|
-
)
|
91
|
-
|
110
|
+
// WAVファイル読み込み
|
92
|
-
|
93
|
-
if(dstFormat.mBytesPerFrame > 0){
|
94
|
-
numFrames = bufferByteSize / dstFormat.mBytesPerFrame
|
95
|
-
}
|
96
|
-
|
97
|
-
|
111
|
+
ExtAudioFileRead(inFile!, &readFrameSize, &audioBuffer)
|
98
|
-
print("Error 4 in convertAudio: (error.description)")
|
99
|
-
|
100
|
-
|
112
|
+
// 読み込むデータがなくなれば終了
|
101
|
-
error = noErr;
|
102
|
-
break;
|
103
|
-
}
|
104
|
-
|
105
|
-
|
113
|
+
if readFrameSize <= 0 { break }
|
114
|
+
// AACファイル書き込み
|
106
|
-
|
115
|
+
ExtAudioFileWrite(outFile!, readFrameSize, &audioBuffer)
|
107
|
-
print("Error 5 in convertAudio: (error.description)")
|
108
116
|
}
|
117
|
+
|
109
118
|
|
119
|
+
/// MARK: ファイルを閉じる
|
120
|
+
|
121
|
+
ExtAudioFileDispose(inFile!)
|
110
|
-
|
122
|
+
ExtAudioFileDispose(outFile!)
|
111
|
-
print("Error 6 in convertAudio: (error.description)")
|
112
|
-
error = ExtAudioFileDispose(inFile!)
|
113
|
-
print("Error 7 in convertAudio: (error.description)")
|
114
123
|
}
|
115
124
|
```
|
116
125
|
|
@@ -126,5 +135,33 @@
|
|
126
135
|
```
|
127
136
|
|
128
137
|
|
138
|
+
###発生している問題・エラーメッセージ
|
139
|
+
|
140
|
+
`convertAudio`メソッドの`ExtAudioFileGetProperty(inFile!, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat)`にて、
|
141
|
+
|
142
|
+
**Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value**
|
143
|
+
|
144
|
+
というエラーが表示され、アプリが落ちます。
|
145
|
+
|
146
|
+
`inFile`に`nil`が入っていることが原因のエラーだということはわかっています。
|
147
|
+
|
148
|
+
|
149
|
+
- コンソール
|
150
|
+
|
151
|
+
```
|
152
|
+
2017-11-11 01:17:00.088640+0900 enPiT2SUProduct[34488:655917] 231: EXCEPTION (2003334207): "open audio file"
|
153
|
+
---> 01
|
154
|
+
2003334207
|
155
|
+
<--- 01
|
156
|
+
2017-11-11 01:17:00.089532+0900 enPiT2SUProduct[34488:655917] 231: EXCEPTION (2003334207): "open audio file"
|
157
|
+
---> 02
|
158
|
+
2003334207
|
159
|
+
<--- 02
|
160
|
+
// ここでアプリが落ちる
|
161
|
+
```
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
|
129
166
|
###考えたこと
|
130
167
|
音声変換の途中で、 `ExtAudioFileOpenURL(url as CFURL, &inFile)`という処理を行ったときに、`url`が指す音声ファイルを`inFile`にセットすれば、とりあえず、次の処理に進めるのではないかと考えました。
|