@roitium/expo-orpheus 0.2.3 → 0.2.4
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/android/src/main/java/expo/modules/orpheus/ExpoOrpheusModule.kt +38 -9
- package/build/ExpoOrpheusModule.d.ts +7 -3
- package/build/ExpoOrpheusModule.d.ts.map +1 -1
- package/build/ExpoOrpheusModule.js.map +1 -1
- package/build/hooks/useCurrentTrack.js +1 -1
- package/build/hooks/useCurrentTrack.js.map +1 -1
- package/build/hooks/useShuffleMode.js +1 -1
- package/build/hooks/useShuffleMode.js.map +1 -1
- package/package.json +1 -1
- package/src/ExpoOrpheusModule.ts +10 -5
- package/src/hooks/useCurrentTrack.ts +1 -1
- package/src/hooks/useShuffleMode.ts +1 -1
|
@@ -29,6 +29,11 @@ class ExpoOrpheusModule : Module() {
|
|
|
29
29
|
// 记录上一首歌曲的 ID,用于在切歌时发送给 JS
|
|
30
30
|
private var lastMediaId: String? = null
|
|
31
31
|
|
|
32
|
+
private var currentTrackDuration: Long = 0L
|
|
33
|
+
|
|
34
|
+
// 用来暂存上一首歌曲切歌瞬间的进度
|
|
35
|
+
private var lastTrackFinalPosition: Long = 0L
|
|
36
|
+
|
|
32
37
|
val gson = Gson()
|
|
33
38
|
|
|
34
39
|
override fun definition() = ModuleDefinition {
|
|
@@ -36,10 +41,11 @@ class ExpoOrpheusModule : Module() {
|
|
|
36
41
|
|
|
37
42
|
Events(
|
|
38
43
|
"onPlaybackStateChanged",
|
|
39
|
-
"onTrackTransition",
|
|
40
44
|
"onPlayerError",
|
|
41
45
|
"onPositionUpdate",
|
|
42
|
-
"onIsPlayingChanged"
|
|
46
|
+
"onIsPlayingChanged",
|
|
47
|
+
"onTrackFinished",
|
|
48
|
+
"onTrackStarted"
|
|
43
49
|
)
|
|
44
50
|
|
|
45
51
|
OnCreate {
|
|
@@ -307,19 +313,37 @@ class ExpoOrpheusModule : Module() {
|
|
|
307
313
|
* 核心:处理切歌、播放结束逻辑
|
|
308
314
|
*/
|
|
309
315
|
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
|
310
|
-
val
|
|
311
|
-
Player.MEDIA_ITEM_TRANSITION_REASON_AUTO
|
|
316
|
+
val newId = mediaItem?.mediaId ?: ""
|
|
312
317
|
|
|
313
318
|
sendEvent(
|
|
314
|
-
"
|
|
315
|
-
"
|
|
316
|
-
"previousTrackId" to lastMediaId, // 上一首歌是什么
|
|
319
|
+
"onTrackStarted", mapOf(
|
|
320
|
+
"trackId" to newId,
|
|
317
321
|
"reason" to reason
|
|
318
322
|
)
|
|
319
323
|
)
|
|
320
324
|
|
|
321
|
-
|
|
322
|
-
|
|
325
|
+
lastMediaId = newId
|
|
326
|
+
currentTrackDuration = 0L
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
override fun onPositionDiscontinuity(
|
|
330
|
+
oldPosition: Player.PositionInfo,
|
|
331
|
+
newPosition: Player.PositionInfo,
|
|
332
|
+
reason: Int
|
|
333
|
+
) {
|
|
334
|
+
Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT
|
|
335
|
+
if (oldPosition.mediaItemIndex != newPosition.mediaItemIndex) {
|
|
336
|
+
val lastMediaItem =
|
|
337
|
+
controller?.getMediaItemAt(oldPosition.mediaItemIndex) ?: return
|
|
338
|
+
|
|
339
|
+
sendEvent(
|
|
340
|
+
"onTrackFinished", mapOf(
|
|
341
|
+
"trackId" to lastMediaItem.mediaId,
|
|
342
|
+
"finalPosition" to oldPosition.positionMs / 1000.0,
|
|
343
|
+
"duration" to currentTrackDuration / 1000.0,
|
|
344
|
+
)
|
|
345
|
+
)
|
|
346
|
+
}
|
|
323
347
|
}
|
|
324
348
|
|
|
325
349
|
/**
|
|
@@ -333,6 +357,11 @@ class ExpoOrpheusModule : Module() {
|
|
|
333
357
|
)
|
|
334
358
|
)
|
|
335
359
|
|
|
360
|
+
if (state == Player.STATE_READY) {
|
|
361
|
+
val d = controller?.duration
|
|
362
|
+
if (d != C.TIME_UNSET && d != null) currentTrackDuration = d
|
|
363
|
+
}
|
|
364
|
+
|
|
336
365
|
updateProgressRunnerState()
|
|
337
366
|
}
|
|
338
367
|
|
|
@@ -29,11 +29,15 @@ export type OrpheusEvents = {
|
|
|
29
29
|
onPlaybackStateChanged(event: {
|
|
30
30
|
state: PlaybackState;
|
|
31
31
|
}): void;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
previousTrackId?: string;
|
|
32
|
+
onTrackStarted(event: {
|
|
33
|
+
trackId: string;
|
|
35
34
|
reason: TransitionReason;
|
|
36
35
|
}): void;
|
|
36
|
+
onTrackFinished(event: {
|
|
37
|
+
trackId: string;
|
|
38
|
+
finalPosition: number;
|
|
39
|
+
duration: number;
|
|
40
|
+
}): void;
|
|
37
41
|
onPlayerError(event: {
|
|
38
42
|
code: string;
|
|
39
43
|
message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoOrpheusModule.d.ts","sourceRoot":"","sources":["../src/ExpoOrpheusModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtE,oBAAY,aAAa;IACvB,IAAI,IAAI;IACR,SAAS,IAAI;IACb,KAAK,IAAI;IACT,KAAK,IAAI;CACV;AAED,oBAAY,UAAU;IACpB,GAAG,IAAI;IACP,KAAK,IAAI;IACT,KAAK,IAAI;CACV;AAED,oBAAY,gBAAgB;IAC1B,MAAM,IAAI;IACV,IAAI,IAAI;IACR,IAAI,IAAI;IACR,gBAAgB,IAAI;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,sBAAsB,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,aAAa,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9D,
|
|
1
|
+
{"version":3,"file":"ExpoOrpheusModule.d.ts","sourceRoot":"","sources":["../src/ExpoOrpheusModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoOrpheusModule.js","sourceRoot":"","sources":["../src/ExpoOrpheusModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAgB,MAAM,mBAAmB,CAAC;AAEtE,MAAM,CAAN,IAAY,aAKX;AALD,WAAY,aAAa;IACvB,iDAAQ,CAAA;IACR,2DAAa,CAAA;IACb,mDAAS,CAAA;IACT,mDAAS,CAAA;AACX,CAAC,EALW,aAAa,KAAb,aAAa,QAKxB;AAED,MAAM,CAAN,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,yCAAO,CAAA;IACP,6CAAS,CAAA;IACT,6CAAS,CAAA;AACX,CAAC,EAJW,UAAU,KAAV,UAAU,QAIrB;AAED,MAAM,CAAN,IAAY,gBAKX;AALD,WAAY,gBAAgB;IAC1B,2DAAU,CAAA;IACV,uDAAQ,CAAA;IACR,uDAAQ,CAAA;IACR,+EAAoB,CAAA;AACtB,CAAC,EALW,gBAAgB,KAAhB,gBAAgB,QAK3B;
|
|
1
|
+
{"version":3,"file":"ExpoOrpheusModule.js","sourceRoot":"","sources":["../src/ExpoOrpheusModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAgB,MAAM,mBAAmB,CAAC;AAEtE,MAAM,CAAN,IAAY,aAKX;AALD,WAAY,aAAa;IACvB,iDAAQ,CAAA;IACR,2DAAa,CAAA;IACb,mDAAS,CAAA;IACT,mDAAS,CAAA;AACX,CAAC,EALW,aAAa,KAAb,aAAa,QAKxB;AAED,MAAM,CAAN,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,yCAAO,CAAA;IACP,6CAAS,CAAA;IACT,6CAAS,CAAA;AACX,CAAC,EAJW,UAAU,KAAV,UAAU,QAIrB;AAED,MAAM,CAAN,IAAY,gBAKX;AALD,WAAY,gBAAgB;IAC1B,2DAAU,CAAA;IACV,uDAAQ,CAAA;IACR,uDAAQ,CAAA;IACR,+EAAoB,CAAA;AACtB,CAAC,EALW,gBAAgB,KAAhB,gBAAgB,QAK3B;AAuHD,MAAM,CAAC,MAAM,OAAO,GAAG,mBAAmB,CAAgB,SAAS,CAAC,CAAC","sourcesContent":["import { requireNativeModule, NativeModule } from \"expo-modules-core\";\n\nexport enum PlaybackState {\n IDLE = 1,\n BUFFERING = 2,\n READY = 3,\n ENDED = 4,\n}\n\nexport enum RepeatMode {\n OFF = 0,\n TRACK = 1,\n QUEUE = 2,\n}\n\nexport enum TransitionReason {\n REPEAT = 0,\n AUTO = 1,\n SEEK = 2,\n PLAYLIST_CHANGED = 3,\n}\n\nexport interface Track {\n id: string;\n url: string;\n title?: string;\n artist?: string;\n artwork?: string;\n duration?: number;\n [key: string]: any;\n}\n\nexport type OrpheusEvents = {\n onPlaybackStateChanged(event: { state: PlaybackState }): void;\n onTrackStarted(event: { trackId: string; reason: TransitionReason }): void;\n onTrackFinished(event: {\n trackId: string;\n finalPosition: number;\n duration: number;\n }): void;\n onPlayerError(event: { code: string; message: string }): void;\n onPositionUpdate(event: {\n position: number;\n duration: number;\n buffered: number;\n }): void;\n onIsPlayingChanged(event: { status: boolean }): void;\n};\n\ndeclare class OrpheusModule extends NativeModule<OrpheusEvents> {\n /**\n * 获取当前进度(秒)\n */\n getPosition(): Promise<number>;\n\n /**\n * 获取总时长(秒)\n */\n getDuration(): Promise<number>;\n\n /**\n * 获取缓冲进度(秒)\n */\n getBuffered(): Promise<number>;\n\n /**\n * 获取是否正在播放\n */\n getIsPlaying(): Promise<boolean>;\n\n /**\n * 获取当前播放索引\n */\n getCurrentIndex(): Promise<number>;\n\n /**\n * 获取当前播放的 Track 对象\n */\n getCurrentTrack(): Promise<Track | null>;\n\n /**\n * 获取随机模式状态\n */\n getShuffleMode(): Promise<boolean>;\n\n /**\n * 获取指定索引的 Track\n */\n getIndexTrack(index: number): Promise<Track | null>;\n\n getRepeatMode(): Promise<RepeatMode>;\n\n setBilibiliCookie(cookie: string): void;\n\n play(): Promise<void>;\n\n pause(): Promise<void>;\n\n clear(): Promise<void>;\n\n skipTo(index: number): Promise<void>;\n\n skipToNext(): Promise<void>;\n\n skipToPrevious(): Promise<void>;\n\n /**\n * 跳转进度\n * @param seconds 秒数\n */\n seekTo(seconds: number): Promise<void>;\n\n setRepeatMode(mode: RepeatMode): Promise<void>;\n\n setShuffleMode(enabled: boolean): Promise<void>;\n\n getQueue(): Promise<Track[]>;\n\n /**\n * 添加到队列末尾,且不去重。\n * @param tracks\n * @param startFromId 可选,添加后立即播放该 ID 的曲目\n * @param clearQueue 可选,是否清空当前队列\n */\n addToEnd(\n tracks: Track[],\n startFromId?: string,\n clearQueue?: boolean\n ): Promise<void>;\n\n /**\n * 播放下一首\n * @param track\n */\n playNext(track: Track): Promise<void>;\n\n removeTrack(index: number): Promise<void>;\n}\n\nexport const Orpheus = requireNativeModule<OrpheusModule>(\"Orpheus\");\n"]}
|
|
@@ -24,7 +24,7 @@ export function useCurrentTrack() {
|
|
|
24
24
|
setIndex(currentIndex);
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
|
-
const sub = Orpheus.addListener("
|
|
27
|
+
const sub = Orpheus.addListener("onTrackStarted", async () => {
|
|
28
28
|
const { currentTrack, currentIndex } = await fetchTrack();
|
|
29
29
|
if (isMounted) {
|
|
30
30
|
setTrack(currentTrack);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCurrentTrack.js","sourceRoot":"","sources":["../../src/hooks/useCurrentTrack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAS,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,UAAU,eAAe;IAC7B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAS,CAAC,CAAC,CAAC,CAAC;IAE/C,MAAM,UAAU,GAAG,KAAK,IAAI,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACrD,OAAO,CAAC,eAAe,EAAE;gBACzB,OAAO,CAAC,eAAe,EAAE;aAC1B,CAAC,CAAC;YACH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;QACxC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;YACjD,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC;QAClD,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,IAAI,CAAC;QAErB,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,EAAE;YACnD,IAAI,SAAS,EAAE,CAAC;gBACd,QAAQ,CAAC,YAAY,CAAC,CAAC;gBACvB,QAAQ,CAAC,YAAY,CAAC,CAAC;YACzB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"useCurrentTrack.js","sourceRoot":"","sources":["../../src/hooks/useCurrentTrack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAS,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,UAAU,eAAe;IAC7B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAS,CAAC,CAAC,CAAC,CAAC;IAE/C,MAAM,UAAU,GAAG,KAAK,IAAI,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACrD,OAAO,CAAC,eAAe,EAAE;gBACzB,OAAO,CAAC,eAAe,EAAE;aAC1B,CAAC,CAAC;YACH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;QACxC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;YACjD,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC;QAClD,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,IAAI,CAAC;QAErB,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,EAAE;YACnD,IAAI,SAAS,EAAE,CAAC;gBACd,QAAQ,CAAC,YAAY,CAAC,CAAC;gBACvB,QAAQ,CAAC,YAAY,CAAC,CAAC;YACzB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;YAC1D,IAAI,SAAS,EAAE,CAAC;gBACd,QAAQ,CAAC,YAAY,CAAC,CAAC;gBACvB,QAAQ,CAAC,YAAY,CAAC,CAAC;YACzB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,KAAK,CAAC;YAClB,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Track, Orpheus } from \"../ExpoOrpheusModule\";\n\nexport function useCurrentTrack() {\n const [track, setTrack] = useState<Track | null>(null);\n const [index, setIndex] = useState<number>(-1);\n\n const fetchTrack = async () => {\n try {\n const [currentTrack, currentIndex] = await Promise.all([\n Orpheus.getCurrentTrack(),\n Orpheus.getCurrentIndex(),\n ]);\n return { currentTrack, currentIndex };\n } catch (e) {\n console.warn(\"Failed to fetch current track\", e);\n return { currentTrack: null, currentIndex: -1 };\n }\n };\n\n useEffect(() => {\n let isMounted = true;\n\n fetchTrack().then(({ currentTrack, currentIndex }) => {\n if (isMounted) {\n setTrack(currentTrack);\n setIndex(currentIndex);\n }\n });\n\n const sub = Orpheus.addListener(\"onTrackStarted\", async () => {\n const { currentTrack, currentIndex } = await fetchTrack();\n if (isMounted) {\n setTrack(currentTrack);\n setIndex(currentIndex);\n }\n });\n\n return () => {\n isMounted = false;\n sub.remove();\n };\n }, []);\n\n return { track, index };\n}\n"]}
|
|
@@ -8,7 +8,7 @@ export function useShuffleMode() {
|
|
|
8
8
|
};
|
|
9
9
|
useEffect(() => {
|
|
10
10
|
refresh();
|
|
11
|
-
const sub = Orpheus.addListener("
|
|
11
|
+
const sub = Orpheus.addListener("onTrackStarted", refresh);
|
|
12
12
|
return () => sub.remove();
|
|
13
13
|
}, []);
|
|
14
14
|
const toggleShuffle = async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useShuffleMode.js","sourceRoot":"","sources":["../../src/hooks/useShuffleMode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEtD,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3C,cAAc,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,EAAE,CAAC;QACV,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"useShuffleMode.js","sourceRoot":"","sources":["../../src/hooks/useShuffleMode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEtD,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3C,cAAc,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,EAAE,CAAC;QACV,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,aAAa,GAAG,KAAK,IAAI,EAAE;QAC/B,MAAM,MAAM,GAAG,CAAC,WAAW,CAAC;QAC5B,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,MAAM,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACrC,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,OAAO,CAAC,WAAW,EAAE,aAAa,CAAU,CAAC;AAC/C,CAAC","sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Orpheus } from \"../ExpoOrpheusModule\";\n\nexport function useShuffleMode() {\n const [shuffleMode, setShuffleMode] = useState(false);\n\n const refresh = async () => {\n const val = await Orpheus.getShuffleMode();\n setShuffleMode(val);\n };\n\n useEffect(() => {\n refresh();\n const sub = Orpheus.addListener(\"onTrackStarted\", refresh);\n return () => sub.remove();\n }, []);\n\n const toggleShuffle = async () => {\n const newVal = !shuffleMode;\n setShuffleMode(newVal);\n await Orpheus.setShuffleMode(newVal);\n refresh();\n };\n\n return [shuffleMode, toggleShuffle] as const;\n}\n"]}
|
package/package.json
CHANGED
package/src/ExpoOrpheusModule.ts
CHANGED
|
@@ -32,10 +32,11 @@ export interface Track {
|
|
|
32
32
|
|
|
33
33
|
export type OrpheusEvents = {
|
|
34
34
|
onPlaybackStateChanged(event: { state: PlaybackState }): void;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
onTrackStarted(event: { trackId: string; reason: TransitionReason }): void;
|
|
36
|
+
onTrackFinished(event: {
|
|
37
|
+
trackId: string;
|
|
38
|
+
finalPosition: number;
|
|
39
|
+
duration: number;
|
|
39
40
|
}): void;
|
|
40
41
|
onPlayerError(event: { code: string; message: string }): void;
|
|
41
42
|
onPositionUpdate(event: {
|
|
@@ -121,7 +122,11 @@ declare class OrpheusModule extends NativeModule<OrpheusEvents> {
|
|
|
121
122
|
* @param startFromId 可选,添加后立即播放该 ID 的曲目
|
|
122
123
|
* @param clearQueue 可选,是否清空当前队列
|
|
123
124
|
*/
|
|
124
|
-
addToEnd(
|
|
125
|
+
addToEnd(
|
|
126
|
+
tracks: Track[],
|
|
127
|
+
startFromId?: string,
|
|
128
|
+
clearQueue?: boolean
|
|
129
|
+
): Promise<void>;
|
|
125
130
|
|
|
126
131
|
/**
|
|
127
132
|
* 播放下一首
|
|
@@ -28,7 +28,7 @@ export function useCurrentTrack() {
|
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
const sub = Orpheus.addListener("
|
|
31
|
+
const sub = Orpheus.addListener("onTrackStarted", async () => {
|
|
32
32
|
const { currentTrack, currentIndex } = await fetchTrack();
|
|
33
33
|
if (isMounted) {
|
|
34
34
|
setTrack(currentTrack);
|