@capgo/native-audio 6.4.20 → 6.4.21
Sign up to get free protection for your applications and to get access to all the features.
@@ -1,74 +1,118 @@
|
|
1
1
|
import AVFoundation
|
2
2
|
|
3
3
|
public class RemoteAudioAsset: AudioAsset {
|
4
|
-
var
|
5
|
-
var
|
4
|
+
var playerItems: [AVPlayerItem] = []
|
5
|
+
var players: [AVPlayer] = []
|
6
|
+
var playerObservers: [NSKeyValueObservation] = []
|
6
7
|
|
7
8
|
override init(owner: NativeAudio, withAssetId assetId: String, withPath path: String!, withChannels channels: Int!, withVolume volume: Float!, withFadeDelay delay: Float!) {
|
8
9
|
super.init(owner: owner, withAssetId: assetId, withPath: path, withChannels: channels, withVolume: volume, withFadeDelay: delay)
|
9
10
|
|
10
11
|
if let url = URL(string: path) {
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
for _ in 0..<channels {
|
13
|
+
let playerItem = AVPlayerItem(url: url)
|
14
|
+
let player = AVPlayer(playerItem: playerItem)
|
15
|
+
player.volume = volume
|
16
|
+
self.playerItems.append(playerItem)
|
17
|
+
self.players.append(player)
|
18
|
+
|
19
|
+
// Add observer for playback finished
|
20
|
+
let observer = player.observe(\.timeControlStatus) { [weak self] player, _ in
|
21
|
+
if player.timeControlStatus == .paused && player.currentItem?.currentTime() == player.currentItem?.duration {
|
22
|
+
self?.playerDidFinishPlaying(player: player)
|
23
|
+
}
|
24
|
+
}
|
25
|
+
self.playerObservers.append(observer)
|
26
|
+
}
|
14
27
|
}
|
15
28
|
}
|
16
29
|
|
30
|
+
func playerDidFinishPlaying(player: AVPlayer) {
|
31
|
+
self.owner.notifyListeners("complete", data: [
|
32
|
+
"assetId": self.assetId
|
33
|
+
])
|
34
|
+
}
|
35
|
+
|
17
36
|
override func play(time: TimeInterval, delay: TimeInterval) {
|
18
|
-
guard
|
37
|
+
guard !players.isEmpty else { return }
|
38
|
+
let player = players[playIndex]
|
19
39
|
if delay > 0 {
|
20
|
-
// Calculate the future time to play
|
21
40
|
let timeToPlay = CMTimeAdd(CMTimeMakeWithSeconds(player.currentTime().seconds, preferredTimescale: 1), CMTimeMakeWithSeconds(delay, preferredTimescale: 1))
|
22
41
|
player.seek(to: timeToPlay)
|
23
42
|
} else {
|
24
43
|
player.seek(to: CMTimeMakeWithSeconds(time, preferredTimescale: 1))
|
25
44
|
}
|
26
45
|
player.play()
|
46
|
+
playIndex = (playIndex + 1) % players.count
|
27
47
|
}
|
28
48
|
|
29
49
|
override func pause() {
|
30
|
-
|
50
|
+
guard !players.isEmpty else { return }
|
51
|
+
let player = players[playIndex]
|
52
|
+
player.pause()
|
31
53
|
}
|
32
54
|
|
33
55
|
override func resume() {
|
34
|
-
|
56
|
+
guard !players.isEmpty else { return }
|
57
|
+
let player = players[playIndex]
|
58
|
+
player.play()
|
35
59
|
}
|
36
60
|
|
37
61
|
override func stop() {
|
38
|
-
player
|
39
|
-
|
62
|
+
for player in players {
|
63
|
+
player.pause()
|
64
|
+
player.seek(to: CMTime.zero)
|
65
|
+
}
|
40
66
|
}
|
41
67
|
|
42
68
|
override func loop() {
|
43
|
-
player
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
69
|
+
for player in players {
|
70
|
+
player.actionAtItemEnd = .none
|
71
|
+
NotificationCenter.default.addObserver(self,
|
72
|
+
selector: #selector(playerItemDidReachEnd(notification:)),
|
73
|
+
name: .AVPlayerItemDidPlayToEndTime,
|
74
|
+
object: player.currentItem)
|
75
|
+
player.play()
|
76
|
+
}
|
49
77
|
}
|
50
78
|
|
51
79
|
@objc func playerItemDidReachEnd(notification: Notification) {
|
52
|
-
player
|
53
|
-
player
|
80
|
+
guard let player = notification.object as? AVPlayer else { return }
|
81
|
+
player.seek(to: CMTime.zero)
|
82
|
+
player.play()
|
54
83
|
}
|
55
84
|
|
56
85
|
override func unload() {
|
57
86
|
stop()
|
58
87
|
NotificationCenter.default.removeObserver(self)
|
59
|
-
|
60
|
-
|
88
|
+
// Remove KVO observers
|
89
|
+
for observer in playerObservers {
|
90
|
+
observer.invalidate()
|
91
|
+
}
|
92
|
+
playerObservers = []
|
93
|
+
players = []
|
94
|
+
playerItems = []
|
61
95
|
}
|
62
96
|
|
63
97
|
override func setVolume(volume: NSNumber!) {
|
64
|
-
player
|
98
|
+
for player in players {
|
99
|
+
player.volume = volume.floatValue
|
100
|
+
}
|
65
101
|
}
|
66
102
|
|
67
103
|
override func setRate(rate: NSNumber!) {
|
68
|
-
player
|
104
|
+
for player in players {
|
105
|
+
player.rate = rate.floatValue
|
106
|
+
}
|
69
107
|
}
|
70
108
|
|
71
109
|
override func isPlaying() -> Bool {
|
72
|
-
return
|
110
|
+
return players.contains { $0.timeControlStatus == .playing }
|
111
|
+
}
|
112
|
+
|
113
|
+
override func getCurrentTime() -> TimeInterval {
|
114
|
+
guard !players.isEmpty else { return 0 }
|
115
|
+
let player = players[playIndex]
|
116
|
+
return player.currentTime().seconds
|
73
117
|
}
|
74
118
|
}
|