@neoskola/auto-play 0.3.1 → 0.3.2
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.
|
@@ -19,6 +19,9 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
19
19
|
private var didFinishObserver: NSObjectProtocol?
|
|
20
20
|
private var statusObservation: NSKeyValueObservation?
|
|
21
21
|
private var completionFired = false
|
|
22
|
+
private var downloadTask: URLSessionDownloadTask?
|
|
23
|
+
private var localAudioFileURL: URL?
|
|
24
|
+
private var pendingStartFrom: Double = 0
|
|
22
25
|
|
|
23
26
|
var autoDismissMs: Double? {
|
|
24
27
|
return config.autoDismissMs
|
|
@@ -61,6 +64,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
61
64
|
cleanupPlayer()
|
|
62
65
|
completionFired = false
|
|
63
66
|
lastReportedSecond = Int(startFrom)
|
|
67
|
+
pendingStartFrom = startFrom
|
|
64
68
|
|
|
65
69
|
guard let audioURL = URL(string: url) else {
|
|
66
70
|
print("[NowPlayingTemplate] Invalid audio URL: \(url)")
|
|
@@ -70,7 +74,56 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
70
74
|
// Ensure AVAudioSession is active
|
|
71
75
|
NowPlayingSessionManager.shared.ensureSessionActive()
|
|
72
76
|
|
|
73
|
-
|
|
77
|
+
// Update NowPlaying UI immediately (before download completes)
|
|
78
|
+
config.isPlaying = true
|
|
79
|
+
updateNowPlayingInfo()
|
|
80
|
+
MPNowPlayingInfoCenter.default().playbackState = .playing
|
|
81
|
+
|
|
82
|
+
print("[NowPlayingTemplate] Downloading audio: \(url)")
|
|
83
|
+
|
|
84
|
+
// Download file first, then play from local — avoids FigFilePlayer streaming errors
|
|
85
|
+
downloadTask = URLSession.shared.downloadTask(with: audioURL) { [weak self] tempURL, response, error in
|
|
86
|
+
guard let self = self else { return }
|
|
87
|
+
|
|
88
|
+
if let error = error {
|
|
89
|
+
print("[NowPlayingTemplate] Download failed: \(error.localizedDescription)")
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
guard let tempURL = tempURL else {
|
|
94
|
+
print("[NowPlayingTemplate] Download returned no file")
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Move to a persistent temp location (URLSession deletes the file after this block)
|
|
99
|
+
let localURL = FileManager.default.temporaryDirectory
|
|
100
|
+
.appendingPathComponent("carplay_audio_\(UUID().uuidString).mp3")
|
|
101
|
+
|
|
102
|
+
do {
|
|
103
|
+
// Remove old file if exists
|
|
104
|
+
if let oldFile = self.localAudioFileURL {
|
|
105
|
+
try? FileManager.default.removeItem(at: oldFile)
|
|
106
|
+
}
|
|
107
|
+
try FileManager.default.moveItem(at: tempURL, to: localURL)
|
|
108
|
+
self.localAudioFileURL = localURL
|
|
109
|
+
print("[NowPlayingTemplate] Audio downloaded to: \(localURL.lastPathComponent)")
|
|
110
|
+
} catch {
|
|
111
|
+
print("[NowPlayingTemplate] Failed to move downloaded file: \(error)")
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Start playback on main thread
|
|
116
|
+
DispatchQueue.main.async { [weak self] in
|
|
117
|
+
self?.startPlaybackFromLocalFile(localURL: localURL, startFrom: self?.pendingStartFrom ?? 0)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
downloadTask?.resume()
|
|
121
|
+
|
|
122
|
+
return true
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private func startPlaybackFromLocalFile(localURL: URL, startFrom: Double) {
|
|
126
|
+
let asset = AVURLAsset(url: localURL)
|
|
74
127
|
playerItem = AVPlayerItem(asset: asset)
|
|
75
128
|
|
|
76
129
|
// KVO: detect duration as soon as asset loads (critical for progress bar)
|
|
@@ -128,14 +181,9 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
128
181
|
|
|
129
182
|
// Play
|
|
130
183
|
player?.play()
|
|
131
|
-
|
|
132
|
-
// Update NowPlaying UI
|
|
133
|
-
config.isPlaying = true
|
|
134
|
-
updateNowPlayingInfo()
|
|
135
184
|
MPNowPlayingInfoCenter.default().playbackState = .playing
|
|
136
185
|
|
|
137
|
-
print("[NowPlayingTemplate] Native audio playback started
|
|
138
|
-
return true
|
|
186
|
+
print("[NowPlayingTemplate] Native audio playback started from local file")
|
|
139
187
|
}
|
|
140
188
|
|
|
141
189
|
private func handleTimeUpdate(time: CMTime) {
|
|
@@ -234,6 +282,8 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
234
282
|
}
|
|
235
283
|
|
|
236
284
|
private func cleanupPlayer() {
|
|
285
|
+
downloadTask?.cancel()
|
|
286
|
+
downloadTask = nil
|
|
237
287
|
statusObservation?.invalidate()
|
|
238
288
|
statusObservation = nil
|
|
239
289
|
if let timeObserver = timeObserver {
|
|
@@ -249,6 +299,11 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
249
299
|
player?.pause()
|
|
250
300
|
player = nil
|
|
251
301
|
playerItem = nil
|
|
302
|
+
// Clean up temp audio file
|
|
303
|
+
if let localFile = localAudioFileURL {
|
|
304
|
+
try? FileManager.default.removeItem(at: localFile)
|
|
305
|
+
localAudioFileURL = nil
|
|
306
|
+
}
|
|
252
307
|
}
|
|
253
308
|
|
|
254
309
|
// MARK: - CarPlay UI
|