Skip to content

Commit 350394d

Browse files
author
liuchuancong
committed
fix(*)
1 parent 1e8d520 commit 350394d

12 files changed

Lines changed: 96 additions & 42 deletions

File tree

android/app/proguard-rules.pro

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@
1818
-dontwarn com.google.android.play.core.tasks.Task
1919
-keep class tv.danmaku.ijk.media.player.** {*; }
2020
-dontwarn tv.danmaku.ijk.media.**
21-
-keep interface tv.danmaku.ijk.media.player.** { *; }
21+
-keep interface tv.danmaku.ijk.media.player.** { *; }
22+
-keep class androidx.media3.exoplayer.video.** { *; }
23+
-dontwarn android.view.Choreographer$VsyncCallback

android/app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
2323
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING" />
2424
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
25-
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
25+
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
2626
<!--
2727
Media access permissions.
2828
Android 13 or higher.
@@ -75,12 +75,8 @@
7575
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileProvider" android:exported="false" android:grantUriPermissions="true" tools:replace="android:authorities">
7676
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" tools:replace="android:resource" />
7777
</provider>
78-
<service
79-
android:name=".BetterPlayerService"
80-
android:enabled="true"
81-
android:exported="false"
82-
android:foregroundServiceType="mediaPlayback"
83-
tools:ignore="ForegroundServicePermission" />
78+
<service android:name=".BetterPlayerService" android:foregroundServiceType="mediaPlayback" android:exported="false">
79+
</service>
8480
<!-- 注册服务 -->
8581
<service android:name="com.pravera.flutter_foreground_task.service.ForegroundService" android:foregroundServiceType="mediaPlayback" android:exported="false" />
8682
</application>

android/app/src/main/kotlin/com/mystyle/pure_live/BetterPlayerService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ class BetterPlayerService : Service() {
3737

3838

3939
val notificationBuilder = NotificationCompat.Builder(this, channelId)
40-
.setContentTitle("Better Player Notification")
41-
.setContentText("Better Player is running")
40+
.setContentText("纯粹直播正在运行中...")
4241
.setSmallIcon(R.mipmap.ic_launcher)
42+
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
4343
.setPriority(PRIORITY_MIN)
4444
.setOngoing(true)
4545
.setContentIntent(pendingIntent)

android/app/src/main/kotlin/com/mystyle/pure_live/MainActivity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class MainActivity : FlutterActivity() {
2626
} else {
2727
startService(intent)
2828
}
29-
} catch (_: Exception) {
29+
} catch (exception: Exception) {
3030
}
3131
}
3232

@@ -35,7 +35,7 @@ class MainActivity : FlutterActivity() {
3535
try {
3636
val intent = Intent(this, BetterPlayerService::class.java)
3737
stopService(intent)
38-
} catch (_: Exception) {
38+
} catch (exception: Exception) {
3939

4040
}
4141
}

lib/common/global/platform/background_server.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class BackgroundService {
1212
channelName: 'Pure Live Background Service',
1313
channelDescription: 'This notification appears when the foreground service is running.',
1414
showWhen: true,
15-
priority: NotificationPriority.LOW,
15+
priority: NotificationPriority.HIGH,
1616
),
1717

1818
iosNotificationOptions: const IOSNotificationOptions(showNotification: true, playSound: false),

lib/modules/live_play/widgets/video_player/video_controller_panel.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -947,8 +947,10 @@ class BottomActionBar extends StatelessWidget {
947947
children: [
948948
if (GlobalPlayerState.to.isWindowFullscreen.value ||
949949
GlobalPlayerState.to.isFullscreen.value) ...[
950-
ResolutionSelectorButton(controller: controller),
951-
LineSelectorButton(controller: controller),
950+
if (!GlobalPlayerService.instance.playerManager.isVerticalVideo.value)
951+
ResolutionSelectorButton(controller: controller),
952+
if (!GlobalPlayerService.instance.playerManager.isVerticalVideo.value)
953+
LineSelectorButton(controller: controller),
952954
],
953955
VideoFitSetting(controller: controller),
954956
if (Platform.isWindows) OverlayVolumeControl(controller: controller),

lib/modules/live_play/widgets/video_player/video_player.dart

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,19 @@ class VideoPlayer extends StatefulWidget {
1111
State<VideoPlayer> createState() => _VideoPlayerState();
1212
}
1313

14-
class _VideoPlayerState extends State<VideoPlayer> {
14+
class _VideoPlayerState extends State<VideoPlayer> with WidgetsBindingObserver {
15+
@override
16+
void initState() {
17+
super.initState();
18+
WidgetsBinding.instance.addObserver(this); // 注册监听
19+
}
20+
21+
@override
22+
void dispose() {
23+
WidgetsBinding.instance.removeObserver(this); // 销毁监听
24+
super.dispose();
25+
}
26+
1527
VideoController get controller => widget.controller;
1628
Widget _buildVideo() {
1729
return Obx(
@@ -23,6 +35,32 @@ class _VideoPlayerState extends State<VideoPlayer> {
2335
);
2436
}
2537

38+
bool _isPausedByLifecycle = false;
39+
@override
40+
void didChangeAppLifecycleState(AppLifecycleState state) {
41+
super.didChangeAppLifecycleState(state);
42+
final settingsService = Get.find<SettingsService>();
43+
final player = GlobalPlayerService.instance.playerManager;
44+
45+
if (state == AppLifecycleState.paused) {
46+
if (!settingsService.enableBackgroundPlay.value) {
47+
if (player.isPlayingNow) {
48+
_isPausedByLifecycle = true;
49+
player.pause();
50+
}
51+
} else {
52+
// 2. 如果开启了后台播放,务必显式再次调用 resume/play
53+
// 这是为了防止某些设备在失去 Surface 的瞬间自动暂停
54+
player.resume();
55+
}
56+
} else if (state == AppLifecycleState.resumed) {
57+
if (_isPausedByLifecycle) {
58+
player.resume();
59+
_isPausedByLifecycle = false; // 重置标记
60+
}
61+
}
62+
}
63+
2664
@override
2765
Widget build(BuildContext context) {
2866
return _buildVideo();

lib/player/adapters/fijk_adapter.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import '../models/player_exception.dart';
88
import '../models/player_error_type.dart';
99
import '../core/player_error_dispatcher.dart';
1010
import '../interface/unified_player_interface.dart';
11+
import 'package:pure_live/common/models/live_room.dart';
1112
import 'package:pure_live/player/utils/fijk_helper.dart';
1213
import 'package:pure_live/common/services/settings_service.dart';
1314

@@ -108,7 +109,7 @@ class FijkAdapter implements UnifiedPlayer {
108109
}
109110

110111
@override
111-
Future<void> setDataSource(String url, List<String> playUrls, Map<String, String> headers) async {
112+
Future<void> setDataSource(String url, List<String> playUrls, Map<String, String> headers, {LiveRoom? room}) async {
112113
try {
113114
_loadingSubject.add(true);
114115
if (_player.state != FijkState.idle) {

lib/player/adapters/media_kit_adapter.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import '../models/player_exception.dart';
77
import '../models/player_error_type.dart';
88
import '../interface/unified_player_interface.dart';
99
import 'package:media_kit_video/media_kit_video.dart';
10+
import 'package:pure_live/common/models/live_room.dart';
1011
import 'package:media_kit/media_kit.dart' hide PlayerState;
1112
import 'package:pure_live/common/services/settings_service.dart';
1213

@@ -121,7 +122,7 @@ class MediaKitAdapter implements UnifiedPlayer {
121122
// =========================
122123

123124
@override
124-
Future<void> setDataSource(String url, List<String> playUrls, Map<String, String> headers) async {
125+
Future<void> setDataSource(String url, List<String> playUrls, Map<String, String> headers, {LiveRoom? room}) async {
125126
if (_disposed) return;
126127

127128
// 相同地址不重复 open

lib/player/adapters/video_player_adapter.dart

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ import 'dart:async';
22
import 'package:get/get.dart';
33
import 'package:rxdart/rxdart.dart';
44
import '../models/player_state.dart';
5-
import 'package:flutter/material.dart';
65
import '../models/player_exception.dart';
76
import '../models/player_error_type.dart';
87
import '../core/player_error_dispatcher.dart';
98
import '../interface/unified_player_interface.dart';
109
import 'package:better_player_plus/better_player_plus.dart';
11-
import 'package:pure_live/common/services/settings_service.dart';
10+
import 'package:pure_live/common/index.dart' hide PlayerState;
1211

1312
class BetterPlayerAdapter implements UnifiedPlayer {
1413
BetterPlayerController? _controller;
@@ -30,21 +29,11 @@ class BetterPlayerAdapter implements UnifiedPlayer {
3029
BetterPlayerConfiguration betterPlayerConfiguration = BetterPlayerConfiguration(
3130
autoPlay: true,
3231
fit: BoxFit.contain,
33-
handleLifecycle: true,
32+
handleLifecycle: false,
3433
fullScreenByDefault: false,
3534
autoDispose: false,
3635
looping: false,
3736
controlsConfiguration: BetterPlayerControlsConfiguration(showControls: false),
38-
playerVisibilityChangedBehavior: (double visibility) {
39-
final SettingsService settingsService = Get.find<SettingsService>();
40-
if (visibility == 0.0) {
41-
if (!settingsService.enableBackgroundPlay.value) {
42-
pause();
43-
}
44-
} else {
45-
play();
46-
}
47-
},
4837
);
4938

5039
_controller = BetterPlayerController(betterPlayerConfiguration);
@@ -56,6 +45,15 @@ class BetterPlayerAdapter implements UnifiedPlayer {
5645
void _bindListeners() {
5746
_controller!.addEventsListener((BetterPlayerEvent event) {
5847
switch (event.betterPlayerEventType) {
48+
case BetterPlayerEventType.initialized:
49+
case BetterPlayerEventType.changedResolution:
50+
final size = _controller?.videoPlayerController?.value.size;
51+
if (size != null && size.width > 0) {
52+
_widthSubject.add(size.width.toInt());
53+
_heightSubject.add(size.height.toInt());
54+
}
55+
break;
56+
5957
case BetterPlayerEventType.play:
6058
_playingSubject.add(true);
6159
_stateSubject.add(PlayerState.playing);
@@ -70,6 +68,9 @@ class BetterPlayerAdapter implements UnifiedPlayer {
7068
break;
7169
case BetterPlayerEventType.bufferingEnd:
7270
_loadingSubject.add(false);
71+
if (_playingSubject.value) {
72+
_stateSubject.add(PlayerState.playing);
73+
}
7374
break;
7475
case BetterPlayerEventType.finished:
7576
_completeSubject.add(true);
@@ -90,14 +91,27 @@ class BetterPlayerAdapter implements UnifiedPlayer {
9091
}
9192

9293
@override
93-
Future<void> setDataSource(String url, List<String> playUrls, Map<String, String> headers) async {
94+
Future<void> setDataSource(String url, List<String> playUrls, Map<String, String> headers, {LiveRoom? room}) async {
9495
try {
9596
_loadingSubject.add(true);
96-
97+
_widthSubject.add(null);
98+
_heightSubject.add(null);
99+
_completeSubject.add(false);
97100
BetterPlayerDataSource dataSource = BetterPlayerDataSource(
98101
BetterPlayerDataSourceType.network,
99102
url,
100103
headers: headers,
104+
liveStream: true,
105+
notificationConfiguration: room != null
106+
? BetterPlayerNotificationConfiguration(
107+
showNotification: true,
108+
title: room.nick ?? "",
109+
author: room.title ?? "",
110+
imageUrl: room.cover,
111+
notificationChannelName: "VideoPlayer",
112+
activityName: "MainActivity",
113+
)
114+
: const BetterPlayerNotificationConfiguration(showNotification: false),
101115
);
102116

103117
await _controller!.setupDataSource(dataSource);

0 commit comments

Comments
 (0)