react-native-nitro-player 0.5.2 → 0.5.3

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/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A powerful audio player library for React Native with playlist management, playback controls, and support for Android Auto and CarPlay.
4
4
 
5
+ Documentation: [https://nitroplayer.riteshshukla.in/](https://nitroplayer.riteshshukla.in/)
6
+
5
7
  ## Installation
6
8
 
7
9
  ```bash
@@ -41,7 +41,7 @@ final class DownloadDatabase {
41
41
  let record = DownloadedTrackRecord(
42
42
  trackId: track.trackId,
43
43
  originalTrack: self.trackItemToRecord(track.originalTrack),
44
- localPath: track.localPath,
44
+ localPath: URL(fileURLWithPath: track.localPath).lastPathComponent,
45
45
  localArtworkPath: self.variantToString(track.localArtworkPath),
46
46
  downloadedAt: track.downloadedAt,
47
47
  fileSize: track.fileSize,
@@ -71,12 +71,13 @@ final class DownloadDatabase {
71
71
  return false
72
72
  }
73
73
  // Verify file still exists
74
- let exists = FileManager.default.fileExists(atPath: record.localPath)
74
+ let absolutePath = resolveAbsolutePath(for: record)
75
+ let exists = FileManager.default.fileExists(atPath: absolutePath)
75
76
  if exists {
76
- print("✅ DownloadDatabase: Track \(trackId) IS downloaded at \(record.localPath)")
77
+ print("✅ DownloadDatabase: Track \(trackId) IS downloaded at \(absolutePath)")
77
78
  } else {
78
79
  print(
79
- "❌ DownloadDatabase: Track \(trackId) record exists but file NOT found at \(record.localPath)"
80
+ "❌ DownloadDatabase: Track \(trackId) record exists but file NOT found at \(absolutePath)"
80
81
  )
81
82
  }
82
83
  return exists
@@ -129,10 +130,11 @@ final class DownloadDatabase {
129
130
  return nil
130
131
  }
131
132
 
132
- print(" Found record, checking file at: \(record.localPath)")
133
+ let absolutePath = resolveAbsolutePath(for: record)
134
+ print(" Found record, checking file at: \(absolutePath)")
133
135
 
134
136
  // Verify file still exists
135
- guard FileManager.default.fileExists(atPath: record.localPath) else {
137
+ guard FileManager.default.fileExists(atPath: absolutePath) else {
136
138
  print(" ❌ File does NOT exist, cleaning up record")
137
139
  // File was deleted externally, clean up record
138
140
  queue.async(flags: .barrier) {
@@ -156,8 +158,9 @@ final class DownloadDatabase {
156
158
  var invalidTrackIds: [String] = []
157
159
 
158
160
  for (trackId, record) in downloadedTracks {
159
- print(" Checking track \(trackId) at path: \(record.localPath)")
160
- if FileManager.default.fileExists(atPath: record.localPath) {
161
+ let absolutePath = resolveAbsolutePath(for: record)
162
+ print(" Checking track \(trackId) at path: \(absolutePath)")
163
+ if FileManager.default.fileExists(atPath: absolutePath) {
161
164
  print(" ✅ File exists")
162
165
  validTracks.append(recordToDownloadedTrack(record))
163
166
  } else {
@@ -241,8 +244,9 @@ final class DownloadDatabase {
241
244
  var trackIdsToRemove: [String] = []
242
245
 
243
246
  for (trackId, record) in downloadedTracks {
244
- if !FileManager.default.fileExists(atPath: record.localPath) {
245
- print(" ❌ Missing file for track \(trackId): \(record.localPath)")
247
+ let absolutePath = resolveAbsolutePath(for: record)
248
+ if !FileManager.default.fileExists(atPath: absolutePath) {
249
+ print(" ❌ Missing file for track \(trackId): \(absolutePath)")
246
250
  trackIdsToRemove.append(trackId)
247
251
  }
248
252
  }
@@ -283,7 +287,7 @@ final class DownloadDatabase {
283
287
  guard let record = self.downloadedTracks[trackId] else { return }
284
288
 
285
289
  // Delete the file
286
- DownloadFileManager.shared.deleteFile(at: record.localPath)
290
+ DownloadFileManager.shared.deleteFile(at: self.resolveAbsolutePath(for: record))
287
291
 
288
292
  // Delete artwork if exists
289
293
  if let artworkPath = record.localArtworkPath {
@@ -314,7 +318,7 @@ final class DownloadDatabase {
314
318
  // Delete all tracks in the playlist
315
319
  for trackId in trackIds {
316
320
  if let record = self.downloadedTracks[trackId] {
317
- DownloadFileManager.shared.deleteFile(at: record.localPath)
321
+ DownloadFileManager.shared.deleteFile(at: self.resolveAbsolutePath(for: record))
318
322
  if let artworkPath = record.localArtworkPath {
319
323
  DownloadFileManager.shared.deleteFile(at: artworkPath)
320
324
  }
@@ -333,7 +337,7 @@ final class DownloadDatabase {
333
337
  queue.async(flags: .barrier) {
334
338
  // Delete all files
335
339
  for record in self.downloadedTracks.values {
336
- DownloadFileManager.shared.deleteFile(at: record.localPath)
340
+ DownloadFileManager.shared.deleteFile(at: self.resolveAbsolutePath(for: record))
337
341
  if let artworkPath = record.localArtworkPath {
338
342
  DownloadFileManager.shared.deleteFile(at: artworkPath)
339
343
  }
@@ -376,12 +380,30 @@ final class DownloadDatabase {
376
380
  [String: DownloadedTrackRecord].self, from: tracksData)
377
381
  print("✅ DownloadDatabase: Loaded \(self.downloadedTracks.count) tracks from disk")
378
382
 
383
+ // Migrate absolute paths → filenames (one-time, for existing installs)
384
+ var needsMigration = false
385
+ for (trackId, record) in self.downloadedTracks {
386
+ if record.localPath.contains("/") {
387
+ let filename = URL(fileURLWithPath: record.localPath).lastPathComponent
388
+ self.downloadedTracks[trackId] = DownloadedTrackRecord(
389
+ trackId: record.trackId,
390
+ originalTrack: record.originalTrack,
391
+ localPath: filename,
392
+ localArtworkPath: record.localArtworkPath,
393
+ downloadedAt: record.downloadedAt,
394
+ fileSize: record.fileSize,
395
+ storageLocation: record.storageLocation
396
+ )
397
+ needsMigration = true
398
+ }
399
+ }
400
+ if needsMigration { self.saveToDisk() }
401
+
379
402
  // Log each downloaded track
380
403
  for (trackId, record) in self.downloadedTracks {
381
404
  print(" 📥 \(trackId)")
382
405
  print(" Title: \(record.originalTrack.title)")
383
- print(" Path: \(record.localPath)")
384
- print(" Exists: \(FileManager.default.fileExists(atPath: record.localPath))")
406
+ print(" Path (filename): \(record.localPath)")
385
407
  }
386
408
  } catch {
387
409
  print("❌ DownloadDatabase: Failed to load tracks from disk: \(error)")
@@ -415,6 +437,11 @@ final class DownloadDatabase {
415
437
 
416
438
  // MARK: - Conversion Helpers
417
439
 
440
+ private func resolveAbsolutePath(for record: DownloadedTrackRecord) -> String {
441
+ let location: StorageLocation = record.storageLocation == "private" ? .private : .public
442
+ return DownloadFileManager.shared.absolutePath(forFilename: record.localPath, storageLocation: location)
443
+ }
444
+
418
445
  /// Convert Variant_NullType_String? to String?
419
446
  private func variantToString(_ variant: Variant_NullType_String?) -> String? {
420
447
  guard let variant = variant else { return nil }
@@ -461,7 +488,7 @@ final class DownloadDatabase {
461
488
  return DownloadedTrack(
462
489
  trackId: record.trackId,
463
490
  originalTrack: recordToTrackItem(record.originalTrack),
464
- localPath: record.localPath,
491
+ localPath: resolveAbsolutePath(for: record),
465
492
  localArtworkPath: stringToVariant(record.localArtworkPath),
466
493
  downloadedAt: record.downloadedAt,
467
494
  fileSize: record.fileSize,
@@ -327,4 +327,11 @@ final class DownloadFileManager {
327
327
 
328
328
  return nil
329
329
  }
330
+
331
+ /// Reconstructs the current absolute path for a stored filename and storage location.
332
+ /// Always uses the current app container path, so it survives container UUID changes.
333
+ func absolutePath(forFilename filename: String, storageLocation: StorageLocation) -> String {
334
+ let dir = storageLocation == .private ? privateDownloadsDirectory : publicDownloadsDirectory
335
+ return dir.appendingPathComponent(filename).path
336
+ }
330
337
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-player",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "A powerful audio player library for React Native with playlist management, playback controls, and support for Android Auto and CarPlay",
5
5
  "main": "lib/index",
6
6
  "module": "lib/index",