opt: cache image (#1787)

This commit is contained in:
My-Responsitories
2025-12-22 10:43:32 +08:00
committed by GitHub
parent 952d168022
commit d80324655e
5 changed files with 45 additions and 57 deletions

View File

@@ -124,12 +124,10 @@ class _CachedNetworkSVGImageState extends State<CachedNetworkSVGImage> {
Future<void> _loadImage() async { Future<void> _loadImage() async {
try { try {
var file = (await widget._cacheManager.getFileFromCache(_cacheKey))?.file; final file = await widget._cacheManager.getSingleFile(
file ??= await widget._cacheManager.getSingleFile(
widget._url, widget._url,
key: _cacheKey, key: _cacheKey,
headers: widget._headers ?? {}, headers: widget._headers ?? const {},
); );
final svg = await file.readAsString(); final svg = await file.readAsString();
_svgString = svg; _svgString = svg;

View File

@@ -1779,7 +1779,7 @@ class PlPlayerController {
); );
} }
Map<String, WeakReference<ui.Image>>? previewCache; final Map<String, ui.Image?> previewCache = {};
LoadingState<VideoShotData>? videoShot; LoadingState<VideoShotData>? videoShot;
late final RxBool showPreview = false.obs; late final RxBool showPreview = false.obs;
late final showSeekPreview = Pref.showSeekPreview; late final showSeekPreview = Pref.showSeekPreview;
@@ -1807,14 +1807,10 @@ class PlPlayerController {
showPreview.value = false; showPreview.value = false;
previewIndex.value = null; previewIndex.value = null;
videoShot = null; videoShot = null;
previewCache for (var i in previewCache.values) {
?..forEach((_, ref) { i?.dispose();
try { }
ref.target?.dispose(); previewCache.clear();
} catch (_) {}
})
..clear();
previewCache = null;
} }
Future<void> getVideoShot() async { Future<void> getVideoShot() async {

View File

@@ -12,7 +12,6 @@ import 'package:PiliPlus/common/widgets/pair.dart';
import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.dart'; import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.dart';
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart'; import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
import 'package:PiliPlus/common/widgets/view_safe_area.dart'; import 'package:PiliPlus/common/widgets/view_safe_area.dart';
import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/models/common/sponsor_block/action_type.dart'; import 'package:PiliPlus/models/common/sponsor_block/action_type.dart';
import 'package:PiliPlus/models/common/sponsor_block/post_segment_model.dart'; import 'package:PiliPlus/models/common/sponsor_block/post_segment_model.dart';
import 'package:PiliPlus/models/common/sponsor_block/segment_type.dart'; import 'package:PiliPlus/models/common/sponsor_block/segment_type.dart';
@@ -23,7 +22,6 @@ import 'package:PiliPlus/models_new/video/video_detail/episode.dart' as ugc;
import 'package:PiliPlus/models_new/video/video_detail/episode.dart'; import 'package:PiliPlus/models_new/video/video_detail/episode.dart';
import 'package:PiliPlus/models_new/video/video_detail/section.dart'; import 'package:PiliPlus/models_new/video/video_detail/section.dart';
import 'package:PiliPlus/models_new/video/video_detail/ugc_season.dart'; import 'package:PiliPlus/models_new/video/video_detail/ugc_season.dart';
import 'package:PiliPlus/models_new/video/video_shot/data.dart';
import 'package:PiliPlus/pages/common/common_intro_controller.dart'; import 'package:PiliPlus/pages/common/common_intro_controller.dart';
import 'package:PiliPlus/pages/danmaku/danmaku_model.dart'; import 'package:PiliPlus/pages/danmaku/danmaku_model.dart';
import 'package:PiliPlus/pages/live_room/widgets/bottom_control.dart' import 'package:PiliPlus/pages/live_room/widgets/bottom_control.dart'
@@ -59,7 +57,6 @@ import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:canvas_danmaku/canvas_danmaku.dart'; import 'package:canvas_danmaku/canvas_danmaku.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:dio/dio.dart';
import 'package:easy_debounce/easy_throttle.dart'; import 'package:easy_debounce/easy_throttle.dart';
import 'package:fl_chart/fl_chart.dart'; import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@@ -2548,7 +2545,7 @@ Widget buildSeekPreviewWidget(
} }
try { try {
VideoShotData data = plPlayerController.videoShot!.data; final data = plPlayerController.videoShot!.data;
final double scale = final double scale =
plPlayerController.isFullScreen.value && plPlayerController.isFullScreen.value &&
@@ -2590,10 +2587,7 @@ Widget buildSeekPreviewWidget(
imgXSize: imgXSize, imgXSize: imgXSize,
imgYSize: imgYSize, imgYSize: imgYSize,
height: height, height: height,
image: plPlayerController.previewCache?[url]?.target, imageCache: plPlayerController.previewCache,
onCacheImg: (img) =>
(plPlayerController.previewCache ??= {})[url] ??=
WeakReference(img),
onSetSize: (xSize, ySize) => data onSetSize: (xSize, ySize) => data
..imgXSize = imgXSize = xSize ..imgXSize = imgXSize = xSize
..imgYSize = imgYSize = ySize, ..imgYSize = imgYSize = ySize,
@@ -2603,7 +2597,7 @@ Widget buildSeekPreviewWidget(
), ),
); );
} catch (e) { } catch (e) {
if (kDebugMode) debugPrint('seek preview: $e'); if (kDebugMode) rethrow;
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
}, },
@@ -2613,25 +2607,23 @@ Widget buildSeekPreviewWidget(
class VideoShotImage extends StatefulWidget { class VideoShotImage extends StatefulWidget {
const VideoShotImage({ const VideoShotImage({
super.key, super.key,
this.image, required this.imageCache,
required this.url, required this.url,
required this.x, required this.x,
required this.y, required this.y,
required this.imgXSize, required this.imgXSize,
required this.imgYSize, required this.imgYSize,
required this.height, required this.height,
required this.onCacheImg,
required this.onSetSize, required this.onSetSize,
}); });
final ui.Image? image; final Map<String, ui.Image?> imageCache;
final String url; final String url;
final int x; final int x;
final int y; final int y;
final double imgXSize; final double imgXSize;
final double imgYSize; final double imgYSize;
final double height; final double height;
final ValueChanged<ui.Image> onCacheImg;
final Function(double imgXSize, double imgYSize) onSetSize; final Function(double imgXSize, double imgYSize) onSetSize;
@override @override
@@ -2641,26 +2633,22 @@ class VideoShotImage extends StatefulWidget {
Future<ui.Image?> _getImg(String url) async { Future<ui.Image?> _getImg(String url) async {
final cacheManager = DefaultCacheManager(); final cacheManager = DefaultCacheManager();
final cacheKey = Utils.getFileName(url, fileExt: false); final cacheKey = Utils.getFileName(url, fileExt: false);
final fileInfo = await cacheManager.getFileFromCache(cacheKey); try {
if (fileInfo != null) { final fileInfo = await cacheManager.getSingleFile(
final bytes = await fileInfo.file.readAsBytes();
return _loadImg(bytes);
} else {
final res = await Request().get<Uint8List>(
url, url,
options: Options(responseType: ResponseType.bytes), key: cacheKey,
headers: Constants.baseHeaders,
); );
if (res.statusCode == 200) { return _loadImg(fileInfo.path);
final Uint8List data = res.data; } catch (_) {
cacheManager.putFile(cacheKey, data, fileExtension: 'jpg');
return _loadImg(data);
}
}
return null; return null;
} }
}
Future<ui.Image?> _loadImg(Uint8List bytes) async { Future<ui.Image?> _loadImg(String path) async {
final codec = await ui.instantiateImageCodec(bytes); final codec = await ui.instantiateImageCodecFromBuffer(
await ImmutableBuffer.fromFilePath(path),
);
final frame = await codec.getNextFrame(); final frame = await codec.getNextFrame();
codec.dispose(); codec.dispose();
return frame.image; return frame.image;
@@ -2710,19 +2698,25 @@ class _VideoShotImageState extends State<VideoShotImage> {
_rrect = RRect.fromRectAndRadius(_dstRect, const Radius.circular(10)); _rrect = RRect.fromRectAndRadius(_dstRect, const Radius.circular(10));
} }
Future<void> _loadImg() async { void _loadImg() {
_image = widget.image; final url = widget.url;
_image = widget.imageCache[url];
if (_image != null) { if (_image != null) {
_initSizeIfNeeded(); _initSizeIfNeeded();
setState(() {}); } else if (!widget.imageCache.containsKey(url)) {
} else { widget.imageCache[url] = null;
final image = await _getImg(widget.url); _getImg(url).then((image) {
if (mounted && image != null) { if (image != null) {
widget.imageCache[url] = image;
if (mounted) {
_image = image; _image = image;
widget.onCacheImg(image);
_initSizeIfNeeded(); _initSizeIfNeeded();
setState(() {}); setState(() {});
} }
} else {
widget.imageCache.remove(url);
}
});
} }
} }
@@ -2821,7 +2815,7 @@ Widget buildViewPointWidget(
} }
// if (kDebugMode) debugPrint('${item.title},,${item.from}'); // if (kDebugMode) debugPrint('${item.title},,${item.from}');
} catch (e) { } catch (e) {
if (kDebugMode) debugPrint('$e'); if (kDebugMode) rethrow;
} }
}, },
), ),

View File

@@ -894,13 +894,13 @@ packages:
source: hosted source: hosted
version: "4.1.2" version: "4.1.2"
image: image:
dependency: "direct main" dependency: transitive
description: description:
name: image name: image
sha256: "51555e36056541237b15b57afc31a0f53d4f9aefd9bd00873a6dc0090e54e332" sha256: "48c11d0943b93b6fb29103d956ff89aafeae48f6058a3939649be2093dcff0bf"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.6.0" version: "4.7.1"
image_cropper: image_cropper:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -207,7 +207,7 @@ dependencies:
ref: master ref: master
crclib: ^3.0.0 crclib: ^3.0.0
web_socket_channel: ^3.0.3 web_socket_channel: ^3.0.3
image: ^4.5.4 # image: ^4.7.1
# window_manager: ^0.5.1 # window_manager: ^0.5.1
window_manager: window_manager:
git: git: