@javascriptcommon/react-native-track-player 1.2.9 → 1.2.24

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.
Files changed (131) hide show
  1. package/android/build.gradle +61 -4
  2. package/android/src/main/AndroidManifest.xml +2 -4
  3. package/android/src/main/ic_home-playstore.png +0 -0
  4. package/android/src/main/ic_repeat-playstore.png +0 -0
  5. package/android/src/main/ic_repeat_50-playstore.png +0 -0
  6. package/android/src/main/ic_shuffle-playstore.png +0 -0
  7. package/android/src/main/ic_shuffle_50-playstore.png +0 -0
  8. package/android/src/main/ic_shuffle_sm-playstore.png +0 -0
  9. package/android/src/main/ic_stop-playstore.png +0 -0
  10. package/android/src/main/ic_test-playstore.png +0 -0
  11. package/android/src/main/java/com/guichaguri/trackplayer/{service/HeadlessJsMediaService.java → HeadlessJsMediaService.java} +83 -32
  12. package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.kt +25 -0
  13. package/android/src/main/java/com/guichaguri/trackplayer/extensions/AudioPlayerStateExt.kt +19 -0
  14. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/EventHolder.kt +30 -0
  15. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/NotificationEventHolder.kt +20 -0
  16. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/PlayerEventHolder.kt +111 -0
  17. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AAMediaSessionCallback.kt +10 -0
  18. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioContentType.kt +10 -0
  19. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItem.kt +66 -0
  20. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItemTransitionReason.kt +33 -0
  21. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioPlayerState.kt +30 -0
  22. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/BufferConfig.kt +8 -0
  23. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/CacheConfig.kt +17 -0
  24. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/Capability.kt +19 -0
  25. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/FocusChangeData.kt +3 -0
  26. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/MediaSessionCallback.kt +17 -0
  27. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationConfig.kt +43 -0
  28. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationMetadata.kt +8 -0
  29. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationState.kt +8 -0
  30. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayWhenReadyChangeData.kt +5 -0
  31. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackEndedReason.kt +5 -0
  32. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackError.kt +6 -0
  33. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackMetadata.kt +200 -0
  34. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerConfig.kt +33 -0
  35. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerOptions.kt +9 -0
  36. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PositionChangedReason.kt +39 -0
  37. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/QueuedPlayerOptions.kt +49 -0
  38. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/notification/NotificationManager.kt +678 -0
  39. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/AudioPlayer.kt +10 -0
  40. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/BaseAudioPlayer.kt +864 -0
  41. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/QueuedAudioPlayer.kt +269 -0
  42. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/MediaSourceExt.kt +35 -0
  43. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/PlayerCache.kt +26 -0
  44. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/utils/Utils.kt +12 -0
  45. package/android/src/main/java/com/guichaguri/trackplayer/model/MetadataAdapter.kt +224 -0
  46. package/android/src/main/java/com/guichaguri/trackplayer/model/State.kt +13 -0
  47. package/android/src/main/java/com/guichaguri/trackplayer/model/Track.kt +120 -0
  48. package/android/src/main/java/com/guichaguri/trackplayer/model/TrackAudioItem.kt +19 -0
  49. package/android/src/main/java/com/guichaguri/trackplayer/model/TrackType.kt +11 -0
  50. package/android/src/main/java/com/guichaguri/trackplayer/module/AutoConnectionDetector.kt +151 -0
  51. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicEvents.kt +66 -0
  52. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.kt +1192 -0
  53. package/android/src/main/java/com/guichaguri/trackplayer/service/BundleUtils.kt +117 -0
  54. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.kt +31 -0
  55. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.kt +347 -0
  56. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.kt +1268 -0
  57. package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.kt +228 -0
  58. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.kt +141 -0
  59. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.kt +396 -0
  60. package/android/src/main/res/drawable-hdpi/ic_home.png +0 -0
  61. package/android/src/main/res/drawable-mdpi/ic_home.png +0 -0
  62. package/android/src/main/res/drawable-xhdpi/ic_home.png +0 -0
  63. package/android/src/main/res/drawable-xxhdpi/ic_home.png +0 -0
  64. package/android/src/main/res/drawable-xxxhdpi/ic_home.png +0 -0
  65. package/android/src/main/res/mipmap-hdpi/ic_arrow_down_circle_foreground.png +0 -0
  66. package/android/src/main/res/mipmap-hdpi/ic_clock_now_foreground.png +0 -0
  67. package/android/src/main/res/mipmap-hdpi/ic_close_foreground.png +0 -0
  68. package/android/src/main/res/mipmap-hdpi/ic_heart_foreground.png +0 -0
  69. package/android/src/main/res/mipmap-hdpi/ic_heart_outlined_foreground.png +0 -0
  70. package/android/src/main/res/mipmap-hdpi/ic_repeat_off_foreground.png +0 -0
  71. package/android/src/main/res/mipmap-hdpi/ic_repeat_on_foreground.png +0 -0
  72. package/android/src/main/res/mipmap-hdpi/ic_shuffle_off_foreground.png +0 -0
  73. package/android/src/main/res/mipmap-hdpi/ic_shuffle_on_foreground.png +0 -0
  74. package/android/src/main/res/mipmap-mdpi/ic_arrow_down_circle_foreground.png +0 -0
  75. package/android/src/main/res/mipmap-mdpi/ic_clock_now_foreground.png +0 -0
  76. package/android/src/main/res/mipmap-mdpi/ic_close_foreground.png +0 -0
  77. package/android/src/main/res/mipmap-mdpi/ic_heart_foreground.png +0 -0
  78. package/android/src/main/res/mipmap-mdpi/ic_heart_outlined_foreground.png +0 -0
  79. package/android/src/main/res/mipmap-mdpi/ic_repeat_off_foreground.png +0 -0
  80. package/android/src/main/res/mipmap-mdpi/ic_repeat_on_foreground.png +0 -0
  81. package/android/src/main/res/mipmap-mdpi/ic_shuffle_off_foreground.png +0 -0
  82. package/android/src/main/res/mipmap-mdpi/ic_shuffle_on_foreground.png +0 -0
  83. package/android/src/main/res/mipmap-xhdpi/ic_arrow_down_circle_foreground.png +0 -0
  84. package/android/src/main/res/mipmap-xhdpi/ic_clock_now_foreground.png +0 -0
  85. package/android/src/main/res/mipmap-xhdpi/ic_close_foreground.png +0 -0
  86. package/android/src/main/res/mipmap-xhdpi/ic_heart_foreground.png +0 -0
  87. package/android/src/main/res/mipmap-xhdpi/ic_heart_outlined_foreground.png +0 -0
  88. package/android/src/main/res/mipmap-xhdpi/ic_repeat_off_foreground.png +0 -0
  89. package/android/src/main/res/mipmap-xhdpi/ic_repeat_on_foreground.png +0 -0
  90. package/android/src/main/res/mipmap-xhdpi/ic_shuffle_off_foreground.png +0 -0
  91. package/android/src/main/res/mipmap-xhdpi/ic_shuffle_on_foreground.png +0 -0
  92. package/android/src/main/res/mipmap-xxhdpi/ic_arrow_down_circle_foreground.png +0 -0
  93. package/android/src/main/res/mipmap-xxhdpi/ic_clock_now_foreground.png +0 -0
  94. package/android/src/main/res/mipmap-xxhdpi/ic_close_foreground.png +0 -0
  95. package/android/src/main/res/mipmap-xxhdpi/ic_heart_foreground.png +0 -0
  96. package/android/src/main/res/mipmap-xxhdpi/ic_heart_outlined_foreground.png +0 -0
  97. package/android/src/main/res/mipmap-xxhdpi/ic_repeat_off_foreground.png +0 -0
  98. package/android/src/main/res/mipmap-xxhdpi/ic_repeat_on_foreground.png +0 -0
  99. package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_off_foreground.png +0 -0
  100. package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_on_foreground.png +0 -0
  101. package/android/src/main/res/mipmap-xxxhdpi/ic_arrow_down_circle_foreground.png +0 -0
  102. package/android/src/main/res/mipmap-xxxhdpi/ic_clock_now_foreground.png +0 -0
  103. package/android/src/main/res/mipmap-xxxhdpi/ic_close_foreground.png +0 -0
  104. package/android/src/main/res/mipmap-xxxhdpi/ic_heart_foreground.png +0 -0
  105. package/android/src/main/res/mipmap-xxxhdpi/ic_heart_outlined_foreground.png +0 -0
  106. package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_off_foreground.png +0 -0
  107. package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_on_foreground.png +0 -0
  108. package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_off_foreground.png +0 -0
  109. package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_on_foreground.png +0 -0
  110. package/android/src/main/res/raw/silent_5_seconds.mp3 +0 -0
  111. package/android/src/main/res/strings.xml +6 -0
  112. package/android/src/main/res/values/strings.xml +6 -0
  113. package/index.d.ts +62 -1
  114. package/lib/index.js +10 -9
  115. package/package.json +1 -1
  116. package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.java +0 -28
  117. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicEvents.java +0 -55
  118. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.java +0 -298
  119. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.java +0 -47
  120. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.java +0 -383
  121. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.java +0 -271
  122. package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.java +0 -243
  123. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.java +0 -148
  124. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.java +0 -379
  125. package/android/src/main/java/com/guichaguri/trackplayer/service/models/Track.java +0 -141
  126. package/android/src/main/java/com/guichaguri/trackplayer/service/models/TrackType.java +0 -35
  127. package/android/src/main/res/drawable-hdpi/ic_logo.png +0 -0
  128. package/android/src/main/res/drawable-mdpi/ic_logo.png +0 -0
  129. package/android/src/main/res/drawable-xhdpi/ic_logo.png +0 -0
  130. package/android/src/main/res/drawable-xxhdpi/ic_logo.png +0 -0
  131. package/android/src/main/res/drawable-xxxhdpi/ic_logo.png +0 -0
@@ -1,383 +0,0 @@
1
- package com.guichaguri.trackplayer.service;
2
-
3
- import android.annotation.SuppressLint;
4
- import android.content.BroadcastReceiver;
5
- import android.content.Context;
6
- import android.content.Intent;
7
- import android.content.IntentFilter;
8
- import android.media.AudioAttributes;
9
- import android.media.AudioDeviceInfo;
10
- import android.media.AudioFocusRequest;
11
- import android.media.AudioManager;
12
- import android.media.AudioManager.OnAudioFocusChangeListener;
13
- import android.net.wifi.WifiManager;
14
- import android.net.wifi.WifiManager.WifiLock;
15
- import android.os.Build;
16
- import android.os.Bundle;
17
- import android.os.Handler;
18
- import android.os.PowerManager;
19
- import android.os.PowerManager.WakeLock;
20
- import androidx.annotation.RequiresApi;
21
-
22
- import android.support.v4.media.session.PlaybackStateCompat;
23
- import android.util.Log;
24
- import com.guichaguri.trackplayer.module.MusicEvents;
25
- import com.guichaguri.trackplayer.service.metadata.MetadataManager;
26
- import com.guichaguri.trackplayer.service.models.Track;
27
-
28
- /**
29
- * @author Guichaguri
30
- */
31
- public class MusicManager implements OnAudioFocusChangeListener {
32
-
33
- private final MusicService service;
34
-
35
- private final WakeLock wakeLock;
36
- private final WifiLock wifiLock;
37
-
38
- private MetadataManager metadata;
39
-
40
- private Track currentTrack;
41
-
42
- private int state;
43
- private int previousState;
44
- private long position;
45
- private long bufferedPosition;
46
-
47
- @RequiresApi(26)
48
- private AudioFocusRequest focus = null;
49
- private boolean hasAudioFocus = false;
50
- private boolean wasDucking = false;
51
-
52
- private BroadcastReceiver noisyReceiver = new BroadcastReceiver() {
53
- @Override
54
- public void onReceive(Context context, Intent intent) {
55
- service.emit(MusicEvents.BUTTON_PAUSE, null);
56
- }
57
- };
58
- private boolean receivingNoisyEvents = false;
59
-
60
- private boolean stopWithApp = false;
61
- private boolean alwaysPauseOnInterruption = false;
62
-
63
- @SuppressLint("InvalidWakeLockTag")
64
- public MusicManager(MusicService service) {
65
- this.service = service;
66
- this.metadata = new MetadataManager(service, this);
67
-
68
- PowerManager powerManager = (PowerManager)service.getSystemService(Context.POWER_SERVICE);
69
- wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "track-player-wake-lock");
70
- wakeLock.setReferenceCounted(false);
71
-
72
- // Android 7: Use the application context here to prevent any memory leaks
73
- WifiManager wifiManager = (WifiManager)service.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
74
- wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "track-player-wifi-lock");
75
- wifiLock.setReferenceCounted(false);
76
- }
77
-
78
- public Track getCurrentTrack(){return currentTrack;}
79
- public void setCurrentTrack(Track track){currentTrack = track;}
80
-
81
- public boolean shouldStopWithApp() {
82
- return stopWithApp;
83
- }
84
-
85
- public void setStopWithApp(boolean stopWithApp) {
86
- this.stopWithApp = stopWithApp;
87
- }
88
-
89
- public void setAlwaysPauseOnInterruption(boolean alwaysPauseOnInterruption) {
90
- this.alwaysPauseOnInterruption = alwaysPauseOnInterruption;
91
- }
92
-
93
- public MetadataManager getMetadata() {
94
- return metadata;
95
- }
96
-
97
- public Handler getHandler() {
98
- return service.handler;
99
- }
100
-
101
- public long getState(){
102
- return state;
103
- }
104
-
105
- public void setState(int state, long position){
106
- this.state = state;
107
- if(position != -1) {
108
- this.position = position;
109
- this.bufferedPosition = position;
110
- }
111
- onPlayerStateChanged();
112
- }
113
-
114
- @SuppressLint("WakelockTimeout")
115
- public void onPlay() {
116
- Log.d(Utils.LOG, "onPlay");
117
- /*if(playback == null) return;
118
-
119
- Track track = playback.getCurrentTrack();
120
- if(track == null) return;
121
-
122
- if(!playback.isRemote()) {
123
- requestFocus();
124
-
125
- if(!receivingNoisyEvents) {
126
- receivingNoisyEvents = true;
127
- service.registerReceiver(noisyReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
128
- }
129
-
130
- if(!wakeLock.isHeld()) wakeLock.acquire();
131
-
132
- if(!Utils.isLocal(track.uri)) {
133
- if(!wifiLock.isHeld()) wifiLock.acquire();
134
- }
135
- }*/
136
-
137
- requestFocus();
138
-
139
- if(!receivingNoisyEvents) {
140
- receivingNoisyEvents = true;
141
- service.registerReceiver(noisyReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
142
- }
143
-
144
- if(!wakeLock.isHeld()) wakeLock.acquire();
145
-
146
- /*if(!Utils.isLocal(currentTrack.uri)) {
147
- if(!wifiLock.isHeld()) wifiLock.acquire();
148
- }*/
149
-
150
- metadata.setActive(true);
151
- }
152
-
153
- public void onPause() {
154
- Log.d(Utils.LOG, "onPause");
155
-
156
- // Unregisters the noisy receiver
157
- if(receivingNoisyEvents) {
158
- try {
159
- service.unregisterReceiver(noisyReceiver);
160
- receivingNoisyEvents = false;
161
- }catch(Exception e){ }
162
- }
163
-
164
- // Release the wake and the wifi locks
165
- if(wakeLock.isHeld()) wakeLock.release();
166
- if(wifiLock.isHeld()) wifiLock.release();
167
-
168
- metadata.setActive(true);
169
- }
170
-
171
- public void onStop() {
172
- Log.d(Utils.LOG, "onStop");
173
-
174
- // Unregisters the noisy receiver
175
- if(receivingNoisyEvents) {
176
- try {
177
- service.unregisterReceiver(noisyReceiver);
178
- receivingNoisyEvents = false;
179
- }catch(Exception e){ }
180
- }
181
-
182
- // Release the wake and the wifi locks
183
- if(wakeLock.isHeld()) wakeLock.release();
184
- if(wifiLock.isHeld()) wifiLock.release();
185
-
186
- abandonFocus();
187
-
188
- metadata.setActive(false);
189
- }
190
-
191
- public void onPlayerStateChanged() {
192
-
193
- if(Utils.isPlaying(state) && !Utils.isPlaying(previousState)) {
194
- this.onPlay();
195
- } else if(Utils.isPaused(state) && !Utils.isPaused(previousState)) {
196
- this.onPause();
197
- } else if(Utils.isStopped(state) && !Utils.isStopped(previousState)) {
198
- this.onStop();
199
- }
200
-
201
- this.onStateChange(state, position, bufferedPosition);
202
- previousState = state;
203
-
204
- if(state == PlaybackStateCompat.STATE_STOPPED) {
205
- this.onEnd(getCurrentTrack(), 0);
206
- }
207
- }
208
-
209
- public void onStateChange(int state, long position, long bufferedPosition) {
210
- Log.d(Utils.LOG, "onStateChange");
211
-
212
- Bundle bundle = new Bundle();
213
- bundle.putInt("state", state);
214
- service.emit(MusicEvents.PLAYBACK_STATE, bundle);
215
- metadata.updatePlayback(state, position, bufferedPosition, 1);
216
- }
217
-
218
- public void onTrackUpdate(Track previous, long prevPos, Track next) {
219
- Log.d(Utils.LOG, "onTrackUpdate");
220
-
221
- if(next != null) metadata.updateMetadata(next);
222
-
223
- Bundle bundle = new Bundle();
224
- bundle.putString("track", previous != null ? previous.id : null);
225
- bundle.putDouble("position", Utils.toSeconds(prevPos));
226
- bundle.putString("nextTrack", next != null ? next.id : null);
227
- service.emit(MusicEvents.PLAYBACK_TRACK_CHANGED, bundle);
228
- }
229
-
230
- public void onReset() {
231
- metadata.removeNotifications();
232
- }
233
-
234
- public void onEnd(Track previous, long prevPos) {
235
- Log.d(Utils.LOG, "onEnd");
236
-
237
- Bundle bundle = new Bundle();
238
- bundle.putString("track", previous != null ? previous.id : null);
239
- bundle.putDouble("position", Utils.toSeconds(prevPos));
240
- service.emit(MusicEvents.PLAYBACK_QUEUE_ENDED, bundle);
241
- }
242
-
243
- public void onMetadataReceived(String source, String title, String url, String artist, String album, String date, String genre) {
244
- Log.d(Utils.LOG, "onMetadataReceived: " + source);
245
-
246
- Bundle bundle = new Bundle();
247
- bundle.putString("source", source);
248
- bundle.putString("title", title);
249
- bundle.putString("url", url);
250
- bundle.putString("artist", artist);
251
- bundle.putString("album", album);
252
- bundle.putString("date", date);
253
- bundle.putString("genre", genre);
254
- service.emit(MusicEvents.PLAYBACK_METADATA, bundle);
255
- }
256
-
257
- public void onError(String code, String error) {
258
- Log.d(Utils.LOG, "onError");
259
- Log.e(Utils.LOG, "Playback error: " + code + " - " + error);
260
-
261
- Bundle bundle = new Bundle();
262
- bundle.putString("code", code);
263
- bundle.putString("message", error);
264
- service.emit(MusicEvents.PLAYBACK_ERROR, bundle);
265
- }
266
-
267
- @Override
268
- public void onAudioFocusChange(int focus) {
269
- Log.d(Utils.LOG, "onDuck");
270
-
271
- boolean permanent = false;
272
- boolean paused = false;
273
- boolean ducking = false;
274
-
275
- switch(focus) {
276
- case AudioManager.AUDIOFOCUS_GAIN:
277
- paused = false;
278
- break;
279
- case AudioManager.AUDIOFOCUS_LOSS:
280
- permanent = true;
281
- paused = true;
282
- abandonFocus();
283
- break;
284
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
285
- paused = true;
286
- break;
287
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
288
- if (alwaysPauseOnInterruption)
289
- paused = true;
290
- else
291
- ducking = true;
292
- break;
293
- default:
294
- break;
295
- }
296
-
297
- if (ducking) {
298
- //playback.setVolumeMultiplier(0.5F);
299
- wasDucking = true;
300
- } else if (wasDucking) {
301
- //playback.setVolumeMultiplier(1.0F);
302
- wasDucking = false;
303
- }
304
-
305
- Bundle bundle = new Bundle();
306
- bundle.putBoolean("permanent", permanent);
307
- bundle.putBoolean("paused", paused);
308
- bundle.putBoolean("ducking", ducking);
309
- service.emit(MusicEvents.BUTTON_DUCK, bundle);
310
- }
311
-
312
- private void requestFocus() {
313
- if(hasAudioFocus) return;
314
- Log.d(Utils.LOG, "Requesting audio focus...");
315
-
316
- AudioManager manager = (AudioManager)service.getSystemService(Context.AUDIO_SERVICE);
317
- int r;
318
-
319
- if(manager == null) {
320
- r = AudioManager.AUDIOFOCUS_REQUEST_FAILED;
321
- } else if(Build.VERSION.SDK_INT >= 26) {
322
- focus = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
323
- .setOnAudioFocusChangeListener(this)
324
- .setAudioAttributes(new AudioAttributes.Builder()
325
- .setUsage(AudioAttributes.USAGE_MEDIA)
326
- .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
327
- .build())
328
- .setWillPauseWhenDucked(alwaysPauseOnInterruption)
329
- .build();
330
-
331
- r = manager.requestAudioFocus(focus);
332
- } else {
333
- //noinspection deprecation
334
- r = manager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
335
- }
336
-
337
- hasAudioFocus = r == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
338
- }
339
-
340
- private void abandonFocus() {
341
- if(!hasAudioFocus) return;
342
- Log.d(Utils.LOG, "Abandoning audio focus...");
343
-
344
- AudioManager manager = (AudioManager)service.getSystemService(Context.AUDIO_SERVICE);
345
- int r;
346
-
347
- if(manager == null) {
348
- r = AudioManager.AUDIOFOCUS_REQUEST_FAILED;
349
- } else if(Build.VERSION.SDK_INT >= 26) {
350
- r = manager.abandonAudioFocusRequest(focus);
351
- } else {
352
- //noinspection deprecation
353
- r = manager.abandonAudioFocus(this);
354
- }
355
-
356
- hasAudioFocus = r != AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
357
- }
358
-
359
- public void destroy(boolean intentToStop) {
360
- Log.d(Utils.LOG, "Releasing service resources...");
361
-
362
- // Disable audio focus
363
- abandonFocus();
364
-
365
- // Stop receiving audio becoming noisy events
366
- if(receivingNoisyEvents) {
367
- try {
368
- service.unregisterReceiver(noisyReceiver);
369
- receivingNoisyEvents = false;
370
- }catch(Exception e){ }
371
- }
372
-
373
- // Release the playback resources
374
- //if(playback != null) playback.destroy();
375
-
376
- // Release the metadata resources
377
- metadata.destroy(intentToStop);
378
-
379
- // Release the locks
380
- if(wifiLock.isHeld()) wifiLock.release();
381
- if(wakeLock.isHeld()) wakeLock.release();
382
- }
383
- }
@@ -1,271 +0,0 @@
1
- package com.guichaguri.trackplayer.service;
2
-
3
- import android.app.Notification;
4
- import android.app.NotificationChannel;
5
- import android.app.NotificationManager;
6
- import android.content.Context;
7
- import android.content.Intent;
8
- import android.content.SharedPreferences;
9
- import android.content.pm.ServiceInfo;
10
- import android.graphics.Bitmap;
11
- import android.graphics.BitmapFactory;
12
- import android.os.Build;
13
- import android.os.Bundle;
14
- import android.os.Handler;
15
- import android.os.IBinder;
16
- import android.preference.PreferenceManager;
17
- import android.support.v4.media.MediaBrowserCompat;
18
- import android.support.v4.media.RatingCompat;
19
- import android.util.Log;
20
- import android.view.KeyEvent;
21
-
22
- import androidx.annotation.NonNull;
23
- import androidx.core.app.NotificationCompat;
24
- import androidx.localbroadcastmanager.content.LocalBroadcastManager;
25
- import androidx.media.session.MediaButtonReceiver;
26
-
27
- import com.facebook.react.HeadlessJsTaskService;
28
- import com.facebook.react.ReactInstanceManager;
29
- import com.facebook.react.bridge.Arguments;
30
- import com.facebook.react.bridge.ReactContext;
31
- import com.facebook.react.jstasks.HeadlessJsTaskConfig;
32
- import com.guichaguri.trackplayer.R;
33
- import com.guichaguri.trackplayer.service.metadata.ButtonEvents;
34
- import com.guichaguri.trackplayer.service.models.Track;
35
-
36
- import javax.annotation.Nullable;
37
-
38
- import static android.view.KeyEvent.KEYCODE_MEDIA_FAST_FORWARD;
39
- import static android.view.KeyEvent.KEYCODE_MEDIA_NEXT;
40
- import static android.view.KeyEvent.KEYCODE_MEDIA_PLAY;
41
- import static android.view.KeyEvent.KEYCODE_MEDIA_PREVIOUS;
42
- import static android.view.KeyEvent.KEYCODE_MEDIA_REWIND;
43
- import static android.view.KeyEvent.KEYCODE_MEDIA_STOP;
44
- import static androidx.core.app.NotificationCompat.PRIORITY_MIN;
45
- import static com.guichaguri.trackplayer.service.Utils.bundleToJson;
46
- import static com.guichaguri.trackplayer.service.Utils.jsonStringToBundle;
47
-
48
- import java.util.List;
49
-
50
- /**
51
- * @author Guichaguri
52
- */
53
- public class MusicService extends HeadlessJsMediaService {
54
-
55
- MusicManager manager;
56
- Handler handler;
57
- private Boolean intentToStop = false;
58
-
59
- @Nullable
60
- @Override
61
- protected HeadlessJsTaskConfig getTaskConfig(Intent intent) {
62
- return new HeadlessJsTaskConfig("TrackPlayer", Arguments.createMap(), 0, true);
63
- }
64
-
65
- @Override
66
- public void onHeadlessJsTaskFinish(int taskId) {
67
- // Overridden to prevent the service from being terminated
68
- }
69
-
70
- public void emit(String event, Bundle data) {
71
- Intent intent = new Intent(Utils.EVENT_INTENT);
72
-
73
- intent.putExtra("event", event);
74
- if(data != null) intent.putExtra("data", data);
75
-
76
- LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
77
- }
78
-
79
- public void destroy(boolean intentToStop) {
80
- if(handler != null) {
81
- handler.removeMessages(0);
82
- handler = null;
83
- }
84
-
85
- if(manager != null) {
86
- manager.destroy(intentToStop);
87
- manager = null;
88
- }
89
- }
90
-
91
- private void onStartForeground() {
92
- boolean serviceForeground = false;
93
-
94
- if(manager != null) {
95
- // The session is only active when the service is on foreground
96
- serviceForeground = manager.getMetadata().getSession().isActive();
97
- }
98
-
99
- if(!serviceForeground) {
100
- ReactInstanceManager reactInstanceManager = getReactNativeHost().getReactInstanceManager();
101
- ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
102
-
103
- // Checks whether there is a React activity
104
- if(reactContext == null || !reactContext.hasCurrentActivity()) {
105
- String channel = Utils.getNotificationChannel((Context) this);
106
-
107
- // Sets the service to foreground with an empty notification
108
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
109
- startForeground(1, new NotificationCompat.Builder(this, channel).build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
110
- }else{
111
- startForeground(1, new NotificationCompat.Builder(this, channel).build());
112
- }
113
- // Stops the service right after
114
- stopSelf();
115
- }
116
- }
117
- }
118
-
119
- @Nullable
120
- @Override
121
- public IBinder onBind(Intent intent) {
122
- if(Utils.CONNECT_INTENT.equals(intent.getAction())) {
123
- return new MusicBinder(this, manager);
124
- }
125
-
126
- return super.onBind(intent);
127
- }
128
-
129
- @androidx.annotation.Nullable
130
- @Override
131
- public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, @androidx.annotation.Nullable Bundle rootHints) {
132
- return null;
133
- }
134
-
135
- @Override
136
- public void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
137
-
138
- }
139
-
140
- @Override
141
- public void onCreate() {
142
-
143
- super.onCreate();
144
-
145
- //onStartForeground();
146
-
147
- if (manager == null)
148
- manager = new MusicManager(this);
149
-
150
- if(handler == null)
151
- handler = new Handler();
152
-
153
- String channel = Utils.getNotificationChannel((Context) this);
154
-
155
- // Sets the service to foreground with an empty notification
156
- try {
157
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
158
- startForeground(1, new NotificationCompat.Builder(this, channel).build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
159
- } else {
160
- startForeground(1, new NotificationCompat.Builder(this, channel).build());
161
- }
162
- }catch(Exception ex){}
163
- }
164
-
165
- @Override
166
- public int onStartCommand(Intent intent, int flags, int startId) {
167
- if(intent != null && Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
168
- onStartForeground();
169
-
170
- if (Build.VERSION.SDK_INT >= 33) {
171
- try {
172
- startAndStopEmptyNotificationToAvoidANR();
173
- } catch(Exception ex){}
174
- }
175
-
176
- KeyEvent intentExtra = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
177
- if (intentExtra.getKeyCode() == KEYCODE_MEDIA_STOP) {
178
- intentToStop = true;
179
- startServiceOreoAndAbove();
180
- stopSelf();
181
- } else {
182
- intentToStop = false;
183
- }
184
-
185
- if (manager != null && manager.getMetadata().getSession() != null) {
186
- MediaButtonReceiver.handleIntent(manager.getMetadata().getSession(), intent);
187
- return START_NOT_STICKY;
188
- }
189
- }
190
-
191
- if (manager == null)
192
- manager = new MusicManager(this);
193
-
194
- if(handler == null)
195
- handler = new Handler();
196
-
197
- super.onStartCommand(intent, flags, startId);
198
- return START_NOT_STICKY;
199
- }
200
-
201
- public void startServiceOreoAndAbove(){
202
- // Needed to prevent crash when dismissing notification
203
- // https://stackoverflow.com/questions/47609261/bound-service-crash-with-context-startforegroundservice-did-not-then-call-ser?rq=1
204
- if (Build.VERSION.SDK_INT >= 26) {
205
- String CHANNEL_ID = Utils.NOTIFICATION_CHANNEL;
206
- String CHANNEL_NAME = "Playback";
207
-
208
- NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
209
- ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
210
-
211
- Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
212
- .setCategory(Notification.CATEGORY_SERVICE).setSmallIcon(R.drawable.ic_logo).setPriority(PRIORITY_MIN).build();
213
-
214
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
215
- startForeground(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
216
- }else{
217
- startForeground(1, notification);
218
- }
219
- }
220
- }
221
-
222
- /**
223
- * Workaround for the "Context.startForegroundService() did not then call Service.startForeground()"
224
- * within 5s" ANR and crash by creating an empty notification and stopping it right after. For more
225
- * information see https://github.com/doublesymmetry/react-native-track-player/issues/1666
226
- */
227
- private void startAndStopEmptyNotificationToAvoidANR() {
228
- NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
229
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
230
- notificationManager.createNotificationChannel(
231
- new NotificationChannel("Playback", "Playback", NotificationManager.IMPORTANCE_LOW)
232
- );
233
- }
234
-
235
- NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "Playback")
236
- .setPriority(NotificationCompat.PRIORITY_LOW)
237
- .setCategory(NotificationCompat.CATEGORY_SERVICE)
238
- .setSmallIcon(R.drawable.ic_logo);
239
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
240
- notificationBuilder.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE);
241
- }
242
- android.app.Notification notification = notificationBuilder.build();
243
- startForeground(1, notification);
244
- stopForeground(true);
245
- }
246
-
247
- @Override
248
- public void onDestroy() {
249
- super.onDestroy();
250
- if(manager != null) {
251
- manager.destroy(true);
252
- manager = null;
253
- }
254
- }
255
-
256
- @Override
257
- public void onTaskRemoved(Intent rootIntent) {
258
- super.onTaskRemoved(rootIntent);
259
-
260
- if (manager == null || manager.shouldStopWithApp()) {
261
- destroy(true);
262
- stopSelf();
263
- }
264
-
265
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
266
- stopForeground(STOP_FOREGROUND_REMOVE);
267
- } else {
268
- stopForeground(true);
269
- }
270
- }
271
- }