@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
- let asset = AVURLAsset(url: audioURL)
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: \(url)")
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neoskola/auto-play",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Android Auto and Apple CarPlay for react-native",
5
5
  "main": "lib/index",
6
6
  "module": "lib/index",