xref: /MusicFree/src/service/index.ts (revision 41ddce918e1138d8f16e522cc7c19ac86ceca698)
1import Config from "@/core/config.ts";
2import RNTrackPlayer, { Event, State } from "react-native-track-player";
3import LyricManager from "@/core/lyricManager";
4import LyricUtil from "@/native/lyricUtil";
5import TrackPlayer from "@/core/trackPlayer";
6import { musicIsPaused } from "@/utils/trackUtils";
7import PersistStatus from "@/core/persistStatus.ts";
8
9let resumeState: State | null;
10module.exports = async function () {
11    RNTrackPlayer.addEventListener(Event.RemotePlay, () => TrackPlayer.play());
12    RNTrackPlayer.addEventListener(Event.RemotePause, () =>
13        TrackPlayer.pause(),
14    );
15    RNTrackPlayer.addEventListener(Event.RemotePrevious, () =>
16        TrackPlayer.skipToPrevious(),
17    );
18    RNTrackPlayer.addEventListener(Event.RemoteNext, () =>
19        TrackPlayer.skipToNext(),
20    );
21    RNTrackPlayer.addEventListener(
22        Event.RemoteDuck,
23        async ({paused, permanent}) => {
24            if (Config.getConfig('basic.notInterrupt')) {
25                return;
26            }
27            if (permanent) {
28                return TrackPlayer.pause();
29            }
30            const tempRemoteDuckConf = Config.getConfig(
31                'basic.tempRemoteDuck',
32            );
33            if (tempRemoteDuckConf === '降低音量') {
34                if (paused) {
35                    return RNTrackPlayer.setVolume(0.5);
36                } else {
37                    return RNTrackPlayer.setVolume(1);
38                }
39            } else {
40                if (paused) {
41                    resumeState =
42                        (await RNTrackPlayer.getPlaybackState()).state ??
43                        State.Paused;
44                    return TrackPlayer.pause();
45                } else {
46                    if (resumeState && !musicIsPaused(resumeState)) {
47                        resumeState = null;
48                        return TrackPlayer.play();
49                    }
50                    resumeState = null;
51                }
52            }
53        },
54    );
55
56    RNTrackPlayer.addEventListener(Event.PlaybackActiveTrackChanged, () => {
57        const currentMusicItem = TrackPlayer.getCurrentMusic();
58        if (currentMusicItem) {
59            LyricUtil.setStatusBarLyricText(
60                `${currentMusicItem.title} - ${currentMusicItem.artist}`,
61            );
62        }
63    });
64
65    RNTrackPlayer.addEventListener(Event.PlaybackProgressUpdated, evt => {
66        PersistStatus.set('music.progress', evt.position);
67
68        // 歌词逻辑
69        const parser = LyricManager.getLyricState().lyricParser;
70        if (parser) {
71            const prevLyricText = LyricManager.getCurrentLyric()?.lrc;
72            const currentLyricItem = parser.getPosition(evt.position);
73            if (prevLyricText !== currentLyricItem?.lrc) {
74                LyricManager.setCurrentLyric(currentLyricItem ?? null);
75                const showTranslation = PersistStatus.get(
76                    'lyric.showTranslation',
77                );
78                if (Config.getConfig('lyric.showStatusBarLyric')) {
79                    LyricUtil.setStatusBarLyricText(
80                        (currentLyricItem?.lrc ?? '') +
81                            (showTranslation
82                                ? `\n${currentLyricItem?.translation ?? ''}`
83                                : ''),
84                    );
85                }
86            }
87        }
88    });
89
90    RNTrackPlayer.addEventListener(Event.RemoteStop, async () => {
91        RNTrackPlayer.stop();
92    });
93
94    RNTrackPlayer.addEventListener(Event.RemoteSeek, async evt => {
95        TrackPlayer.seekTo(evt.position);
96    });
97};
98