expo-audio 58.0.9 → 58.0.11
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/CHANGELOG.md +12 -0
- package/android/build.gradle +2 -3
- package/android/src/main/java/expo/modules/audio/AudioRecords.kt +3 -1
- package/android/src/main/java/expo/modules/audio/service/AudioControlsService.kt +43 -12
- package/android/src/main/java/expo/modules/audio/service/SeekInterval.kt +9 -0
- package/build/AudioConstants.d.ts +24 -0
- package/build/AudioConstants.js.map +1 -1
- package/build/MediaSessionController.web.js +4 -4
- package/build/MediaSessionController.web.js.map +1 -1
- package/build/utils/lockScreenOptions.d.ts +2 -0
- package/build/utils/lockScreenOptions.js +17 -0
- package/build/utils/lockScreenOptions.js.map +1 -0
- package/ios/AudioRecords.swift +2 -0
- package/ios/MediaController.swift +21 -5
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/{58.0.9/expo.modules.audio-58.0.9-sources.jar → 58.0.11/expo.modules.audio-58.0.11-sources.jar} +0 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11-sources.jar.md5 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11-sources.jar.sha1 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11-sources.jar.sha256 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11-sources.jar.sha512 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.aar +0 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.aar.sha512 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/{58.0.9/expo.modules.audio-58.0.9.module → 58.0.11/expo.modules.audio-58.0.11.module} +22 -29
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.module.md5 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/{58.0.9/expo.modules.audio-58.0.9.pom → 58.0.11/expo.modules.audio-58.0.11.pom} +1 -7
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.11/expo.modules.audio-58.0.11.pom.sha512 +1 -0
- package/package.json +4 -4
- package/src/AudioConstants.ts +24 -0
- package/src/MediaSessionController.web.ts +4 -5
- package/src/utils/lockScreenOptions.ts +21 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9-sources.jar.md5 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9-sources.jar.sha1 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9-sources.jar.sha256 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9-sources.jar.sha512 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.aar +0 -0
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.module.md5 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 58.0.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Remove the unused `androidx.media3:media3-ui` dependency on Android. ([#52321](https://github.com/expo/expo/pull/52321) by [@lukmccall](https://github.com/lukmccall))
|
|
8
|
+
|
|
9
|
+
## 58.0.10
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Add `seekForwardIntervalSeconds` and `seekBackwardIntervalSeconds` to `AudioLockScreenOptions` to customize the lock screen skip intervals. Both default to 10 seconds and are clamped to at least 0.1 seconds. ([#44804](https://github.com/expo/expo/pull/44804) by [@radko93](https://github.com/radko93))
|
|
14
|
+
|
|
3
15
|
## 58.0.9
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/android/build.gradle
CHANGED
|
@@ -4,13 +4,13 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'expo.modules.audio'
|
|
7
|
-
version = '58.0.
|
|
7
|
+
version = '58.0.11'
|
|
8
8
|
|
|
9
9
|
android {
|
|
10
10
|
namespace "expo.modules.audio"
|
|
11
11
|
defaultConfig {
|
|
12
12
|
versionCode 1
|
|
13
|
-
versionName "58.0.
|
|
13
|
+
versionName "58.0.11"
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
compileOptions {
|
|
@@ -28,7 +28,6 @@ dependencies {
|
|
|
28
28
|
|
|
29
29
|
def androidxMedia3Version = "1.9.1"
|
|
30
30
|
implementation "androidx.media3:media3-session:$androidxMedia3Version"
|
|
31
|
-
implementation "androidx.media3:media3-ui:$androidxMedia3Version"
|
|
32
31
|
implementation "androidx.media3:media3-exoplayer:$androidxMedia3Version"
|
|
33
32
|
implementation "androidx.media3:media3-exoplayer-dash:$androidxMedia3Version"
|
|
34
33
|
implementation "androidx.media3:media3-datasource:$androidxMedia3Version"
|
|
@@ -114,7 +114,9 @@ class AudioLockScreenOptions(
|
|
|
114
114
|
@Field val showSeekBackward: Boolean,
|
|
115
115
|
@Field val showNextTrack: Boolean = false,
|
|
116
116
|
@Field val showPreviousTrack: Boolean = false,
|
|
117
|
-
@Field val isLiveStream: Boolean? = null
|
|
117
|
+
@Field val isLiveStream: Boolean? = null,
|
|
118
|
+
@Field val seekForwardIntervalSeconds: Double = 10.0,
|
|
119
|
+
@Field val seekBackwardIntervalSeconds: Double = 10.0
|
|
118
120
|
) : Record
|
|
119
121
|
|
|
120
122
|
enum class InterruptionMode(val value: String) : Enumerable {
|
|
@@ -269,6 +269,22 @@ class AudioControlsService : MediaSessionService() {
|
|
|
269
269
|
return builder.build()
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
+
private fun skipBackIcon(seconds: Double): Int = when (seconds) {
|
|
273
|
+
5.0 -> CommandButton.ICON_SKIP_BACK_5
|
|
274
|
+
10.0 -> CommandButton.ICON_SKIP_BACK_10
|
|
275
|
+
15.0 -> CommandButton.ICON_SKIP_BACK_15
|
|
276
|
+
30.0 -> CommandButton.ICON_SKIP_BACK_30
|
|
277
|
+
else -> CommandButton.ICON_SKIP_BACK
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private fun skipForwardIcon(seconds: Double): Int = when (seconds) {
|
|
281
|
+
5.0 -> CommandButton.ICON_SKIP_FORWARD_5
|
|
282
|
+
10.0 -> CommandButton.ICON_SKIP_FORWARD_10
|
|
283
|
+
15.0 -> CommandButton.ICON_SKIP_FORWARD_15
|
|
284
|
+
30.0 -> CommandButton.ICON_SKIP_FORWARD_30
|
|
285
|
+
else -> CommandButton.ICON_SKIP_FORWARD
|
|
286
|
+
}
|
|
287
|
+
|
|
272
288
|
private fun updateSessionCustomLayout(isPlaying: Boolean) {
|
|
273
289
|
val session = mediaSession ?: return
|
|
274
290
|
val mediaButtons = mutableListOf<CommandButton>()
|
|
@@ -285,8 +301,9 @@ class AudioControlsService : MediaSessionService() {
|
|
|
285
301
|
.build()
|
|
286
302
|
)
|
|
287
303
|
} else if (currentOptions?.showSeekBackward == true) {
|
|
304
|
+
val backwardSeconds = seekIntervalMs(currentOptions?.seekBackwardIntervalSeconds) / 1000.0
|
|
288
305
|
mediaButtons.add(
|
|
289
|
-
CommandButton.Builder(
|
|
306
|
+
CommandButton.Builder(skipBackIcon(backwardSeconds))
|
|
290
307
|
.setDisplayName("Seek Backward")
|
|
291
308
|
.setEnabled(true)
|
|
292
309
|
.setSessionCommand(SessionCommand(ACTION_SEEK_BACKWARD, Bundle.EMPTY))
|
|
@@ -326,8 +343,9 @@ class AudioControlsService : MediaSessionService() {
|
|
|
326
343
|
.build()
|
|
327
344
|
)
|
|
328
345
|
} else if (currentOptions?.showSeekForward == true) {
|
|
346
|
+
val forwardSeconds = seekIntervalMs(currentOptions?.seekForwardIntervalSeconds) / 1000.0
|
|
329
347
|
mediaButtons.add(
|
|
330
|
-
CommandButton.Builder(
|
|
348
|
+
CommandButton.Builder(skipForwardIcon(forwardSeconds))
|
|
331
349
|
.setDisplayName("Seek Forward")
|
|
332
350
|
.setEnabled(true)
|
|
333
351
|
.setSessionCommand(SessionCommand(ACTION_SEEK_FORWARD, Bundle.EMPTY))
|
|
@@ -385,15 +403,28 @@ class AudioControlsService : MediaSessionService() {
|
|
|
385
403
|
private fun resolveSessionPlayer(playable: LockScreenPlayable, options: AudioLockScreenOptions?): Player {
|
|
386
404
|
val player = PlayRequestingPlayer(playable.player) { playable.requestPlay() }
|
|
387
405
|
val isLive = options?.isLiveStream ?: playable.isLive
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
406
|
+
val forwardMs = seekIntervalMs(options?.seekForwardIntervalSeconds)
|
|
407
|
+
val backwardMs = seekIntervalMs(options?.seekBackwardIntervalSeconds)
|
|
391
408
|
|
|
392
409
|
return object : ForwardingPlayer(player) {
|
|
410
|
+
override fun getSeekForwardIncrement(): Long = forwardMs
|
|
411
|
+
|
|
412
|
+
override fun getSeekBackIncrement(): Long = backwardMs
|
|
413
|
+
|
|
414
|
+
override fun seekForward() {
|
|
415
|
+
seekTo(currentPosition + forwardMs)
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
override fun seekBack() {
|
|
419
|
+
seekTo((currentPosition - backwardMs).coerceAtLeast(0))
|
|
420
|
+
}
|
|
421
|
+
|
|
393
422
|
override fun getAvailableCommands(): Player.Commands {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
.
|
|
423
|
+
val commands = super.getAvailableCommands().buildUpon()
|
|
424
|
+
if (isLive) {
|
|
425
|
+
commands.remove(Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)
|
|
426
|
+
}
|
|
427
|
+
return commands.build()
|
|
397
428
|
}
|
|
398
429
|
}
|
|
399
430
|
}
|
|
@@ -532,13 +563,15 @@ class AudioControlsService : MediaSessionService() {
|
|
|
532
563
|
|
|
533
564
|
fun seekForward() {
|
|
534
565
|
currentPlayable?.player?.let { player ->
|
|
535
|
-
|
|
566
|
+
val intervalMs = seekIntervalMs(currentOptions?.seekForwardIntervalSeconds)
|
|
567
|
+
player.seekTo(player.currentPosition + intervalMs)
|
|
536
568
|
}
|
|
537
569
|
}
|
|
538
570
|
|
|
539
571
|
fun seekBackward() {
|
|
540
572
|
currentPlayable?.player?.let { player ->
|
|
541
|
-
|
|
573
|
+
val intervalMs = seekIntervalMs(currentOptions?.seekBackwardIntervalSeconds)
|
|
574
|
+
player.seekTo((player.currentPosition - intervalMs).coerceAtLeast(0))
|
|
542
575
|
}
|
|
543
576
|
}
|
|
544
577
|
|
|
@@ -660,7 +693,5 @@ class AudioControlsService : MediaSessionService() {
|
|
|
660
693
|
const val ACTION_SEEK_BACKWARD = "expo.modules.audio.action.SEEK_BACKWARD"
|
|
661
694
|
const val ACTION_NEXT_TRACK = "expo.modules.audio.action.NEXT_TRACK"
|
|
662
695
|
const val ACTION_PREVIOUS_TRACK = "expo.modules.audio.action.PREVIOUS_TRACK"
|
|
663
|
-
|
|
664
|
-
const val SEEK_INTERVAL_MS = 10000L
|
|
665
696
|
}
|
|
666
697
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
package expo.modules.audio.service
|
|
2
|
+
|
|
3
|
+
private const val DEFAULT_SEEK_INTERVAL_SECONDS = 10.0
|
|
4
|
+
private const val MIN_SEEK_INTERVAL_MS = 100L
|
|
5
|
+
|
|
6
|
+
internal fun seekIntervalMs(seconds: Double?): Long {
|
|
7
|
+
val resolved = seconds?.takeIf { it.isFinite() } ?: DEFAULT_SEEK_INTERVAL_SECONDS
|
|
8
|
+
return (resolved * 1000).toLong().coerceAtLeast(MIN_SEEK_INTERVAL_MS)
|
|
9
|
+
}
|
|
@@ -23,4 +23,28 @@ export type AudioLockScreenOptions = {
|
|
|
23
23
|
* and scrub bar, and disable seek controls.
|
|
24
24
|
*/
|
|
25
25
|
isLiveStream?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* How far, in seconds, the lock screen seek forward button jumps ahead.
|
|
28
|
+
* Values below `0.1` are clamped up to `0.1` so that the button always moves playback.
|
|
29
|
+
*
|
|
30
|
+
* On Android, the whole-second values `5`, `10`, `15`, and `30` render a matching numbered skip
|
|
31
|
+
* icon, and every other value renders a generic skip icon. On iOS, the number is drawn into the
|
|
32
|
+
* glyph for any value, because it is passed through as the skip command's preferred interval.
|
|
33
|
+
* On web, the browser decides which control it shows and which offset it sends, so this value is
|
|
34
|
+
* only used as a fallback when the browser omits an offset of its own.
|
|
35
|
+
* @default 10
|
|
36
|
+
*/
|
|
37
|
+
seekForwardIntervalSeconds?: number;
|
|
38
|
+
/**
|
|
39
|
+
* How far, in seconds, the lock screen seek backward button jumps back.
|
|
40
|
+
* Values below `0.1` are clamped up to `0.1` so that the button always moves playback.
|
|
41
|
+
*
|
|
42
|
+
* On Android, the whole-second values `5`, `10`, `15`, and `30` render a matching numbered skip
|
|
43
|
+
* icon, and every other value renders a generic skip icon. On iOS, the number is drawn into the
|
|
44
|
+
* glyph for any value, because it is passed through as the skip command's preferred interval.
|
|
45
|
+
* On web, the browser decides which control it shows and which offset it sends, so this value is
|
|
46
|
+
* only used as a fallback when the browser omits an offset of its own.
|
|
47
|
+
* @default 10
|
|
48
|
+
*/
|
|
49
|
+
seekBackwardIntervalSeconds?: number;
|
|
26
50
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["AudioConstants.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA,cAAc;AACd;;CAEC,GACD,
|
|
1
|
+
{"version":3,"sources":["AudioConstants.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA,cAAc;AACd;;CAEC,GACD,WA8CE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { normalizeLockScreenOptions } from './utils/lockScreenOptions';
|
|
2
2
|
class MediaSessionController {
|
|
3
3
|
activePlayer = null;
|
|
4
4
|
metadata = null;
|
|
@@ -10,7 +10,7 @@ class MediaSessionController {
|
|
|
10
10
|
}
|
|
11
11
|
this.activePlayer = player;
|
|
12
12
|
this.metadata = metadata ?? null;
|
|
13
|
-
this.options = options
|
|
13
|
+
this.options = normalizeLockScreenOptions(options);
|
|
14
14
|
this._applyMetadata();
|
|
15
15
|
this._applyActionHandlers();
|
|
16
16
|
this.updatePlaybackState(player);
|
|
@@ -115,13 +115,13 @@ class MediaSessionController {
|
|
|
115
115
|
}
|
|
116
116
|
});
|
|
117
117
|
const seekForward = (details)=>{
|
|
118
|
-
const skipTime = details.seekOffset ??
|
|
118
|
+
const skipTime = details.seekOffset ?? this.options?.seekForwardIntervalSeconds ?? 10;
|
|
119
119
|
const newTime = Math.min(player.currentTime + skipTime, player.duration || 0);
|
|
120
120
|
player.seekTo(newTime);
|
|
121
121
|
this.updatePositionState(player);
|
|
122
122
|
};
|
|
123
123
|
const seekBackward = (details)=>{
|
|
124
|
-
const skipTime = details.seekOffset ??
|
|
124
|
+
const skipTime = details.seekOffset ?? this.options?.seekBackwardIntervalSeconds ?? 10;
|
|
125
125
|
const newTime = Math.max(player.currentTime - skipTime, 0);
|
|
126
126
|
player.seekTo(newTime);
|
|
127
127
|
this.updatePositionState(player);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["MediaSessionController.web.ts"],"sourcesContent":[null],"names":["
|
|
1
|
+
{"version":3,"sources":["MediaSessionController.web.ts"],"sourcesContent":[null],"names":["normalizeLockScreenOptions","MediaSessionController","activePlayer","metadata","options","setActivePlayer","player","navigator","mediaSession","clear","_applyMetadata","_applyActionHandlers","updatePlaybackState","updatePositionState","updateMetadata","playbackState","actions","action","_setHandler","setPositionState","playing","duration","Number","isFinite","position","Math","min","max","currentTime","playbackRate","isActive","getActiveState","title","artist","albumTitle","artworkUrl","artwork","src","MediaMetadata","album","handler","setActionHandler","play","pause","details","seekTime","seekTo","seekForward","skipTime","seekOffset","seekForwardIntervalSeconds","newTime","seekBackward","seekBackwardIntervalSeconds","showSeekForward","showSeekBackward","showNextTrack","next","showPreviousTrack","previous","mediaSessionController"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const DEFAULT_SEEK_INTERVAL_SECONDS = 10;
|
|
2
|
+
const MIN_SEEK_INTERVAL_SECONDS = 0.1;
|
|
3
|
+
function normalizeInterval(seconds) {
|
|
4
|
+
if (seconds === undefined || !Number.isFinite(seconds)) {
|
|
5
|
+
return DEFAULT_SEEK_INTERVAL_SECONDS;
|
|
6
|
+
}
|
|
7
|
+
return Math.max(seconds, MIN_SEEK_INTERVAL_SECONDS);
|
|
8
|
+
}
|
|
9
|
+
export function normalizeLockScreenOptions(options) {
|
|
10
|
+
return {
|
|
11
|
+
...options,
|
|
12
|
+
seekForwardIntervalSeconds: normalizeInterval(options?.seekForwardIntervalSeconds),
|
|
13
|
+
seekBackwardIntervalSeconds: normalizeInterval(options?.seekBackwardIntervalSeconds)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=lockScreenOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["utils/lockScreenOptions.ts"],"sourcesContent":[null],"names":["DEFAULT_SEEK_INTERVAL_SECONDS","MIN_SEEK_INTERVAL_SECONDS","normalizeInterval","seconds","undefined","Number","isFinite","Math","max","normalizeLockScreenOptions","options","seekForwardIntervalSeconds","seekBackwardIntervalSeconds"],"mappings":"AAEA,MAAMA,gCAAgC;AACtC,MAAMC,4BAA4B;AAElC,SAASC,kBAAkBC,OAA2B;IACpD,IAAIA,YAAYC,aAAa,CAACC,OAAOC,QAAQ,CAACH,UAAU;QACtD,OAAOH;IACT;IACA,OAAOO,KAAKC,GAAG,CAACL,SAASF;AAC3B;AAEA,OAAO,SAASQ,2BACdC,OAA2C;IAE3C,OAAO;QACL,GAAGA,OAAO;QACVC,4BAA4BT,kBAAkBQ,SAASC;QACvDC,6BAA6BV,kBAAkBQ,SAASE;IAC1D;AACF"}
|
package/ios/AudioRecords.swift
CHANGED
|
@@ -82,6 +82,8 @@ struct LockScreenOptions: Record {
|
|
|
82
82
|
@Field var showNextTrack: Bool = false
|
|
83
83
|
@Field var showPreviousTrack: Bool = false
|
|
84
84
|
@Field var isLiveStream: Bool? = false
|
|
85
|
+
@Field var seekForwardIntervalSeconds: Double = 10.0
|
|
86
|
+
@Field var seekBackwardIntervalSeconds: Double = 10.0
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
enum BitRateStrategy: String, Enumerable {
|
|
@@ -279,6 +279,20 @@ class MediaController {
|
|
|
279
279
|
.resume()
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
static func cmTime(seconds: Double) -> CMTime {
|
|
283
|
+
return CMTime(seconds: seconds, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
static func normalizedSkipInterval(_ seconds: Double?) -> Double {
|
|
287
|
+
guard let seconds, seconds.isFinite else {
|
|
288
|
+
return defaultSkipIntervalSeconds
|
|
289
|
+
}
|
|
290
|
+
return max(seconds, minSkipIntervalSeconds)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private static let defaultSkipIntervalSeconds = 10.0
|
|
294
|
+
private static let minSkipIntervalSeconds = 0.1
|
|
295
|
+
|
|
282
296
|
private func enableRemoteCommands(options: LockScreenOptions?) {
|
|
283
297
|
removeRemoteCommandTargets()
|
|
284
298
|
|
|
@@ -322,14 +336,15 @@ class MediaController {
|
|
|
322
336
|
return .commandFailed
|
|
323
337
|
}
|
|
324
338
|
|
|
325
|
-
let seekTime =
|
|
339
|
+
let seekTime = MediaController.cmTime(seconds: event.positionTime)
|
|
326
340
|
playable.lockScreenPlayer.seek(to: seekTime)
|
|
327
341
|
|
|
328
342
|
return .success
|
|
329
343
|
}
|
|
330
344
|
remoteCommandTargets.append((remoteCommandCenter.changePlaybackPositionCommand, changePlaybackPositionTarget))
|
|
331
345
|
|
|
332
|
-
|
|
346
|
+
let forwardInterval = MediaController.normalizedSkipInterval(options?.seekForwardIntervalSeconds)
|
|
347
|
+
remoteCommandCenter.skipForwardCommand.preferredIntervals = [NSNumber(value: forwardInterval)]
|
|
333
348
|
let skipForwardTarget = remoteCommandCenter.skipForwardCommand.addTarget { [weak self] event in
|
|
334
349
|
guard let playable = self?.activePlayable,
|
|
335
350
|
let event = event as? MPSkipIntervalCommandEvent else {
|
|
@@ -337,14 +352,15 @@ class MediaController {
|
|
|
337
352
|
}
|
|
338
353
|
|
|
339
354
|
let currentTime = playable.lockScreenPlayer.currentTime()
|
|
340
|
-
let seekTime = currentTime +
|
|
355
|
+
let seekTime = currentTime + MediaController.cmTime(seconds: event.interval)
|
|
341
356
|
playable.lockScreenPlayer.seek(to: seekTime, toleranceBefore: .zero, toleranceAfter: .zero)
|
|
342
357
|
|
|
343
358
|
return .success
|
|
344
359
|
}
|
|
345
360
|
remoteCommandTargets.append((remoteCommandCenter.skipForwardCommand, skipForwardTarget))
|
|
346
361
|
|
|
347
|
-
|
|
362
|
+
let backwardInterval = MediaController.normalizedSkipInterval(options?.seekBackwardIntervalSeconds)
|
|
363
|
+
remoteCommandCenter.skipBackwardCommand.preferredIntervals = [NSNumber(value: backwardInterval)]
|
|
348
364
|
let skipBackwardTarget = remoteCommandCenter.skipBackwardCommand.addTarget { [weak self] event in
|
|
349
365
|
guard let playable = self?.activePlayable,
|
|
350
366
|
let event = event as? MPSkipIntervalCommandEvent else {
|
|
@@ -352,7 +368,7 @@ class MediaController {
|
|
|
352
368
|
}
|
|
353
369
|
|
|
354
370
|
let currentTime = playable.lockScreenPlayer.currentTime()
|
|
355
|
-
let seekTime = currentTime -
|
|
371
|
+
let seekTime = currentTime - MediaController.cmTime(seconds: event.interval)
|
|
356
372
|
playable.lockScreenPlayer.seek(to: seekTime, toleranceBefore: .zero, toleranceAfter: .zero)
|
|
357
373
|
|
|
358
374
|
return .success
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
7f6fb27d35bc920588fa9100a7fd63ac
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1089c59b7c8b6286130e48fa84cdbd683184f842
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e7035fa3aa4c45a8f1c77d9472b35851ffb8e75bed9e68db92e2fd37244af937
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b649370f9eddc880f23c87efa10c0c2945fe4cff8305a53ab9c4daf2709130c8fe2cac5704709d502934cc0715442b81bd04295ea089e9ea7d1d2b7c778a5b45
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
20a4382720f542aa2ff96be772e74dd8
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e68c21381c292fb846dfbf1e5d1100a8121ac714
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ad896a65fac8e318f5c60bed4af93679a59f13e14e2d0efc403172de490e5651
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
07c509104e22b83b36e7e8b4b41d3b991945b3840e88136de912c13b7cb99527471248df5804f37d1ab675ca1e5d013110ec6e4e0f3df39328514ec182a3b5cb
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"component": {
|
|
4
4
|
"group": "expo.modules.audio",
|
|
5
5
|
"module": "expo.modules.audio",
|
|
6
|
-
"version": "58.0.
|
|
6
|
+
"version": "58.0.11",
|
|
7
7
|
"attributes": {
|
|
8
8
|
"org.gradle.status": "release"
|
|
9
9
|
}
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
{
|
|
27
|
-
"name": "expo.modules.audio-58.0.
|
|
28
|
-
"url": "expo.modules.audio-58.0.
|
|
29
|
-
"size":
|
|
30
|
-
"sha512": "
|
|
31
|
-
"sha256": "
|
|
32
|
-
"sha1": "
|
|
33
|
-
"md5": "
|
|
27
|
+
"name": "expo.modules.audio-58.0.11.aar",
|
|
28
|
+
"url": "expo.modules.audio-58.0.11.aar",
|
|
29
|
+
"size": 565381,
|
|
30
|
+
"sha512": "07c509104e22b83b36e7e8b4b41d3b991945b3840e88136de912c13b7cb99527471248df5804f37d1ab675ca1e5d013110ec6e4e0f3df39328514ec182a3b5cb",
|
|
31
|
+
"sha256": "ad896a65fac8e318f5c60bed4af93679a59f13e14e2d0efc403172de490e5651",
|
|
32
|
+
"sha1": "e68c21381c292fb846dfbf1e5d1100a8121ac714",
|
|
33
|
+
"md5": "20a4382720f542aa2ff96be772e74dd8"
|
|
34
34
|
}
|
|
35
35
|
]
|
|
36
36
|
},
|
|
@@ -78,13 +78,6 @@
|
|
|
78
78
|
"requires": "1.9.1"
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
-
{
|
|
82
|
-
"group": "androidx.media3",
|
|
83
|
-
"module": "media3-ui",
|
|
84
|
-
"version": {
|
|
85
|
-
"requires": "1.9.1"
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
81
|
{
|
|
89
82
|
"group": "androidx.media3",
|
|
90
83
|
"module": "media3-exoplayer",
|
|
@@ -137,13 +130,13 @@
|
|
|
137
130
|
],
|
|
138
131
|
"files": [
|
|
139
132
|
{
|
|
140
|
-
"name": "expo.modules.audio-58.0.
|
|
141
|
-
"url": "expo.modules.audio-58.0.
|
|
142
|
-
"size":
|
|
143
|
-
"sha512": "
|
|
144
|
-
"sha256": "
|
|
145
|
-
"sha1": "
|
|
146
|
-
"md5": "
|
|
133
|
+
"name": "expo.modules.audio-58.0.11.aar",
|
|
134
|
+
"url": "expo.modules.audio-58.0.11.aar",
|
|
135
|
+
"size": 565381,
|
|
136
|
+
"sha512": "07c509104e22b83b36e7e8b4b41d3b991945b3840e88136de912c13b7cb99527471248df5804f37d1ab675ca1e5d013110ec6e4e0f3df39328514ec182a3b5cb",
|
|
137
|
+
"sha256": "ad896a65fac8e318f5c60bed4af93679a59f13e14e2d0efc403172de490e5651",
|
|
138
|
+
"sha1": "e68c21381c292fb846dfbf1e5d1100a8121ac714",
|
|
139
|
+
"md5": "20a4382720f542aa2ff96be772e74dd8"
|
|
147
140
|
}
|
|
148
141
|
]
|
|
149
142
|
},
|
|
@@ -157,13 +150,13 @@
|
|
|
157
150
|
},
|
|
158
151
|
"files": [
|
|
159
152
|
{
|
|
160
|
-
"name": "expo.modules.audio-58.0.
|
|
161
|
-
"url": "expo.modules.audio-58.0.
|
|
162
|
-
"size":
|
|
163
|
-
"sha512": "
|
|
164
|
-
"sha256": "
|
|
165
|
-
"sha1": "
|
|
166
|
-
"md5": "
|
|
153
|
+
"name": "expo.modules.audio-58.0.11-sources.jar",
|
|
154
|
+
"url": "expo.modules.audio-58.0.11-sources.jar",
|
|
155
|
+
"size": 44839,
|
|
156
|
+
"sha512": "b649370f9eddc880f23c87efa10c0c2945fe4cff8305a53ab9c4daf2709130c8fe2cac5704709d502934cc0715442b81bd04295ea089e9ea7d1d2b7c778a5b45",
|
|
157
|
+
"sha256": "e7035fa3aa4c45a8f1c77d9472b35851ffb8e75bed9e68db92e2fd37244af937",
|
|
158
|
+
"sha1": "1089c59b7c8b6286130e48fa84cdbd683184f842",
|
|
159
|
+
"md5": "7f6fb27d35bc920588fa9100a7fd63ac"
|
|
167
160
|
}
|
|
168
161
|
]
|
|
169
162
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a3849da446f6d0ec25bccadb355562c5
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0c430787cea17db40d80ad5ef5f8f90c56789ca3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2abccf282782faedf948e770e536e2f751e850afa7ed033d76e517c6602a9e10
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0dda8f8f4ce87379065e0d2bbcd33727fc3d406e4f4f19d6001608ffe531864c519e2bb6fccbfe7cb214d48d20d7573ef149c1c7ee2fd8abe27735723001091e
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<modelVersion>4.0.0</modelVersion>
|
|
10
10
|
<groupId>expo.modules.audio</groupId>
|
|
11
11
|
<artifactId>expo.modules.audio</artifactId>
|
|
12
|
-
<version>58.0.
|
|
12
|
+
<version>58.0.11</version>
|
|
13
13
|
<packaging>aar</packaging>
|
|
14
14
|
<name>expo.modules.audio</name>
|
|
15
15
|
<url>https://github.com/expo/expo</url>
|
|
@@ -67,12 +67,6 @@
|
|
|
67
67
|
<version>1.9.1</version>
|
|
68
68
|
<scope>runtime</scope>
|
|
69
69
|
</dependency>
|
|
70
|
-
<dependency>
|
|
71
|
-
<groupId>androidx.media3</groupId>
|
|
72
|
-
<artifactId>media3-ui</artifactId>
|
|
73
|
-
<version>1.9.1</version>
|
|
74
|
-
<scope>runtime</scope>
|
|
75
|
-
</dependency>
|
|
76
70
|
<dependency>
|
|
77
71
|
<groupId>androidx.media3</groupId>
|
|
78
72
|
<artifactId>media3-exoplayer</artifactId>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
8cc9deda15059f0232fb08dba46da6ce
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3111a3b346fef94740c2b7d6a6906dc8701dd5b5
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
41026cf88ca9f4b261d9fcb4e2aa3e24f79cb3407fe95a3c2a93f31d7c2b94b3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3747a431b8ae4c73f3d9746442f7144af5a0f98fa0c420641c08956578e734419e7267a34a8ef620e855d281ef8b32fc07ed60117ddbb8c0b2f44bffcccb8e1a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-audio",
|
|
3
|
-
"version": "58.0.
|
|
3
|
+
"version": "58.0.11",
|
|
4
4
|
"description": "A cross-platform audio library for React Native and Expo apps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"android",
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"main": "build/index.js",
|
|
23
23
|
"types": "build/index.d.ts",
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@expo/internal-scripts": "58.0.
|
|
25
|
+
"@expo/internal-scripts": "58.0.5",
|
|
26
26
|
"@types/jest": "^30.0.0",
|
|
27
27
|
"@types/node": "^22.14.0",
|
|
28
28
|
"@types/react": "~19.3.0",
|
|
29
|
-
"expo": "58.0.
|
|
30
|
-
"expo-asset": "58.0.
|
|
29
|
+
"expo": "58.0.22",
|
|
30
|
+
"expo-asset": "58.0.19"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"expo": "*",
|
package/src/AudioConstants.ts
CHANGED
|
@@ -24,4 +24,28 @@ export type AudioLockScreenOptions = {
|
|
|
24
24
|
* and scrub bar, and disable seek controls.
|
|
25
25
|
*/
|
|
26
26
|
isLiveStream?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* How far, in seconds, the lock screen seek forward button jumps ahead.
|
|
29
|
+
* Values below `0.1` are clamped up to `0.1` so that the button always moves playback.
|
|
30
|
+
*
|
|
31
|
+
* On Android, the whole-second values `5`, `10`, `15`, and `30` render a matching numbered skip
|
|
32
|
+
* icon, and every other value renders a generic skip icon. On iOS, the number is drawn into the
|
|
33
|
+
* glyph for any value, because it is passed through as the skip command's preferred interval.
|
|
34
|
+
* On web, the browser decides which control it shows and which offset it sends, so this value is
|
|
35
|
+
* only used as a fallback when the browser omits an offset of its own.
|
|
36
|
+
* @default 10
|
|
37
|
+
*/
|
|
38
|
+
seekForwardIntervalSeconds?: number;
|
|
39
|
+
/**
|
|
40
|
+
* How far, in seconds, the lock screen seek backward button jumps back.
|
|
41
|
+
* Values below `0.1` are clamped up to `0.1` so that the button always moves playback.
|
|
42
|
+
*
|
|
43
|
+
* On Android, the whole-second values `5`, `10`, `15`, and `30` render a matching numbered skip
|
|
44
|
+
* icon, and every other value renders a generic skip icon. On iOS, the number is drawn into the
|
|
45
|
+
* glyph for any value, because it is passed through as the skip command's preferred interval.
|
|
46
|
+
* On web, the browser decides which control it shows and which offset it sends, so this value is
|
|
47
|
+
* only used as a fallback when the browser omits an offset of its own.
|
|
48
|
+
* @default 10
|
|
49
|
+
*/
|
|
50
|
+
seekBackwardIntervalSeconds?: number;
|
|
27
51
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AudioMetadata } from './Audio.types';
|
|
2
2
|
import type { AudioLockScreenOptions } from './AudioConstants';
|
|
3
|
+
import { normalizeLockScreenOptions } from './utils/lockScreenOptions';
|
|
3
4
|
|
|
4
5
|
interface MediaSessionPlayer {
|
|
5
6
|
play(): void;
|
|
@@ -13,8 +14,6 @@ interface MediaSessionPlayer {
|
|
|
13
14
|
readonly playbackRate: number;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
const SKIP_SECONDS = 10;
|
|
17
|
-
|
|
18
17
|
class MediaSessionController {
|
|
19
18
|
private activePlayer: MediaSessionPlayer | null = null;
|
|
20
19
|
private metadata: AudioMetadata | null = null;
|
|
@@ -33,7 +32,7 @@ class MediaSessionController {
|
|
|
33
32
|
|
|
34
33
|
this.activePlayer = player;
|
|
35
34
|
this.metadata = metadata ?? null;
|
|
36
|
-
this.options = options
|
|
35
|
+
this.options = normalizeLockScreenOptions(options);
|
|
37
36
|
|
|
38
37
|
this._applyMetadata();
|
|
39
38
|
this._applyActionHandlers();
|
|
@@ -159,14 +158,14 @@ class MediaSessionController {
|
|
|
159
158
|
});
|
|
160
159
|
|
|
161
160
|
const seekForward = (details: MediaSessionActionDetails) => {
|
|
162
|
-
const skipTime = details.seekOffset ??
|
|
161
|
+
const skipTime = details.seekOffset ?? this.options?.seekForwardIntervalSeconds ?? 10;
|
|
163
162
|
const newTime = Math.min(player.currentTime + skipTime, player.duration || 0);
|
|
164
163
|
player.seekTo(newTime);
|
|
165
164
|
this.updatePositionState(player);
|
|
166
165
|
};
|
|
167
166
|
|
|
168
167
|
const seekBackward = (details: MediaSessionActionDetails) => {
|
|
169
|
-
const skipTime = details.seekOffset ??
|
|
168
|
+
const skipTime = details.seekOffset ?? this.options?.seekBackwardIntervalSeconds ?? 10;
|
|
170
169
|
const newTime = Math.max(player.currentTime - skipTime, 0);
|
|
171
170
|
player.seekTo(newTime);
|
|
172
171
|
this.updatePositionState(player);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AudioLockScreenOptions } from '../AudioConstants';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_SEEK_INTERVAL_SECONDS = 10;
|
|
4
|
+
const MIN_SEEK_INTERVAL_SECONDS = 0.1;
|
|
5
|
+
|
|
6
|
+
function normalizeInterval(seconds: number | undefined): number {
|
|
7
|
+
if (seconds === undefined || !Number.isFinite(seconds)) {
|
|
8
|
+
return DEFAULT_SEEK_INTERVAL_SECONDS;
|
|
9
|
+
}
|
|
10
|
+
return Math.max(seconds, MIN_SEEK_INTERVAL_SECONDS);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function normalizeLockScreenOptions(
|
|
14
|
+
options: AudioLockScreenOptions | undefined
|
|
15
|
+
): AudioLockScreenOptions {
|
|
16
|
+
return {
|
|
17
|
+
...options,
|
|
18
|
+
seekForwardIntervalSeconds: normalizeInterval(options?.seekForwardIntervalSeconds),
|
|
19
|
+
seekBackwardIntervalSeconds: normalizeInterval(options?.seekBackwardIntervalSeconds),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
a514205fbda56545f5396a0990b9f4f9
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
cbab8824e92895ba7865770ec62e4875325bd42a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0f11527368066bf18f182fb39f3c1d69696aa59ddaec4b7ee16ec48183e25e23
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ec4911e9008b292a0785c1496a40432c56b611dc2f19ecb0dc71020d4b439fed146d7bb18337a96bf6b77da28cb0fe71e6e8c7bd17b37649e554e4de43fb9d37
|
package/local-maven-repo/expo/modules/audio/expo.modules.audio/58.0.9/expo.modules.audio-58.0.9.aar
DELETED
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
9bd94c9bb03c7d84ae5536946035f450
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
bc24348a398e64ff880dc00571befaff11fcdd7c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
148a8d932e5afc93e3a3cf4ea35d969d7f3329ac3127cc9da9fea428144321c9
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4251e28214a66fe78e625507dc58ff5a7f4547ce00a7ac7fd93171043547fd383168a0fff1936654259ebb916e4ac392770afd96be55a8ec7e7185fac49f7d2f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
5e299a847ed16ce1866161eb0dddeaf2
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
22318dfc20d8ed34bb9ab0cbfcfe8df59b938203
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
fc5b401e0b74ce952248f6326f1886e58c5782af8ba4be045499ce3d6662a248
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0bf6874fcb8ebe25db4034cff6ff6f76dedfb0f0640dc04f825d50a321801a66598c09c5eb4b8daaa0a27bd64b2208e53ed19aa4632674de03d125b1ae50c6f1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
68d2bf761a10b1eb2756fdcbc901d2d1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0753d2a03dadccd6ec89f924f7d7a530003a397b
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b7cd8f79f5f7e4914206b6912eeb50edd852a485299c7c3e430306db626ce63b
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
641646b9c31bd16aa30a7bf6cac11ad642525e2812a41ca135edcfbddece5e8038816658ff8906941ef5e3343f87b870dd8774790484c339997f15558f6f4b5b
|