@capgo/native-audio 8.3.4 → 8.3.6

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.
@@ -101,6 +101,7 @@ public class NativeAudio extends Plugin implements AudioManager.OnAudioFocusChan
101
101
  private String currentlyPlayingAssetId;
102
102
  private static final int NOTIFICATION_ID = 1001;
103
103
  private static final String CHANNEL_ID = "native_audio_channel";
104
+ private static final int MAX_NOTIFICATION_ARTWORK_SIZE = 512;
104
105
 
105
106
  // Track playOnce assets for automatic cleanup
106
107
  private Set<String> playOnceAssets = new HashSet<>();
@@ -1633,16 +1634,40 @@ public class NativeAudio extends Plugin implements AudioManager.OnAudioFocusChan
1633
1634
  Uri uri = Uri.parse(urlString);
1634
1635
  Bitmap bitmap = null;
1635
1636
 
1637
+ // Configure BitmapFactory options to decode at full resolution
1638
+ BitmapFactory.Options options = new BitmapFactory.Options();
1639
+ options.inScaled = false; // Disable density-based scaling
1640
+ options.inPreferredConfig = Bitmap.Config.ARGB_8888; // Use high quality format
1641
+
1636
1642
  if (uri.getScheme() == null || uri.getScheme().equals("file")) {
1637
1643
  // Local file
1638
1644
  File file = new File(uri.getPath());
1639
1645
  if (file.exists()) {
1640
- bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
1646
+ bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
1641
1647
  }
1642
1648
  } else {
1643
1649
  // Remote URL
1644
1650
  URL url = new URL(urlString);
1645
- bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
1651
+ bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream(), null, options);
1652
+ }
1653
+
1654
+ // Resize to optimal notification size if the bitmap is too large
1655
+ // Android notifications typically display artwork at around 128-256dp
1656
+ // We target 512px as a good balance between quality and memory usage
1657
+ if (bitmap != null && bitmap.getWidth() > 0 && bitmap.getHeight() > 0) {
1658
+ if (bitmap.getWidth() > MAX_NOTIFICATION_ARTWORK_SIZE || bitmap.getHeight() > MAX_NOTIFICATION_ARTWORK_SIZE) {
1659
+ float scale = Math.min(
1660
+ (float) MAX_NOTIFICATION_ARTWORK_SIZE / bitmap.getWidth(),
1661
+ (float) MAX_NOTIFICATION_ARTWORK_SIZE / bitmap.getHeight()
1662
+ );
1663
+ int newWidth = Math.round(bitmap.getWidth() * scale);
1664
+ int newHeight = Math.round(bitmap.getHeight() * scale);
1665
+ Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
1666
+ if (scaledBitmap != null) {
1667
+ bitmap.recycle(); // Free memory from original bitmap
1668
+ bitmap = scaledBitmap;
1669
+ }
1670
+ }
1646
1671
  }
1647
1672
 
1648
1673
  Bitmap finalBitmap = bitmap;
@@ -113,10 +113,9 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
113
113
 
114
114
  func getCurrentTime() -> TimeInterval {
115
115
  var result: TimeInterval = 0
116
- owner?.executeOnAudioQueue { [weak self] in
117
- guard let self else { return }
118
- guard !channels.isEmpty, playIndex < channels.count else { return }
119
- result = channels[playIndex].currentTime
116
+ owner?.readOnAudioQueue {
117
+ guard !self.channels.isEmpty, self.playIndex < self.channels.count else { return }
118
+ result = self.channels[self.playIndex].currentTime
120
119
  }
121
120
  return result
122
121
  }
@@ -313,9 +312,8 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
313
312
 
314
313
  func isPlaying() -> Bool {
315
314
  var result = false
316
- owner?.executeOnAudioQueue { [weak self] in
317
- guard let self else { return }
318
- result = channels.contains(where: { $0.isPlaying })
315
+ owner?.readOnAudioQueue {
316
+ result = self.channels.contains(where: { $0.isPlaying })
319
317
  }
320
318
  return result
321
319
  }
@@ -12,7 +12,7 @@ enum MyError: Error {
12
12
  @objc(NativeAudio)
13
13
  // swiftlint:disable:next type_body_length
14
14
  public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
15
- private let pluginVersion: String = "8.3.4"
15
+ private let pluginVersion: String = "8.3.6"
16
16
  public let identifier = "NativeAudio"
17
17
  public let jsName = "NativeAudio"
18
18
  public let pluginMethods: [CAPPluginMethod] = [
@@ -1279,6 +1279,15 @@ public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
1279
1279
  }
1280
1280
  }
1281
1281
 
1282
+ /// Use this for read-only access to shared state — avoids the .barrier write lock
1283
+ /// that `executeOnAudioQueue` applies, preventing deadlocks with third-party SDKs.
1284
+ internal func readOnAudioQueue<T>(_ block: () -> T) -> T {
1285
+ if DispatchQueue.getSpecific(key: queueKey) != nil {
1286
+ return block()
1287
+ }
1288
+ return audioQueue.sync { block() }
1289
+ }
1290
+
1282
1291
  @objc func notifyCurrentTime(_ asset: AudioAsset) {
1283
1292
  audioQueue.sync {
1284
1293
  let rawTime = asset.getCurrentTime()
@@ -34,7 +34,6 @@ public class RemoteAudioAsset: AudioAsset {
34
34
  let playerItem = AVPlayerItem(asset: asset)
35
35
  let player = AVPlayer(playerItem: playerItem)
36
36
  player.volume = self.initialVolume
37
- player.rate = 1.0
38
37
  self.playerItems.append(playerItem)
39
38
  self.players.append(player)
40
39
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/native-audio",
3
- "version": "8.3.4",
3
+ "version": "8.3.6",
4
4
  "description": "A native plugin for native audio engine",
5
5
  "license": "MPL-2.0",
6
6
  "main": "dist/plugin.cjs.js",