Skip to content

Commit

Permalink
新增蓝牙歌词支持(#615
Browse files Browse the repository at this point in the history
  • Loading branch information
lyswhut committed Nov 2, 2024
1 parent 81ae3cb commit ccebcd2
Show file tree
Hide file tree
Showing 27 changed files with 332 additions and 103 deletions.
118 changes: 97 additions & 21 deletions android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import android.os.Bundle;
import android.util.Log;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.WritableMap;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -20,12 +22,14 @@ public class Lyric extends LyricPlayer {
LyricEvent lyricEvent = null;
ReactApplicationContext reactAppContext;

boolean isShowLyric = false;
boolean isRunPlayer = false;
// String lastText = "LX Music ^-^";
int lastLine = 0;
List lines = new ArrayList();
boolean isShowTranslation;
boolean isShowRoma;
boolean isShowLyricView = false;
boolean isSendLyricTextEvent = false;
String lyricText = "";
String translationText = "";
String romaLyricText = "";
Expand All @@ -36,6 +40,7 @@ public class Lyric extends LyricPlayer {
this.isShowRoma = isShowRoma;
this.playbackRate = playbackRate;
registerScreenBroadcastReceiver();
// checkA2DPConnection(reactContext);
}

private void registerScreenBroadcastReceiver() {
Expand Down Expand Up @@ -65,8 +70,40 @@ public void onReceive(Context context, Intent intent) {
reactAppContext.registerReceiver(screenOnOffReceiver, theFilter);
}

// private void checkA2DPConnection(Context context) {
// BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

// if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
// bluetoothAdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() {
// @Override
// public void onServiceConnected(int profile, BluetoothProfile proxy) {
// if (profile == BluetoothProfile.A2DP) {
// List<BluetoothDevice> connectedDevices = proxy.getConnectedDevices();
// if (!connectedDevices.isEmpty()) {
// System.out.println("已连接的 A2DP 媒体设备:");
// for (BluetoothDevice device : connectedDevices) {
// System.out.println("设备名称: " + "地址: " + device.getAddress());
// }
// } else {
// System.out.println("没有连接的 A2DP 媒体设备");
// }
// }
// bluetoothAdapter.closeProfileProxy(profile, proxy);
// }

// @Override
// public void onServiceDisconnected(int profile) {
// // 服务断开时的处理
// System.out.println("蓝牙服务断开时的处理");
// }
// }, BluetoothProfile.A2DP);
// } else {
// System.out.println("蓝牙未开启或设备不支持蓝牙");
// }
// }

private void handleScreenOff() {
if (!isShowLyric) return;
if (!isRunPlayer || !isShowLyricView) return;
setTempPause(true);

if (lyricView != null) {
Expand All @@ -77,30 +114,59 @@ private void handleScreenOff() {
}

private void handleScreenOn() {
if (!isShowLyric) return;
if (!isRunPlayer || !isShowLyricView) return;
if (lyricView == null) lyricView = new LyricView(reactAppContext, lyricEvent);
lyricView.runOnUiThread(() -> {
lyricView.showLyricView();
setViewLyric(lastLine);
handleGetCurrentLyric(lastLine);
setTempPause(false);
});
}

private void setViewLyric(int lineNum) {
private void pausePlayer() {
if (!isRunPlayer || isShowLyricView || isSendLyricTextEvent) return;
isRunPlayer = false;
this.pause();
}

private void setCurrentLyric(String lyric, ArrayList<String> extendedLyrics) {
if (isShowLyricView && lyricView != null) {
lyricView.setLyric(lyric, extendedLyrics);
}
if (isSendLyricTextEvent) {
WritableMap params = Arguments.createMap();
params.putString("text", lyric);
params.putArray("extendedLyrics", Arguments.makeNativeArray(extendedLyrics));
lyricEvent.sendEvent(lyricEvent.LYRIC_Line_PLAY, params);
}
}
private void handleGetCurrentLyric(int lineNum) {
lastLine = lineNum;
if (lyricView == null) return;
if (lineNum >= 0 && lineNum < lines.size()) {
HashMap line = (HashMap) lines.get(lineNum);
if (line != null) {
lyricView.setLyric((String) line.get("text"), (ArrayList<String>) line.get("extendedLyrics"));
setCurrentLyric((String) line.get("text"), (ArrayList<String>) line.get("extendedLyrics"));
return;
}
}
lyricView.setLyric("", new ArrayList<>(0));
setCurrentLyric("", new ArrayList<>(0));
}

public void showLyric(Bundle options, Promise promise) {
public void setSendLyricTextEvent(boolean isSend) {
if (isSendLyricTextEvent == isSend) return;
isSendLyricTextEvent = isSend;
if (isSend) {
if (lyricEvent == null) lyricEvent = new LyricEvent(reactAppContext);
isRunPlayer = true;
} else {
pausePlayer();
}
}

public void showDesktopLyric(Bundle options, Promise promise) {
if (isShowLyricView) return;
if (lyricEvent == null) lyricEvent = new LyricEvent(reactAppContext);
isShowLyricView = true;
if (lyricView == null) lyricView = new LyricView(reactAppContext, lyricEvent);
try {
lyricView.showLyricView(options);
Expand All @@ -109,24 +175,26 @@ public void showLyric(Bundle options, Promise promise) {
Log.e("Lyric", e.getMessage());
return;
}

isShowLyric = true;
isRunPlayer = true;
promise.resolve(null);
}

public void hideLyric() {
this.pause();
public void hideDesktopLyric() {
if (!isShowLyricView) return;
isShowLyricView = false;
pausePlayer();
if (lyricView != null) {
lyricView.destroy();
lyricView = null;
}
isShowLyric = false;
}

private void refreshLyric() {
if (!isRunPlayer) return;
ArrayList<String> extendedLyrics = new ArrayList<>(2);
if (isShowTranslation && !"".equals(translationText)) extendedLyrics.add(translationText);
if (isShowRoma && !"".equals(romaLyricText)) extendedLyrics.add(romaLyricText);
if (lyricView != null) super.setLyric(lyricText, extendedLyrics);
super.setLyric(lyricText, extendedLyrics);
}

public void setLyric(String lyric, String translation, String romaLyric) {
Expand All @@ -139,7 +207,7 @@ public void setLyric(String lyric, String translation, String romaLyric) {
@Override
public void onSetLyric(List lines) {
this.lines = lines;
setViewLyric(-1);
handleGetCurrentLyric(-1);
// for (int i = 0; i < lines.size(); i++) {
// HashMap line = (HashMap) lines.get(i);
// Log.d("Lyric", "onSetLyric: " +(String) line.get("text") + " " + line.get("extendedLyrics"));
Expand All @@ -148,14 +216,14 @@ public void onSetLyric(List lines) {

@Override
public void onPlay(int lineNum) {
setViewLyric(lineNum);
handleGetCurrentLyric(lineNum);
// Log.d("Lyric", lineNum + " " + text + " " + (String) line.get("translation"));
}

public void pauseLyric() {
pause();
if (!isShowLyric) return;
if (lyricView != null) lyricView.setLyric("", new ArrayList<>(0));
if (!isRunPlayer) return;
handleGetCurrentLyric(-1);
}

public void lockLyric() {
Expand Down Expand Up @@ -199,14 +267,22 @@ public void toggleRoma(boolean isShowRoma) {
}

public void setPlayedColor(String unplayColor, String playedColor, String shadowColor) {
if (lyricView == null) return;
lyricView.setColor(unplayColor, playedColor, shadowColor);
}

public void setAlpha(float alpha) { lyricView.setAlpha(alpha); }
public void setAlpha(float alpha) {
if (lyricView == null) return;
lyricView.setAlpha(alpha);
}

public void setTextSize(float size) { lyricView.setTextSize(size); }
public void setTextSize(float size) {
if (lyricView == null) return;
lyricView.setTextSize(size);
}

public void setLyricTextPosition(String positionX, String positionY) {
if (lyricView == null) return;
lyricView.setLyricTextPosition(positionX, positionY);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package cn.toside.music.mobile.lyric;

import android.util.Log;

import androidx.annotation.Nullable;

import com.facebook.react.bridge.ReactApplicationContext;
Expand All @@ -10,12 +8,13 @@

public class LyricEvent {
final String SET_VIEW_POSITION = "set-position";
final String LYRIC_Line_PLAY = "lyric-line-play";

private final ReactApplicationContext reactContext;
LyricEvent(ReactApplicationContext reactContext) { this.reactContext = reactContext; }

public void sendEvent(String eventName, @Nullable WritableMap params) {
Log.d("Lyric", "senEvent: " + eventName);
// Log.d("Lyric", "senEvent: " + eventName);
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,21 @@ public void removeListeners(Integer count) {
}

@ReactMethod
public void showLyric(ReadableMap data, Promise promise) {
public void showDesktopLyric(ReadableMap data, Promise promise) {
if (lyric == null) lyric = new Lyric(reactContext, isShowTranslation, isShowRoma, playbackRate);
lyric.showLyric(Arguments.toBundle(data), promise);
lyric.showDesktopLyric(Arguments.toBundle(data), promise);
}

@ReactMethod
public void hideLyric(Promise promise) {
if (lyric != null) lyric.hideLyric();
public void hideDesktopLyric(Promise promise) {
if (lyric != null) lyric.hideDesktopLyric();
promise.resolve(null);
}

@ReactMethod
public void setSendLyricTextEvent(boolean isSend, Promise promise) {
if (lyric == null) lyric = new Lyric(reactContext, isShowTranslation, isShowRoma, playbackRate);
lyric.setSendLyricTextEvent(isSend);
promise.resolve(null);
}

Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"react-native-pager-view": "6.3.0",
"react-native-quick-base64": "^2.1.2",
"react-native-quick-md5": "^3.0.6",
"react-native-track-player": "github:lyswhut/react-native-track-player#409bfef00c16eb08f2aea35dfaf0b2fc40be0434",
"react-native-track-player": "github:lyswhut/react-native-track-player#930681ab40fdb50f3d0eedff6ecd29b1666fd3ff",
"react-native-vector-icons": "^10.2.0"
},
"devDependencies": {
Expand Down
4 changes: 4 additions & 0 deletions publish/changeLog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
### 新增

- 新增蓝牙歌词支持,可以去 设置-播放设置-显示蓝牙歌词 启用(#615

### 优化

- 首次使用的提示窗口可以点击背景或者返回键关闭(#577
Expand Down
1 change: 1 addition & 0 deletions src/config/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const storageDataPrefix = {
theme: '@theme',

cheatTip: '@cheat_tip',
remoteLyricTip: '@remote_lyric_tip',

dislikeList: '@dislike_list',

Expand Down
1 change: 1 addition & 0 deletions src/config/defaultSetting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const defaultSetting: LX.AppSetting = {
'player.isShowLyricRoma': false,
'player.isShowNotificationImage': true,
'player.isS2t': false,
'player.isShowBluetoothLyric': false,

// 'playDetail.isZoomActiveLrc': false,
// 'playDetail.isShowLyricProgressSetting': false,
Expand Down
4 changes: 2 additions & 2 deletions src/core/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { saveData } from '@/plugins/storage'
import { throttle } from '@/utils/common'
import { getSelectedManagedFolder, saveFontSize, saveViewPrevState, setSelectedManagedFolder } from '@/utils/data'
import { showPactModal as handleShowPactModal } from '@/navigation'
import { hideLyric } from '@/utils/nativeModules/lyricDesktop'
import { hideDesktopLyricView } from '@/utils/nativeModules/lyricDesktop'
import { getPersistedUriList, selectManagedFolder } from '@/utils/fs'


Expand Down Expand Up @@ -57,7 +57,7 @@ export const exitApp = (reason: string) => {
void Promise.all([
hideDesktopLyric(),
destroyPlayer(),
hideLyric(),
hideDesktopLyricView(),
]).finally(() => {
isDestroying = false
utilExitApp()
Expand Down
Loading

0 comments on commit ccebcd2

Please sign in to comment.