* tweak

* opt: image quality

* opt: VideoPlayerServiceHandler

* fixes

* update

Signed-off-by: dom <githubaccount56556@proton.me>

* fix get file name

Signed-off-by: dom <githubaccount56556@proton.me>

---------

Co-authored-by: dom <githubaccount56556@proton.me>
This commit is contained in:
My-Responsitories
2026-01-25 15:21:33 +08:00
committed by GitHub
parent 219228f8b5
commit 038f03a4e7
10 changed files with 64 additions and 49 deletions

View File

@@ -22,8 +22,6 @@ class DisabledIcon<T extends Widget> extends SingleChildRenderObjectWidget {
final StrokeCap strokeCap;
final double lineLengthScale;
T enable() => child as T;
@override
RenderObject createRenderObject(BuildContext context) {
late final iconTheme = IconTheme.of(context);
@@ -31,12 +29,12 @@ class DisabledIcon<T extends Widget> extends SingleChildRenderObjectWidget {
disable: disable,
iconSize:
iconSize ??
(child is Icon ? (child as Icon?)?.size : null) ??
(child is Icon ? (child as Icon).size : null) ??
iconTheme.size ??
24.0,
color:
color ??
(child is Icon ? (child as Icon?)?.color : null) ??
(child is Icon ? (child as Icon).color : null) ??
iconTheme.color!,
strokeCap: strokeCap,
lineLengthScale: lineLengthScale,

View File

@@ -15,7 +15,7 @@ class NetworkImgLayer extends StatelessWidget {
this.type = .def,
this.fadeOutDuration = const Duration(milliseconds: 120),
this.fadeInDuration = const Duration(milliseconds: 120),
this.quality,
this.quality = 1,
this.borderRadius = StyleString.mdRadius,
this.getPlaceHolder,
this.fit = .cover,
@@ -29,7 +29,7 @@ class NetworkImgLayer extends StatelessWidget {
final ImageType type;
final Duration fadeOutDuration;
final Duration fadeInDuration;
final int? quality;
final int quality;
final BorderRadius borderRadius;
final ValueGetter<Widget>? getPlaceHolder;
final BoxFit fit;

View File

@@ -152,7 +152,7 @@ class _LiveEmotePanelState extends State<LiveEmotePanel>
width: width,
height: height,
type: ImageType.emote,
quality: item.pkgType == 3 ? null : 80,
quality: item.pkgType == 3 ? 1 : 80,
),
),
),

View File

@@ -79,9 +79,7 @@ class _RcmdPageState extends CommonPageState<RcmdPage, RcmdController>
child: Card(
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(
horizontal: 10,
),
padding: const .symmetric(horizontal: 10),
child: Text(
'上次看到这里\n点击刷新',
textAlign: .center,
@@ -95,9 +93,7 @@ class _RcmdPageState extends CommonPageState<RcmdPage, RcmdController>
),
);
}
int actualIndex = controller.lastRefreshAt == null
? index
: index > controller.lastRefreshAt!
final actualIndex = index > controller.lastRefreshAt!
? index - 1
: index;
return VideoCardV(

View File

@@ -205,8 +205,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
}
}
void playCallBack() {
plPlayerController?.play();
Future<void>? playCallBack() {
return plPlayerController?.play();
}
// 播放器状态监听

View File

@@ -496,15 +496,15 @@ class PlPlayerController {
return _instance != null;
}
static void setPlayCallBack(VoidCallback? playCallBack) {
static void setPlayCallBack(Future<void>? Function()? playCallBack) {
_playCallBack = playCallBack;
}
static VoidCallback? _playCallBack;
static Future<void>? Function()? _playCallBack;
static void playIfExists() {
static Future<void>? playIfExists() {
// await _instance?.play(repeat: repeat, hideControls: hideControls);
_playCallBack?.call();
return _playCallBack?.call();
}
// try to get PlayerStatus
@@ -819,7 +819,7 @@ class PlPlayerController {
}
// 音轨
late final String audioUri;
final String audioUri;
if (isFileSource) {
audioUri = onlyPlayAudio.value || mediaType == 1
? ''
@@ -969,9 +969,9 @@ class PlPlayerController {
}
late final bool enableAutoEnter = Pref.enableAutoEnter;
Future<void> autoEnterFullscreen() async {
Future<void>? autoEnterFullscreen() {
if (enableAutoEnter) {
Future.delayed(const Duration(milliseconds: 500), () {
return Future.delayed(const Duration(milliseconds: 500), () {
if (dataStatus.status.value != DataStatus.loaded) {
_stopListenerForEnterFullScreen();
_dataListenerForEnterFullScreen = dataStatus.status.listen((status) {
@@ -981,10 +981,11 @@ class PlPlayerController {
}
});
} else {
triggerFullScreen(status: true);
return triggerFullScreen(status: true);
}
});
}
return null;
}
Set<StreamSubscription> subscriptions = {};

View File

@@ -2601,7 +2601,7 @@ Future<ui.Image?> _getImg(String url) async {
final cacheKey = Utils.getFileName(url, fileExt: false);
try {
final fileInfo = await cacheManager.getSingleFile(
url,
ImageUtils.safeThumbnailUrl(url),
key: cacheKey,
headers: Constants.baseHeaders,
);

View File

@@ -1,3 +1,5 @@
import 'dart:io' show File;
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/grpc/bilibili/app/listener/v1.pb.dart' show DetailItem;
import 'package:PiliPlus/models_new/download/bili_download_entry_info.dart';
@@ -8,8 +10,11 @@ import 'package:PiliPlus/models_new/video/video_detail/page.dart';
import 'package:PiliPlus/plugin/pl_player/controller.dart';
import 'package:PiliPlus/plugin/pl_player/models/play_status.dart';
import 'package:PiliPlus/utils/extension/iterable_ext.dart';
import 'package:PiliPlus/utils/image_utils.dart';
import 'package:PiliPlus/utils/path_utils.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:audio_service/audio_service.dart';
import 'package:path/path.dart' as path;
Future<VideoPlayerServiceHandler> initAudioService() {
return AudioService.init(
@@ -31,35 +36,37 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
static final List<MediaItem> _item = [];
bool enableBackgroundPlay = Pref.enableBackgroundPlay;
Function? onPlay;
Function? onPause;
Function(Duration position)? onSeek;
Future<void> Function()? onPlay;
Future<void> Function()? onPause;
Future<void> Function(Duration position)? onSeek;
@override
Future<void> play() async {
onPlay?.call() ?? PlPlayerController.playIfExists();
Future<void> play() {
return onPlay?.call() ??
PlPlayerController.playIfExists() ??
Future.syncValue(null);
// player.play();
}
@override
Future<void> pause() async {
await (onPause?.call() ?? PlPlayerController.pauseIfExists());
Future<void> pause() {
return onPause?.call() ?? PlPlayerController.pauseIfExists();
// player.pause();
}
@override
Future<void> seek(Duration position) async {
Future<void> seek(Duration position) {
playbackState.add(
playbackState.value.copyWith(
updatePosition: position,
),
);
await (onSeek?.call(position) ??
return (onSeek?.call(position) ??
PlPlayerController.seekToIfExists(position, isSeek: false));
// await player.seekTo(position);
}
Future<void> setMediaItem(MediaItem newMediaItem) async {
void setMediaItem(MediaItem newMediaItem) {
if (!enableBackgroundPlay) return;
// if (kDebugMode) {
// debugPrint("此时调用栈为:");
@@ -70,11 +77,11 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
if (!mediaItem.isClosed) mediaItem.add(newMediaItem);
}
Future<void> setPlaybackState(
void setPlaybackState(
PlayerStatus status,
bool isBuffering,
bool isLive,
) async {
) {
if (!enableBackgroundPlay ||
_item.isEmpty ||
!PlPlayerController.instanceExists()) {
@@ -137,6 +144,8 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
if (!PlPlayerController.instanceExists()) return;
if (data == null) return;
Uri getUri(String? cover) => Uri.parse(ImageUtils.safeThumbnailUrl(cover));
late final id = '$cid$herotag';
MediaItem? mediaItem;
if (data is VideoDetailData) {
@@ -149,7 +158,7 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
title: current?.part ?? '',
artist: data.owner?.name,
duration: Duration(seconds: current?.duration ?? 0),
artUri: Uri.parse(data.pic ?? ''),
artUri: getUri(data.pic),
);
} else {
mediaItem = MediaItem(
@@ -157,7 +166,7 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
title: data.title ?? '',
artist: data.owner?.name,
duration: Duration(seconds: data.duration ?? 0),
artUri: Uri.parse(data.pic ?? ''),
artUri: getUri(data.pic),
);
}
} else if (data is EpisodeItem) {
@@ -168,14 +177,14 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
duration: data.from == 'pugv'
? Duration(seconds: data.duration ?? 0)
: Duration(milliseconds: data.duration ?? 0),
artUri: Uri.parse(data.cover ?? ''),
artUri: getUri(data.cover),
);
} else if (data is RoomInfoH5Data) {
mediaItem = MediaItem(
id: id,
title: data.roomInfo?.title ?? '',
artist: data.anchorInfo?.baseInfo?.uname,
artUri: Uri.parse(data.roomInfo?.cover ?? ''),
artUri: getUri(data.roomInfo?.cover),
isLive: true,
);
} else if (data is Part) {
@@ -184,7 +193,7 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
title: data.part ?? '',
artist: artist,
duration: Duration(seconds: data.duration ?? 0),
artUri: Uri.parse(cover ?? ''),
artUri: getUri(cover),
);
} else if (data is DetailItem) {
mediaItem = MediaItem(
@@ -192,15 +201,19 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
title: data.arc.title,
artist: data.owner.name,
duration: Duration(seconds: data.arc.duration.toInt()),
artUri: Uri.parse(data.arc.cover),
artUri: getUri(data.arc.cover),
);
} else if (data is BiliDownloadEntryInfo) {
final coverFile = File(path.join(data.entryDirPath, PathUtils.coverName));
final uri = coverFile.existsSync()
? coverFile.absolute.uri
: getUri(data.cover);
mediaItem = MediaItem(
id: id,
title: data.showTitle,
artist: data.ownerName,
duration: Duration(milliseconds: data.totalTimeMilli),
artUri: Uri.parse(data.cover),
artUri: uri,
);
}
if (mediaItem == null) return;

View File

@@ -1,4 +1,5 @@
import 'dart:io';
import 'dart:math' as math;
import 'dart:typed_data';
import 'package:PiliPlus/common/constants.dart';
@@ -267,22 +268,23 @@ abstract final class ImageUtils {
r'(@(\d+[a-z]_?)*)(\..*)?$',
caseSensitive: false,
);
static String thumbnailUrl(String? src, [int? quality]) {
if (src != null && quality != 100) {
static String thumbnailUrl(String? src, [int maxQuality = 1]) {
if (src != null && maxQuality != 100) {
maxQuality = math.max(maxQuality, GlobalData().imgQuality);
bool hasMatch = false;
src = src.splitMapJoin(
_thumbRegex,
onMatch: (Match match) {
onMatch: (match) {
hasMatch = true;
String suffix = match.group(3) ?? '.webp';
return '${match.group(1)}_${quality ?? GlobalData().imgQuality}q$suffix';
return '${match.group(1)}_${maxQuality}q$suffix';
},
onNonMatch: (String str) {
return str;
},
);
if (!hasMatch) {
src += '@${quality ?? GlobalData().imgQuality}q.webp';
src += '@${maxQuality}q.webp';
}
}
return src.http2https;

View File

@@ -162,9 +162,14 @@ abstract final class Utils {
return randomBase64.substring(0, randomBase64.length - 2);
}
static int _getExt(String uri) {
final i = uri.indexOf('?');
return i == -1 ? uri.length : i;
}
static String getFileName(String uri, {bool fileExt = true}) {
final i0 = uri.lastIndexOf('/') + 1;
final i1 = fileExt ? uri.length : uri.lastIndexOf('.');
final i1 = fileExt ? _getExt(uri) : uri.lastIndexOf('.');
return uri.substring(i0, i1);
}