mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-04-20 03:06:59 +08:00
tweaks (#1810)
* 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:
committed by
GitHub
parent
219228f8b5
commit
038f03a4e7
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -205,8 +205,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
}
|
||||
}
|
||||
|
||||
void playCallBack() {
|
||||
plPlayerController?.play();
|
||||
Future<void>? playCallBack() {
|
||||
return plPlayerController?.play();
|
||||
}
|
||||
|
||||
// 播放器状态监听
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user