質問編集履歴

1

aaa

2021/04/19 15:40

投稿

hihohi
hihohi

スコア1

test CHANGED
@@ -1 +1 @@
1
- AVassetwriterで記録した動画が無音になる
1
+ aaaaaaaaaaaaaa
test CHANGED
@@ -1,375 +1 @@
1
- 以下コードで動画を撮影したのですが、音声が無音の動画が出力されます。
2
-
3
- キャプチャアウトプットに音声のデータはきているのでapendの部分でなにか記述が間違っているのかもしれないですが、
4
-
5
- どう修正すればただしく音声が記録できるかわかりません。
6
-
7
- 修正が必要な箇所が分かる方、お手数ですがご教示いただきたいです。
8
-
9
-
10
-
11
- ```swift
12
-
13
- func setUp(){
14
-
15
- // 入力の設定
16
-
17
- captureSession.beginConfiguration()
18
-
19
-
20
-
21
- // 入力(マイク)
22
-
23
- guard let audioDevice = AVCaptureDevice.default(for: .audio) else {return}
24
-
25
- do {
26
-
27
- // Wrap the audio device in a capture device input.
28
-
29
- let audioInput = try AVCaptureDeviceInput(device: audioDevice)
30
-
31
- // If the input can be added, add it to the session.
32
-
33
- if captureSession.canAddInput(audioInput) {
34
-
35
- captureSession.addInput(audioInput)
36
-
37
- }
38
-
39
- } catch {
40
-
41
- // Configuration failed. Handle error.
42
-
43
- print("audioInput err")
44
-
45
- }
46
-
47
-
48
-
49
-
50
-
51
- let audioQueue = DispatchQueue(label: "audioqueue")
52
-
53
- let audioDataOutput = AVCaptureAudioDataOutput()
54
-
55
- audioDataOutput.setSampleBufferDelegate(self, queue: audioQueue)
56
-
57
-
58
-
59
- if captureSession.canAddOutput(audioDataOutput) {
60
-
61
- captureSession.addOutput(audioDataOutput)
62
-
63
- }else{
64
-
65
- print("audioDataOutput err")
66
-
67
- }
68
-
69
-
70
-
71
-
72
-
73
- // ビルトインカメラを見つける
74
-
75
- let discoverSession = AVCaptureDevice.DiscoverySession.init(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: .back)
76
-
77
- let devices = discoverSession.devices
78
-
79
- camera = devices.first
80
-
81
-
82
-
83
- // AVCaptureSessionへの入力を設定
84
-
85
- do {
86
-
87
- videoInput = try AVCaptureDeviceInput(device: camera)
88
-
89
- if captureSession.canAddInput(videoInput) {
90
-
91
- captureSession.addInput(videoInput)
92
-
93
- }
94
-
95
- } catch {
96
-
97
- print(error)
98
-
99
- return
100
-
101
- }
102
-
103
-
104
-
105
- // AVCaptureSessionのsessionPresetを設定 (映像品質)
106
-
107
- captureSession.sessionPreset = .high
108
-
109
-
110
-
111
- // ビデオデータ出力
112
-
113
- videoOutput = AVCaptureVideoDataOutput()
114
-
115
-
116
-
117
- if let videoConnection = videoOutput.connection(with: .video) {
118
-
119
- // 必要ならVideoの向き設定
120
-
121
- if videoConnection.isVideoOrientationSupported {
122
-
123
- videoConnection.videoOrientation = .landscapeLeft
124
-
125
- }
126
-
127
- // Video安定化設定
128
-
129
- if videoConnection.isVideoStabilizationSupported {
130
-
131
- videoConnection.preferredVideoStabilizationMode = .cinematic
132
-
133
- }
134
-
135
- }
136
-
137
- // ビデオ設定
138
-
139
- videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey: Int(kCVPixelFormatType_32BGRA)] as [String : Any]
140
-
141
- // リアルタイムキャプチャーしながら画像処理をするときは必須
142
-
143
- videoOutput.alwaysDiscardsLateVideoFrames = true
144
-
145
- // キャプチャーセッション用のキュー
146
-
147
- let queue = DispatchQueue(label: "VideoQueue")
148
-
149
- // フレームごとのデータを処理するデリゲートを設定
150
-
151
- videoOutput.setSampleBufferDelegate(self, queue: queue)
152
-
153
- captureSession.addOutput(videoOutput)
154
-
155
-
156
-
157
- captureSession.commitConfiguration()
158
-
159
- // AVCaptureSessionを開始する
160
-
161
- captureSession.startRunning()
162
-
163
- }
164
-
165
-
166
-
167
-
168
-
169
-
170
-
171
- ```
172
-
173
-
174
-
175
- キャプチャ
176
-
177
-
178
-
179
- ```swift
180
-
181
- func startCapture() {
182
-
183
- // ビデオ入力設定 (h264コーデックを使用・フルHD)
184
-
185
- let videoSettings = [
186
-
187
- AVVideoWidthKey: 1920, //1920
188
-
189
- AVVideoHeightKey: 1080, //1080
190
-
191
- AVVideoCodecKey: AVVideoCodecType.h264
192
-
193
- ] as [String: Any]
194
-
195
- videoAssetInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSettings)
196
-
197
-
198
-
199
- //音声入力の設定
200
-
201
- let audioOutputSettings: Dictionary<String, Any> = [
202
-
203
- AVFormatIDKey: Int(kAudioFormatMPEG4AAC) as Any,
204
-
205
- AVNumberOfChannelsKey: 1 as Any,
206
-
207
- AVSampleRateKey: 44100.0 as Any,
208
-
209
- AVEncoderBitRateKey: 128000 as Any
210
-
211
- ]
212
-
213
- audioAssetInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: audioOutputSettings)
214
-
215
-
216
-
217
- // フレームごとの画像を処理するためのバッファーを準備
218
-
219
- pixelBuffer = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: videoAssetInput, sourcePixelBufferAttributes: [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)])
220
-
221
-
222
-
223
- // フレーム番号の初期化
224
-
225
- frameNumber = 0
226
-
227
- do {
228
-
229
- // アセットライターの準備
230
-
231
- checkForAndDeleteFile() //動画あったら消しとく
232
-
233
- try assetWriter = AVAssetWriter(outputURL: self.movieURL() as URL, fileType: AVFileType.mov)
234
-
235
- videoAssetInput.expectsMediaDataInRealTime = true
236
-
237
- audioAssetInput.expectsMediaDataInRealTime = true
238
-
239
- // アセットライターに入力を接続
240
-
241
- assetWriter.add(videoAssetInput)
242
-
243
- assetWriter.add(audioAssetInput)
244
-
245
- assetWriter.startWriting()
246
-
247
- assetWriter.startSession(atSourceTime: CMTime.zero)
248
-
249
- } catch {
250
-
251
- print("could not start video recording ", error)
252
-
253
- }
254
-
255
- }
256
-
257
-
258
-
259
- func stopCapture() {
260
-
261
- videoAssetInput.markAsFinished()
262
-
263
- audioAssetInput.markAsFinished()
264
-
265
- // endSession()を呼ばないとキャプチャーを正常終了できない
266
-
267
- assetWriter.endSession(atSourceTime: endTime)
268
-
269
- // キャプチャー(ビデオ保存)を終了
270
-
271
- assetWriter.finishWriting {
272
-
273
- self.videoAssetInput = nil
274
-
275
- self.audioAssetInput = nil
276
-
277
- self.saveMovieToCameraRoll()
278
-
279
- }
280
-
281
- }
282
-
283
-
284
-
285
- func captureOutput(_ captureoutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
286
-
287
-
288
-
289
- // キャプチャーしたデータが来なかったら処理しない
290
-
291
- if !CMSampleBufferDataIsReady(sampleBuffer) {
292
-
293
- return
294
-
295
- }
296
-
297
-
298
-
299
- let isVideo = captureoutput is AVCaptureVideoDataOutput
300
-
301
-
302
-
303
-
304
-
305
- //キャプチャー開始時刻を記録
306
-
307
- if frameNumber == 0 {
308
-
309
- startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
310
-
311
- }
312
-
313
- // 現在時刻
314
-
315
- let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
316
-
317
- let frameTime = CMTimeSubtract(timestamp, startTime)
318
-
319
-
320
-
321
- //サンプルバッファをCImageにする
322
-
323
- if isVideo {
324
-
325
- guard let buffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
326
-
327
- let cameraImage = CIImage(cvPixelBuffer: buffer)
328
-
329
- //ディスプレイに画像を返す処理
330
-
331
- DispatchQueue.main.async {
332
-
333
- let filteredImage = UIImage(ciImage: cameraImage)
334
-
335
- self.filteredImageView.image = filteredImage
336
-
337
- }
338
-
339
- if self.isRecording {
340
-
341
- if self.videoAssetInput.isReadyForMoreMediaData {
342
-
343
- let filterdBuffer = pixelBufferFromCIImage(ciImage: cameraImage)
344
-
345
- self.pixelBuffer.append(filterdBuffer!, withPresentationTime: frameTime)
346
-
347
- self.frameNumber += 1
348
-
349
- }
350
-
351
- }
352
-
353
-
354
-
355
- } else {
356
-
357
- if self.isRecording {
358
-
359
- if self.audioAssetInput.isReadyForMoreMediaData {
360
-
361
- self.audioAssetInput.append(sampleBuffer)
362
-
363
- }
364
-
365
- }
366
-
367
- }
368
-
369
- self.endTime = frameTime
370
-
371
- }
372
-
373
-
374
-
375
- ```
1
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa