Created
July 3, 2015 00:01
-
-
Save mingsai/5f8bbd0a99dca559d39e to your computer and use it in GitHub Desktop.
A swift delegate for managing an AVAudioRecorder and it's related events.
This file contains 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
// | |
// MNGRecorderHandler.swift | |
// | |
// | |
// Created by Tommie Carter on 6/29/15. | |
// Copyright © 2015 MING Technology. All rights reserved. | |
// | |
import AVFoundation | |
struct MNGAudioRecorderEvents { | |
static let RecordingFinished = "RecordingFinished" | |
static let RecordingSaved = "RecordingSaved" | |
static let RecordingStarted = "RecordingStarted" | |
static let RecordingStopped = "RecordingStopped" | |
static let RecordingPaused = "RecordingPaused" | |
static let RecordingInterrupted = "RecordingInterrupted" | |
static let RecordingInterruptionEnded = "RecordingInterruptionEnded" | |
static let RecordingErrorOccurred = "RecordingErrorOccurred" | |
static let RecordingCancelationRequested = "RecordingCancelationRequested" | |
static let RecordingCanceled = "RecordingCanceled" | |
} | |
class MNGAudioRecorderHandler: NSObject, AVAudioRecorderDelegate { | |
struct Constants { | |
static let ExtensionM4A = ".m4a" | |
static let SelectorCancelRecording = Selector("cancelRecording:") | |
} | |
let recordSettings = [ | |
AVFormatIDKey:Int(kAudioFormatAppleLossless), | |
AVEncoderBitRateKey:NSNumber(int:64000), | |
AVEncoderAudioQualityKey:AVAudioQuality.Max.rawValue, | |
AVNumberOfChannelsKey:NSNumber(int: 2), | |
AVLinearPCMIsNonInterleaved:false, | |
AVLinearPCMBitDepthKey:NSNumber(int: 32), | |
AVLinearPCMIsBigEndianKey:false, | |
AVLinearPCMIsFloatKey:false, | |
AVSampleRateKey:NSNumber(float: 44100.0) //44100.0 | |
] as [String:AnyObject] | |
var audioRecorder: AVAudioRecorder! | |
var meterTimer:NSTimer! | |
var audioFilename:String! { | |
get { | |
return NSProcessInfo.processInfo().globallyUniqueString.stringByAppendingString(Constants.ExtensionM4A) | |
} | |
} | |
var recordingFilePath:String! | |
// { | |
// get { | |
// return NSTemporaryDirectory() + self.audioFilename | |
// } | |
// } | |
override init() { | |
super.init() | |
self.recordingFilePath = NSTemporaryDirectory() + self.audioFilename | |
//file:///private/var/mobile/Containers/Data/Application/4DD09F1D-EA2E-4FBC-BF5D-C527FB488CDD/tmp/8FCC62A1-A2E7-41A2-9FEC-91787CBB61CA-4075-000006B0AFF6E890.m4a | |
let url = NSURL(fileURLWithPath: self.recordingFilePath) | |
do { | |
if self.audioRecorder == nil { | |
self.audioRecorder = try AVAudioRecorder( URL: url, settings: recordSettings ) | |
self.audioRecorder.prepareToRecord() | |
self.audioRecorder.meteringEnabled = true | |
} | |
} catch let e as NSError { | |
print (e.localizedDescription) | |
} | |
} | |
//MARK: Audio Recorder Delegate Methods | |
func audioRecorderDidFinishRecording(recorder: AVAudioRecorder, successfully flag: Bool) { | |
// | |
} | |
func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder, error: NSError?) { | |
// | |
} | |
func audioRecorderBeginInterruption(recorder: AVAudioRecorder) { | |
// | |
} | |
func audioRecorderEndInterruption(recorder: AVAudioRecorder) { | |
// | |
} | |
func audioRecorderEndInterruption(recorder: AVAudioRecorder, withFlags flags: Int) { | |
// | |
} | |
func audioRecorderEndInterruption(recorder: AVAudioRecorder, withOptions flags: Int) { | |
// | |
} | |
func deleteTemporaryRecording() { | |
do { | |
try NSFileManager.defaultManager().removeItemAtPath(self.recordingFilePath) | |
} catch let e as NSError { | |
print(e.localizedDescription) | |
} | |
} | |
func deleteAllRecordings() { | |
let docsDir = | |
NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String | |
let fileManager = NSFileManager.defaultManager() | |
//let error: NSError? | |
do { | |
let files = try fileManager.contentsOfDirectoryAtPath(docsDir) as [String] | |
let recordings = files.filter( { (name: String) -> Bool in | |
return name.hasSuffix("m4a") | |
}) | |
for var i = 0; i < recordings.count; i++ { | |
let path = docsDir + "/" + recordings[i] | |
do { | |
try fileManager.removeItemAtPath(path) | |
print("removing \(path)") | |
} catch let e as NSError { | |
print(e.localizedDescription) | |
} | |
} | |
} catch let e as NSError { | |
print(e.localizedDescription) | |
} | |
} | |
//MARK: Event Notifications | |
func registerEventObservers () { | |
defaultCenter.addObserver(self, selector: Constants.SelectorCancelRecording, name: MNGAudioRecorderEvents.RecordingCancelationRequested, object: nil) | |
} | |
func deRegisterEventObservers() { | |
defaultCenter.removeObserver(self, name: MNGAudioRecorderEvents.RecordingCancelationRequested, object: nil) | |
} | |
func askForNotifications() { | |
NSNotificationCenter.defaultCenter().addObserver(self, | |
selector:"background:", | |
name: UIApplicationWillResignActiveNotification, | |
object:nil) | |
NSNotificationCenter.defaultCenter().addObserver(self, | |
selector:"foreground:", | |
name:UIApplicationWillEnterForegroundNotification, | |
object:nil) | |
NSNotificationCenter.defaultCenter().addObserver(self, | |
selector:"routeChange:", | |
name:AVAudioSessionRouteChangeNotification, | |
object:nil) | |
} | |
func background(notification:NSNotification) { | |
print("background") | |
} | |
func foreground(notification:NSNotification) { | |
print("foreground") | |
} | |
func routeChange(notification:NSNotification) { | |
// let userInfo:Dictionary<String,String!> = notification.userInfo as Dictionary<String,String!> | |
// let userInfo = notification.userInfo as Dictionary<String,[AnyObject]!> | |
// var reason = userInfo[AVAudioSessionRouteChangeReasonKey] | |
// var userInfo: [NSObject : AnyObject]? { get } | |
//let AVAudioSessionRouteChangeReasonKey: NSString! | |
/* | |
if let reason = notification.userInfo[AVAudioSessionRouteChangeReasonKey] as? NSNumber { | |
} | |
if let info = notification.userInfo as? Dictionary<String,String> { | |
if let rs = info["AVAudioSessionRouteChangeReasonKey"] { | |
var reason = rs.toInt()! | |
if rs.integerValue == Int(AVAudioSessionRouteChangeReason.NewDeviceAvailable.toRaw()) { | |
} | |
switch reason { | |
case AVAudioSessionRouteChangeReason | |
print("new device") | |
} | |
} | |
} | |
var description = userInfo[AVAudioSessionRouteChangePreviousRouteKey] | |
*/ | |
/* | |
// var reason = info.valueForKey(AVAudioSessionRouteChangeReasonKey) as UInt | |
//var reason = info.valueForKey(AVAudioSessionRouteChangeReasonKey) as AVAudioSessionRouteChangeReason.Raw | |
//var description = info.valueForKey(AVAudioSessionRouteChangePreviousRouteKey) as String | |
print(description) | |
switch reason { | |
case AVAudioSessionRouteChangeReason.NewDeviceAvailable.toRaw(): | |
print("new device") | |
case AVAudioSessionRouteChangeReason.OldDeviceUnavailable.toRaw(): | |
print("old device unavail") | |
//case AVAudioSessionRouteChangeReasonCategoryChange | |
//case AVAudioSessionRouteChangeReasonOverride | |
//case AVAudioSessionRouteChangeReasonWakeFromSleep | |
//case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory | |
default: | |
print("something or other") | |
} | |
*/ | |
} | |
//MARK: Event Handler Methods | |
func startRecording (notification:NSNotification) { | |
} | |
func cancelRecording (notification:NSNotification) { | |
} | |
func playRecording (url:NSURL) { | |
//play recording | |
} | |
func saveRecordingToCoreData (title:String, comments:String) { | |
let anAudioStory = AudioStory.createInStore(dbStore) as! AudioStory | |
anAudioStory.data = NSData(contentsOfURL: NSURL(fileURLWithPath: self.recordingFilePath)) | |
anAudioStory.title = title | |
anAudioStory.comments = comments | |
} | |
func saveRecordingToDisk () { | |
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) | |
let docsDir: AnyObject = dirPaths[0] | |
let soundFilePath = docsDir.stringByAppendingPathComponent(self.audioFilename) | |
let filemanager = NSFileManager.defaultManager() | |
if filemanager.fileExistsAtPath(soundFilePath) { | |
// probably won't happen. want to do something about it? | |
print("sound exists") | |
//clear file from temporary directory | |
do { | |
try filemanager.removeItemAtPath(recordingFilePath)} catch let e as NSError { | |
print(e.localizedDescription) | |
} | |
} else { | |
//move file from temporary to docs | |
do { | |
try filemanager.moveItemAtPath(recordingFilePath, toPath: soundFilePath) } catch let e as NSError { print(e.localizedDescription) } | |
} | |
} | |
func recordWithPermission(setup:Bool) { | |
let session:AVAudioSession = AVAudioSession.sharedInstance() | |
// ios 8 and later | |
if (session.respondsToSelector("requestRecordPermission:")) { | |
AVAudioSession.sharedInstance().requestRecordPermission({(granted: Bool)-> Void in | |
if granted { | |
print("Permission to record granted") | |
session.configureSpokenRecordingSession() | |
//self.setSessionPlayAndRecord() | |
// if setup { | |
// self.setupRecorder() | |
// } | |
self.audioRecorder.record() | |
self.meterTimer = NSTimer.scheduledTimerWithTimeInterval(0.1, | |
target:self, | |
selector:"updateAudioMeter:", | |
userInfo:nil, | |
repeats:true) | |
} else { | |
print("Permission to record not granted") | |
} | |
}) | |
} else { | |
print("requestRecordPermission unrecognized") | |
} | |
} | |
// transferred to extension | |
// func setSessionPlayback() { | |
// let session:AVAudioSession = AVAudioSession.sharedInstance() | |
// //var error: NSError? | |
// do { | |
// try session.setCategory(AVAudioSessionCategoryPlayback) | |
// | |
// } catch let e as NSError { | |
// print(e.localizedDescription) | |
// print("could not set session category") | |
// | |
// } | |
// | |
// do { | |
// try session.setActive(true) | |
// } catch let e as NSError { | |
// print(e.localizedDescription) | |
// print("could not make session active") | |
// } | |
// } | |
// | |
// func setSessionPlayAndRecord() { | |
// let session:AVAudioSession = AVAudioSession.sharedInstance() | |
// | |
// do { | |
// try session.setCategory(AVAudioSessionCategoryPlayAndRecord) | |
// print ("session category set to \(session.category)") | |
// } catch let e as NSError { | |
// print("could not set session category") | |
// print(e.localizedDescription) | |
// } | |
// do { | |
// try session.setActive(true) | |
// print ("session active status set to \(session)") | |
// | |
// | |
// } catch let e as NSError { | |
// print("could not make session active") | |
// print(e.localizedDescription) | |
// } | |
// } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment