@@ -10,114 +10,151 @@ import UIKit
10
10
import AVFoundation
11
11
12
12
public 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 )
16
16
}
17
17
18
18
public 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 )
37
19
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 {
44
55
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
+ }
47
61
}
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)
54
88
}
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
55
100
}
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
56
113
}
57
114
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
+ }
68
119
}
69
120
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 )
73
124
}
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
+
81
130
}
82
131
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
+ }
93
136
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 ( )
105
142
}
106
- updater. invalidate ( )
143
+
144
+ // DispatchQueue.main.async {
145
+ self . playStopCallback ? ( self . identify)
146
+ // }
147
+
107
148
UIDevice . current. isProximityMonitoringEnabled = false
108
149
self . delegate? . didAudioPlayerStopPlay ( self . player)
109
150
}
110
- }
111
- deinit {
112
- NotificationCenter . default. removeObserver ( self )
113
- }
114
151
}
115
152
116
153
117
154
// MARK: - AVAudioPlayerDelegate
118
155
extension 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
+ }
123
160
}
0 commit comments