Skip to content

Commit 5f21f66

Browse files
author
Cesar Vargas Casaseca
committed
Allow audio in recording
1 parent 81b0400 commit 5f21f66

File tree

2 files changed

+51
-14
lines changed

2 files changed

+51
-14
lines changed

Wyler/SampleApp/Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
<true/>
2323
<key>NSPhotoLibraryUsageDescription</key>
2424
<string>Save Sample Video to Camera Roll</string>
25+
<key>NSMicrophoneUsageDescription</key>
26+
<string>Record audio</string>
2527
<key>UILaunchStoryboardName</key>
2628
<string>LaunchScreen</string>
2729
<key>UIMainStoryboardFile~iphone</key>

Wyler/Wyler/ScreenRecorder.swift

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,21 @@ import Foundation
1010
import ReplayKit
1111
import Photos
1212

13+
public enum WylerError: Error {
14+
case photoLibraryAccessNotGranted
15+
}
16+
1317
final public class ScreenRecorder {
1418
private var videoOutputURL: URL?
1519
private var videoWriter: AVAssetWriter?
1620
private var videoWriterInput: AVAssetWriterInput?
21+
private var audioWriterInput: AVAssetWriterInput?
1722
private var saveToCameraRoll = false
23+
let recorder = RPScreenRecorder.shared()
1824

19-
public init() {}
25+
public init() {
26+
recorder.isMicrophoneEnabled = true
27+
}
2028

2129
/**
2230
Starts recording the content of the application screen. It works together with stopRecording
@@ -30,12 +38,9 @@ final public class ScreenRecorder {
3038
size: CGSize? = nil,
3139
saveToCameraRoll: Bool = false,
3240
errorHandler: @escaping (Error) -> Void) {
33-
if saveToCameraRoll {
34-
checkPhotoLibraryAuthorizationStatus()
35-
}
36-
3741
createVideoWriter(in: outputURL, error: errorHandler)
3842
addVideoWriterInput(size: size)
43+
addAudioWriterInput()
3944
startCapture(error: errorHandler)
4045
}
4146

@@ -72,25 +77,36 @@ final public class ScreenRecorder {
7277
}
7378

7479
private func addVideoWriterInput(size: CGSize?) {
75-
let passingSize: CGSize
76-
77-
if let passedSize = size {
78-
passingSize = passedSize
79-
} else {
80-
passingSize = UIScreen.main.bounds.size
81-
}
80+
let passingSize: CGSize = size ?? UIScreen.main.bounds.size
8281

8382
let videoSettings: [String: Any] = [AVVideoCodecKey: AVVideoCodecType.h264,
8483
AVVideoWidthKey: passingSize.width,
8584
AVVideoHeightKey: passingSize.height]
8685

8786
let newVideoWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
87+
8888
self.videoWriterInput = newVideoWriterInput
89+
newVideoWriterInput.expectsMediaDataInRealTime = true
8990
videoWriter?.add(newVideoWriterInput)
9091
}
9192

93+
private func addAudioWriterInput() {
94+
let settings = [
95+
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
96+
AVSampleRateKey: 12000,
97+
AVNumberOfChannelsKey: 1,
98+
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
99+
]
100+
101+
let audioInput = AVAssetWriterInput(mediaType: .audio, outputSettings: settings)
102+
self.audioWriterInput = audioInput
103+
104+
audioInput.expectsMediaDataInRealTime = true
105+
videoWriter?.add(audioInput)
106+
}
107+
92108
private func startCapture(error: @escaping (Error) -> Void) {
93-
RPScreenRecorder.shared().startCapture(handler: { (sampleBuffer, sampleType, passedError) in
109+
recorder.startCapture(handler: { (sampleBuffer, sampleType, passedError) in
94110
if let passedError = passedError {
95111
error(passedError)
96112
return
@@ -99,6 +115,10 @@ final public class ScreenRecorder {
99115
switch sampleType {
100116
case .video:
101117
self.handleSampleBuffer(sampleBuffer: sampleBuffer)
118+
case .audioApp, .audioMic:
119+
if self.audioWriterInput?.isReadyForMoreMediaData ?? false {
120+
self.audioWriterInput?.append(sampleBuffer)
121+
}
102122
default:
103123
break
104124
}
@@ -128,8 +148,23 @@ final public class ScreenRecorder {
128148
})
129149

130150
self.videoWriterInput?.markAsFinished()
151+
self.audioWriterInput?.markAsFinished()
131152
self.videoWriter?.finishWriting {
132-
self.saveVideoToCameraRoll(errorHandler: errorHandler)
153+
self.saveVideoToCameraRollAfterAuthorized(errorHandler: errorHandler)
154+
}
155+
}
156+
157+
private func saveVideoToCameraRollAfterAuthorized(errorHandler: @escaping (Error) -> Void) {
158+
if PHPhotoLibrary.authorizationStatus() == .authorized {
159+
self.saveVideoToCameraRoll(errorHandler: errorHandler)
160+
} else {
161+
PHPhotoLibrary.requestAuthorization({ (status) in
162+
if status == .authorized {
163+
self.saveVideoToCameraRoll(errorHandler: errorHandler)
164+
} else {
165+
errorHandler(WylerError.photoLibraryAccessNotGranted)
166+
}
167+
})
133168
}
134169
}
135170

0 commit comments

Comments
 (0)