@javascriptcommon/react-native-track-player 4.1.23 → 4.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/doublesymmetry/trackplayer/model/Track.kt +1 -1
- package/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt +43 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt +30 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioItem.kt +3 -2
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/AudioPlayer.kt +99 -114
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/APMRenderersFactory.kt +9 -5
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/processors/BalanceAudioProcessor.kt +66 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/processors/EqualizerAudioProcessor.kt +517 -0
- package/android/src/main/res/raw/silent_5_seconds.mp3 +0 -0
- package/ios/RNTrackPlayer/RNTrackPlayer.swift +56 -4
- package/ios/RNTrackPlayer/TrackPlayer.mm +30 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioTap.swift +21 -18
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/EqualizerAudioTap.swift +565 -232
- package/lib/specs/NativeTrackPlayer.d.ts +7 -0
- package/lib/src/trackPlayer.d.ts +35 -0
- package/lib/src/trackPlayer.js +50 -0
- package/package.json +1 -1
- package/specs/NativeTrackPlayer.ts +9 -0
- package/src/trackPlayer.ts +58 -0
|
@@ -41,55 +41,58 @@ open class AudioTap {
|
|
|
41
41
|
extension AVPlayerWrapper {
|
|
42
42
|
internal func attachTap(_ tap: AudioTap?, to item: AVPlayerItem) {
|
|
43
43
|
guard let tap else { return }
|
|
44
|
-
|
|
44
|
+
|
|
45
|
+
// Try sync first (works for local/progressive files)
|
|
46
|
+
if let track = item.asset.tracks(withMediaType: .audio).first {
|
|
47
|
+
applyTap(tap, to: item, track: track)
|
|
45
48
|
return
|
|
46
49
|
}
|
|
47
|
-
|
|
50
|
+
|
|
51
|
+
// Async fallback for HLS streams where tracks aren't immediately available
|
|
52
|
+
Task {
|
|
53
|
+
guard let tracks = try? await item.asset.loadTracks(withMediaType: .audio),
|
|
54
|
+
let track = tracks.first else { return }
|
|
55
|
+
await MainActor.run {
|
|
56
|
+
self.applyTap(tap, to: item, track: track)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private func applyTap(_ tap: AudioTap, to item: AVPlayerItem, track: AVAssetTrack) {
|
|
48
62
|
let audioMix = AVMutableAudioMix()
|
|
49
63
|
let params = AVMutableAudioMixInputParameters(track: track)
|
|
50
|
-
|
|
51
|
-
// we need to retain this pointer so it doesn't disappear out from under us.
|
|
52
|
-
// we'll then let it go after we finalize. If the tap changed upstream, we
|
|
53
|
-
// aren't going to pick up the new one until after this player item goes away.
|
|
64
|
+
|
|
54
65
|
let client = UnsafeMutableRawPointer(Unmanaged.passRetained(tap).toOpaque())
|
|
55
|
-
|
|
66
|
+
|
|
56
67
|
var callbacks = MTAudioProcessingTapCallbacks(version: kMTAudioProcessingTapCallbacksVersion_0, clientInfo: client)
|
|
57
68
|
{ tapRef, clientInfo, tapStorageOut in
|
|
58
|
-
// initial tap setup
|
|
59
69
|
guard let clientInfo else { return }
|
|
60
70
|
tapStorageOut.pointee = clientInfo
|
|
61
71
|
let audioTap = Unmanaged<AudioTap>.fromOpaque(clientInfo).takeUnretainedValue()
|
|
62
72
|
audioTap.initialize()
|
|
63
73
|
} finalize: { tapRef in
|
|
64
|
-
// clean up
|
|
65
74
|
let audioTap = Unmanaged<AudioTap>.fromOpaque(MTAudioProcessingTapGetStorage(tapRef)).takeUnretainedValue()
|
|
66
75
|
audioTap.finalize()
|
|
67
|
-
// we're done, we can let go of the pointer we retained.
|
|
68
76
|
Unmanaged.passUnretained(audioTap).release()
|
|
69
77
|
} prepare: { tapRef, maxFrames, processingFormat in
|
|
70
|
-
// allocate memory for sound processing
|
|
71
78
|
let audioTap = Unmanaged<AudioTap>.fromOpaque(MTAudioProcessingTapGetStorage(tapRef)).takeUnretainedValue()
|
|
72
79
|
audioTap.prepare(description: processingFormat.pointee)
|
|
73
80
|
} unprepare: { tapRef in
|
|
74
|
-
// deallocate memory for sound processing
|
|
75
81
|
let audioTap = Unmanaged<AudioTap>.fromOpaque(MTAudioProcessingTapGetStorage(tapRef)).takeUnretainedValue()
|
|
76
82
|
audioTap.unprepare()
|
|
77
83
|
} process: { tapRef, numberFrames, flags, bufferListInOut, numberFramesOut, flagsOut in
|
|
78
84
|
guard noErr == MTAudioProcessingTapGetSourceAudio(tapRef, numberFrames, bufferListInOut, flagsOut, nil, numberFramesOut) else {
|
|
79
85
|
return
|
|
80
86
|
}
|
|
81
|
-
|
|
82
|
-
// process sound data
|
|
83
87
|
let audioTap = Unmanaged<AudioTap>.fromOpaque(MTAudioProcessingTapGetStorage(tapRef)).takeUnretainedValue()
|
|
84
88
|
audioTap.process(numberOfFrames: numberFrames, buffer: UnsafeMutableAudioBufferListPointer(bufferListInOut))
|
|
85
89
|
}
|
|
86
|
-
|
|
90
|
+
|
|
87
91
|
var tapRef: MTAudioProcessingTap?
|
|
88
92
|
let error = MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PreEffects, &tapRef)
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
if error != noErr { return }
|
|
94
|
+
|
|
91
95
|
params.audioTapProcessor = tapRef
|
|
92
|
-
|
|
93
96
|
audioMix.inputParameters = [params]
|
|
94
97
|
item.audioMix = audioMix
|
|
95
98
|
}
|