Last active
September 13, 2018 23:36
-
-
Save zonble/412d43eac5372fb8847626c7d0f3657c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import AVFoundation | |
class ZBSimpleRecorder: NSObject { | |
var audioEngine: AVAudioEngine? | |
var file: ExtAudioFileRef? | |
func start(fileURL:URL) { | |
self.stop() | |
func M4aFormat() -> AudioStreamBasicDescription { | |
return AudioStreamBasicDescription(mSampleRate: 44100, | |
mFormatID: kAudioFormatMPEG4AAC, | |
mFormatFlags: AudioFormatFlags(MPEG4ObjectID.aac_Main.rawValue), | |
mBytesPerPacket: 0, | |
mFramesPerPacket: 1024, | |
mBytesPerFrame: 0, | |
mChannelsPerFrame: 2, | |
mBitsPerChannel: 0, | |
mReserved: 0) | |
} | |
audioEngine = AVAudioEngine() | |
guard let audioEngine = audioEngine else { | |
return | |
} | |
let audioSession = AVAudioSession.sharedInstance() | |
try? audioSession.setCategory(AVAudioSessionCategoryRecord) | |
try? audioSession.setMode(AVAudioSessionModeVoiceChat) | |
try? audioSession.setActive(true, with: .notifyOthersOnDeactivation) | |
guard let inputNode = audioEngine.inputNode else { fatalError("Audio engine has no input node") } | |
let recordingFormat = inputNode.outputFormat(forBus: 0) | |
var outputFormat = M4aFormat() | |
var status = noErr | |
status = ExtAudioFileCreateWithURL(fileURL as CFURL, kAudioFileM4AType, &outputFormat, nil, AudioFileFlags.eraseFile.rawValue, &file) | |
assert(status == noErr) | |
var codecManufacturer = kAppleSoftwareAudioCodecManufacturer | |
status = ExtAudioFileSetProperty(file!, kExtAudioFileProperty_CodecManufacturer, UInt32(MemoryLayout<UInt32>.size), &codecManufacturer) | |
assert(status == noErr) | |
status = ExtAudioFileSetProperty(file!, kExtAudioFileProperty_ClientDataFormat, UInt32(MemoryLayout<AudioStreamBasicDescription>.size), recordingFormat.streamDescription) | |
assert(status == noErr) | |
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in | |
let numberOfFrames = buffer.frameLength | |
let audioBufferList = buffer.audioBufferList | |
let status = ExtAudioFileWrite(self.file!, numberOfFrames, audioBufferList) | |
assert(status == noErr) | |
} | |
audioEngine.prepare() | |
try? audioEngine.start() | |
} | |
func stop() { | |
guard let audioEngine = audioEngine else { | |
return | |
} | |
let audioSession = AVAudioSession.sharedInstance() | |
try? audioSession.setActive(false, with: .notifyOthersOnDeactivation) | |
if let file = file { | |
ExtAudioFileDispose(file) | |
self.file = nil | |
} | |
audioEngine.stop() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment