@@ -8,6 +8,7 @@ public class SwiftAudioStreamerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
88 var engine = AVAudioEngine ( )
99 var audioData : [ Float ] = [ ]
1010 var recording = false
11+ var preferredSampleRate : Int ? = nil
1112
1213 // Register plugin
1314 public static func register( with registrar: FlutterPluginRegistrar ) {
@@ -38,38 +39,39 @@ public class SwiftAudioStreamerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
3839 object: nil )
3940 }
4041
41- @objc func handleInterruption( notification: Notification ) {
42- // If no eventSink to emit events to, do nothing (wait)
43- if eventSink == nil {
44- return
45- }
46-
47- guard let userInfo = notification. userInfo,
48- let typeValue = userInfo [ AVAudioSessionInterruptionTypeKey] as? UInt ,
49- let type = AVAudioSession . InterruptionType ( rawValue: typeValue)
50- else {
51- return
52- }
53-
54- switch type {
55- case . began: ( )
56- case . ended:
57- // An interruption ended. Resume playback, if appropriate.
58-
59- guard let optionsValue = userInfo [ AVAudioSessionInterruptionOptionKey] as? UInt else { return }
60- let options = AVAudioSession . InterruptionOptions ( rawValue: optionsValue)
61- if options. contains ( . shouldResume) {
62- startRecording ( )
63- }
64-
65- default :
66- eventSink!(
67- FlutterError (
68- code: " 100 " , message: " Recording was interrupted " ,
69- details: " Another process interrupted recording. " ) )
70- }
42+ @objc func handleInterruption( notification: Notification ) {
43+ // If no eventSink to emit events to, do nothing (wait)
44+ if eventSink == nil {
45+ return
46+ }
47+
48+ guard let userInfo = notification. userInfo,
49+ let typeValue = userInfo [ AVAudioSessionInterruptionTypeKey] as? UInt ,
50+ let type = AVAudioSession . InterruptionType ( rawValue: typeValue)
51+ else {
52+ return
7153 }
7254
55+ switch type {
56+ case . began: ( )
57+ case . ended:
58+ // An interruption ended. Resume playback, if appropriate.
59+
60+ guard let optionsValue = userInfo [ AVAudioSessionInterruptionOptionKey] as? UInt else {
61+ return
62+ }
63+ let options = AVAudioSession . InterruptionOptions ( rawValue: optionsValue)
64+ if options. contains ( . shouldResume) {
65+ startRecording ( sampleRate: preferredSampleRate)
66+ }
67+
68+ default :
69+ eventSink!(
70+ FlutterError (
71+ code: " 100 " , message: " Recording was interrupted " ,
72+ details: " Another process interrupted recording. " ) )
73+ }
74+ }
7375
7476 // Handle stream emitting (Swift => Flutter)
7577 private func emitValues( values: [ Float ] ) {
@@ -89,8 +91,8 @@ public class SwiftAudioStreamerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
8991 ) -> FlutterError ? {
9092 self . eventSink = eventSink
9193 if let args = arguments as? [ String : Any ] {
92- let sampleRate = args [ " sampleRate " ] as? Int
93- startRecording ( sampleRate: sampleRate )
94+ preferredSampleRate = args [ " sampleRate " ] as? Int
95+ startRecording ( sampleRate: preferredSampleRate )
9496 } else {
9597 startRecording ( sampleRate: nil )
9698 }
@@ -108,43 +110,33 @@ public class SwiftAudioStreamerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
108110 func startRecording( sampleRate: Int ? ) {
109111 engine = AVAudioEngine ( )
110112
111- try ! AVAudioSession . sharedInstance ( ) . setCategory (
112- AVAudioSession . Category. playAndRecord, options: . mixWithOthers)
113113 do {
114+ try AVAudioSession . sharedInstance ( ) . setCategory (
115+ AVAudioSession . Category. playAndRecord, options: . mixWithOthers)
116+ try AVAudioSession . sharedInstance ( ) . setActive ( true )
117+
114118 if let sampleRateNotNull = sampleRate {
115119 // Try to set sample rate
116- try print ( AVAudioSession . sharedInstance ( ) . setPreferredSampleRate ( Double ( sampleRateNotNull) ) )
120+ try AVAudioSession . sharedInstance ( ) . setPreferredSampleRate ( Double ( sampleRateNotNull) )
117121 }
118- } catch {
119- print ( " Unexpected error: \( error) . " )
120- }
121122
123+ let input = engine. inputNode
124+ let bus = 0
122125
123- func startRecording( ) {
124- engine = AVAudioEngine ( )
125-
126- do {
127- try AVAudioSession . sharedInstance ( ) . setCategory ( AVAudioSession . Category. playAndRecord, options: . mixWithOthers)
128- try AVAudioSession . sharedInstance ( ) . setActive ( true )
129-
130- if let sampleRateNotNull = sampleRate {
131- // Try to set sample rate
132- try AVAudioSession . sharedInstance ( ) . setPreferredSampleRate ( Double ( sampleRateNotNull) )
133- }
134-
135- let input = engine. inputNode
136- let bus = 0
137-
138- input. installTap ( onBus: bus, bufferSize: 22050 , format: input. inputFormat ( forBus: bus) ) { buffer, _ -> Void in
139- let samples = buffer. floatChannelData ? [ 0 ]
140- // audio callback, samples in samples[0]...samples[buffer.frameLength-1]
141- let arr = Array ( UnsafeBufferPointer ( start: samples, count: Int ( buffer. frameLength) ) )
142- self . emitValues ( values: arr)
143- }
144-
145- try engine. start ( )
146- } catch {
147- eventSink!( FlutterError ( code: " 100 " , message: " Unable to start audio session " , details: error. localizedDescription) )
148- }
126+ input. installTap ( onBus: bus, bufferSize: 22050 , format: input. inputFormat ( forBus: bus) ) {
127+ buffer, _ -> Void in
128+ let samples = buffer. floatChannelData ? [ 0 ]
129+ // audio callback, samples in samples[0]...samples[buffer.frameLength-1]
130+ let arr = Array ( UnsafeBufferPointer ( start: samples, count: Int ( buffer. frameLength) ) )
131+ self . emitValues ( values: arr)
132+ }
133+
134+ try engine. start ( )
135+ } catch {
136+ eventSink!(
137+ FlutterError (
138+ code: " 100 " , message: " Unable to start audio session " , details: error. localizedDescription
139+ ) )
149140 }
141+ }
150142}
0 commit comments