@@ -10,114 +10,151 @@ import UIKit
1010import AVFoundation
1111
1212public protocol IMUIAudioPlayerDelegate : NSObjectProtocol {
13- func didAudioPlayerBeginPlay( _ AudioPlayer: AVAudioPlayer )
14- func didAudioPlayerStopPlay( _ AudioPlayer: AVAudioPlayer )
15- func didAudioPlayerPausePlay( _ AudioPlayer: AVAudioPlayer )
13+ func didAudioPlayerBeginPlay( _ AudioPlayer: AVAudioPlayer )
14+ func didAudioPlayerStopPlay( _ AudioPlayer: AVAudioPlayer )
15+ func didAudioPlayerPausePlay( _ AudioPlayer: AVAudioPlayer )
1616}
1717
1818public class IMUIAudioPlayerHelper : NSObject {
19-
20- static let sharedInstance = IMUIAudioPlayerHelper ( )
21-
22-
23- var player : AVAudioPlayer !
24- weak var delegate : IMUIAudioPlayerDelegate ?
25-
26- // play tick callback
27- public typealias ProgressCallback = ( _ currentTime: TimeInterval , _ duration: TimeInterval ) -> ( )
28- public typealias FinishCallback = ( ) -> ( )
29-
30- var playProgressCallback : ProgressCallback ?
31- var playFinishCallback : FinishCallback ?
32- var updater : CADisplayLink ! = nil
33-
34- override init ( ) {
35- super. init ( )
36- NotificationCenter . default. addObserver ( self , selector: #selector( sensorStateChange ( notification: ) ) , name: NSNotification . Name ( rawValue: " UIDeviceProximityStateDidChangeNotification " ) , object: nil )
3719
38- }
39-
40- func sensorStateChange( notification: Notification ) {
41- if UIDevice . current. proximityState {
42- do {
43- try AVAudioSession . sharedInstance ( ) . setCategory ( AVAudioSessionCategoryPlayAndRecord)
20+ @objc public static let sharedInstance = IMUIAudioPlayerHelper ( )
21+
22+
23+ var player : AVAudioPlayer !
24+ weak var delegate : IMUIAudioPlayerDelegate ?
25+
26+ // play tick callback
27+ public typealias ProgressCallback = ( _ identify: String ,
28+ _ averagePower: Float ,
29+ _ currentTime: TimeInterval ,
30+ _ duration: TimeInterval ) -> ( )
31+ public typealias FinishCallback = ( String ) -> ( )
32+ public typealias StopCallback = ( String ) -> ( )
33+
34+ var playProgressCallback : ProgressCallback ?
35+ var playFinishCallback : FinishCallback ?
36+ var playStopCallback : StopCallback ?
37+
38+ var updater : CADisplayLink ! = nil
39+ var identify = " "
40+
41+ override init ( ) {
42+ super. init ( )
43+ NotificationCenter . default. addObserver ( self , selector: #selector( sensorStateChange) , name: UIDevice . proximityStateDidChangeNotification, object: nil )
44+ }
45+
46+ @objc func sensorStateChange( ) {
47+ do {
48+ if UIDevice . current. proximityState {
49+ if #available( iOS 10 . 0 , * ) {
50+ try AVAudioSession . sharedInstance ( ) . setCategory ( . playAndRecord, mode: . default)
51+ } else {
52+ AVAudioSession . sharedInstance ( ) . perform ( NSSelectorFromString ( " setCategory:error: " ) , with: AVAudioSession . Category. playAndRecord)
53+ }
54+ } else {
4455
45- } catch let error as NSError {
46- print ( " set category fail \( error) " )
56+ if #available( iOS 10 . 0 , * ) {
57+ try AVAudioSession . sharedInstance ( ) . setCategory ( . playback, mode: . default)
58+ } else {
59+ AVAudioSession . sharedInstance ( ) . perform ( NSSelectorFromString ( " setCategory:error: " ) , with: AVAudioSession . Category. playback)
60+ }
4761 }
48- } else {
49- do {
50- try AVAudioSession . sharedInstance ( ) . setCategory ( AVAudioSessionCategoryPlayback)
51-
52- } catch let error as NSError {
53- print ( " set category fail \( error) " )
62+ } catch let error as NSError {
63+ print ( " set category fail \( error) " )
64+ }
65+
66+ }
67+
68+ deinit {
69+ NotificationCenter . default. removeObserver ( self )
70+ }
71+
72+ open func playAudioWithData( _ identify: String ,
73+ _ voiceData: Data ,
74+ _ progressCallback: @escaping ProgressCallback ,
75+ _ finishCallBack: @escaping FinishCallback ,
76+ _ stopCallBack: @escaping StopCallback ) {
77+ self . stopAudio ( )
78+ do {
79+ self . identify = identify
80+ self . playProgressCallback = progressCallback
81+ self . playFinishCallback = finishCallBack
82+ self . playStopCallback = stopCallBack
83+
84+ if #available( iOS 10 . 0 , * ) {
85+ try AVAudioSession . sharedInstance ( ) . setCategory ( . playback, mode: . default)
86+ } else {
87+ AVAudioSession . sharedInstance ( ) . perform ( NSSelectorFromString ( " setCategory:error: " ) , with: AVAudioSession . Category. playback)
5488 }
89+
90+ updater = CADisplayLink ( target: self , selector: #selector( self . trackAudio) )
91+ updater. add ( to: RunLoop . current, forMode: . common)
92+ updater. frameInterval = 1
93+ } catch let error as NSError {
94+ print ( " set category fail \( error) " )
95+ }
96+
97+ if self . player != nil {
98+ self . player. stop ( )
99+ self . player = nil
55100 }
101+
102+ do {
103+ let voicePlayer : AVAudioPlayer = try AVAudioPlayer ( data: voiceData)
104+ voicePlayer. delegate = self
105+ voicePlayer. play ( )
106+ voicePlayer. isMeteringEnabled = true ;
107+ self . player = voicePlayer
108+ } catch let error as NSError {
109+ print ( " alloc AVAudioPlayer with voice data fail with error \( error) " )
110+ }
111+
112+ UIDevice . current. isProximityMonitoringEnabled = true
56113 }
57114
58- open func playAudioWithData( _ voiceData: Data , progressCallback: @escaping ProgressCallback , finishCallBack: @escaping FinishCallback ) {
59- do {
60- self . playProgressCallback = progressCallback
61- self . playFinishCallback = finishCallBack
62- try AVAudioSession . sharedInstance ( ) . setCategory ( AVAudioSessionCategoryPlayback)
63- updater = CADisplayLink ( target: self , selector: #selector( self . trackAudio) )
64- updater. add ( to: RunLoop . current, forMode: RunLoopMode . commonModes)
65- updater. frameInterval = 1
66- } catch let error as NSError {
67- print ( " set category fail \( error) " )
115+ open func renewProgressCallback( _ identfy: String , progressCallback: @escaping ProgressCallback ) {
116+ if identfy == self . identify {
117+ self . playProgressCallback = progressCallback
118+ }
68119 }
69120
70- if self . player != nil {
71- self . player. stop ( )
72- self . player = nil
121+ @ objc func trackAudio ( ) {
122+ player. updateMeters ( )
123+ self . playProgressCallback ? ( self . identify , player. averagePower ( forChannel : 0 ) , player . currentTime , player . duration )
73124 }
74- do {
75- let voicePlayer : AVAudioPlayer = try AVAudioPlayer ( data: voiceData)
76- voicePlayer. delegate = self
77- voicePlayer. play ( )
78- self . player = voicePlayer
79- } catch let error as NSError {
80- print ( " alloc AVAudioPlayer with voice data fail with error \( error) " )
125+
126+ func pausePlayingAudio( ) {
127+ self . player? . pause ( )
128+ updater. invalidate ( )
129+
81130 }
82131
83- UIDevice . current. isProximityMonitoringEnabled = true
84- }
85-
86- func trackAudio( ) {
87- self . playProgressCallback ? ( player. currentTime, player. duration)
88- }
89-
90- func pausePlayingAudio( ) {
91- self . player? . pause ( )
92- updater. invalidate ( )
132+ func resumePlayingAudio( ) {
133+ self . player? . play ( )
134+ updater. add ( to: RunLoop . current, forMode: . common)
135+ }
93136
94- }
95-
96- func resumePlayingAudio( ) {
97- self . player? . play ( )
98- updater. add ( to: RunLoop . current, forMode: RunLoopMode . commonModes)
99- }
100-
101- func stopAudio( ) {
102- if self . player != nil {
103- if self . player. isPlaying {
104- self . player. stop ( )
137+ @objc open func stopAudio( ) {
138+ self . playProgressCallback = nil
139+ updater? . invalidate ( )
140+ if ( self . player != nil ) && self . player. isPlaying {
141+ self . player? . stop ( )
105142 }
106- updater. invalidate ( )
143+
144+ // DispatchQueue.main.async {
145+ self . playStopCallback ? ( self . identify)
146+ // }
147+
107148 UIDevice . current. isProximityMonitoringEnabled = false
108149 self . delegate? . didAudioPlayerStopPlay ( self . player)
109150 }
110- }
111- deinit {
112- NotificationCenter . default. removeObserver ( self )
113- }
114151}
115152
116153
117154// MARK: - AVAudioPlayerDelegate
118155extension IMUIAudioPlayerHelper : AVAudioPlayerDelegate {
119- public func audioPlayerDidFinishPlaying( _ player: AVAudioPlayer , successfully flag: Bool ) {
120- self . stopAudio ( )
121- self . playFinishCallback ? ( )
122- }
156+ public func audioPlayerDidFinishPlaying( _ player: AVAudioPlayer , successfully flag: Bool ) {
157+ self . stopAudio ( )
158+ self . playFinishCallback ? ( self . identify )
159+ }
123160}
0 commit comments