fix(video): iOS video zoom
This commit is contained in:
@@ -789,7 +789,7 @@
|
||||
repositoryURL = "https://github.com/edde746/MPVKit";
|
||||
requirement = {
|
||||
kind = revision;
|
||||
revision = 6f711b36920b37d22e81353dda5a7df7965b1a44;
|
||||
revision = 60266433556169cf5529a81cc603524ed3e4bec1;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/edde746/MPVKit",
|
||||
"state" : {
|
||||
"revision" : "6f711b36920b37d22e81353dda5a7df7965b1a44"
|
||||
"revision" : "60266433556169cf5529a81cc603524ed3e4bec1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/edde746/MPVKit",
|
||||
"state" : {
|
||||
"revision" : "6f711b36920b37d22e81353dda5a7df7965b1a44"
|
||||
"revision" : "60266433556169cf5529a81cc603524ed3e4bec1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -78,14 +78,22 @@ class VideoFilterManager {
|
||||
|
||||
Size? get playerSize => _playerSize;
|
||||
|
||||
static double videoZoomPropertyForScale(double scale) {
|
||||
static double normalizeZoomScale(double scale) {
|
||||
final clamped = scale.clamp(minZoomScale, maxZoomScale).toDouble();
|
||||
return math.log(clamped) / math.ln2;
|
||||
final percent = (clamped * 100).round();
|
||||
if (percent == 100) return 1.0;
|
||||
return percent / 100;
|
||||
}
|
||||
|
||||
static double videoZoomPropertyForScale(double scale) {
|
||||
final normalized = normalizeZoomScale(scale);
|
||||
if (normalized == 1.0) return 0.0;
|
||||
return math.log(normalized) / math.ln2;
|
||||
}
|
||||
|
||||
double setZoomScale(double scale) {
|
||||
final next = scale.clamp(minZoomScale, maxZoomScale).toDouble();
|
||||
if ((_zoomScale - next).abs() < 0.0001) return _zoomScale;
|
||||
final next = normalizeZoomScale(scale);
|
||||
if (_zoomScale == next) return _zoomScale;
|
||||
_zoomScale = next;
|
||||
updateVideoFilter();
|
||||
return _zoomScale;
|
||||
@@ -140,7 +148,7 @@ class VideoFilterManager {
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if (_prePipZoomScale != null) {
|
||||
_zoomScale = _prePipZoomScale!;
|
||||
_zoomScale = normalizeZoomScale(_prePipZoomScale!);
|
||||
_prePipZoomScale = null;
|
||||
shouldUpdate = true;
|
||||
}
|
||||
|
||||
@@ -215,15 +215,16 @@ class _VideoSettingsSheetState extends State<VideoSettingsSheet> {
|
||||
super.initState();
|
||||
_audioSyncOffset = widget.audioSyncOffset;
|
||||
_subtitleSyncOffset = widget.subtitleSyncOffset;
|
||||
_zoomScale = widget.videoZoomScale;
|
||||
_zoomScale = VideoFilterManager.normalizeZoomScale(widget.videoZoomScale);
|
||||
_loadDebugDvConversionMode();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant VideoSettingsSheet oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if ((widget.videoZoomScale - oldWidget.videoZoomScale).abs() > 0.0001) {
|
||||
_zoomScale = widget.videoZoomScale;
|
||||
final nextZoomScale = VideoFilterManager.normalizeZoomScale(widget.videoZoomScale);
|
||||
if (_zoomScale != nextZoomScale) {
|
||||
_zoomScale = nextZoomScale;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,7 +393,7 @@ class _VideoSettingsSheetState extends State<VideoSettingsSheet> {
|
||||
String _formatZoomScale(double scale) => '${(scale * 100).round()}%';
|
||||
|
||||
void _setZoomScale(double scale) {
|
||||
final next = scale.clamp(VideoFilterManager.minZoomScale, VideoFilterManager.maxZoomScale).toDouble();
|
||||
final next = VideoFilterManager.normalizeZoomScale(scale);
|
||||
setState(() {
|
||||
_zoomScale = next;
|
||||
});
|
||||
|
||||
@@ -4,6 +4,48 @@ import 'package:plezy/mpv/mpv.dart';
|
||||
import 'package:plezy/services/video_filter_manager.dart';
|
||||
|
||||
void main() {
|
||||
test('zoom scale snaps to whole percentages', () {
|
||||
final player = _RecordingPlayer();
|
||||
final manager = VideoFilterManager(player: player, availableVersions: const [], selectedMediaIndex: 0);
|
||||
addTearDown(manager.dispose);
|
||||
|
||||
expect(manager.setZoomScale(1.234), 1.23);
|
||||
expect(manager.zoomScale, 1.23);
|
||||
|
||||
expect(manager.adjustZoom(VideoFilterManager.zoomStep), 1.24);
|
||||
expect(manager.zoomScale, 1.24);
|
||||
});
|
||||
|
||||
test('zoom scale snaps near 100 percent to exact default', () {
|
||||
final player = _RecordingPlayer();
|
||||
final manager = VideoFilterManager(player: player, availableVersions: const [], selectedMediaIndex: 0);
|
||||
addTearDown(manager.dispose);
|
||||
|
||||
manager.setZoomScale(1.5);
|
||||
|
||||
expect(manager.setZoomScale(1.00008), 1.0);
|
||||
expect(manager.zoomScale, 1.0);
|
||||
expect(manager.resetZoom(), 1.0);
|
||||
});
|
||||
|
||||
test('video zoom property is exact zero at normalized default', () async {
|
||||
final player = _RecordingPlayer();
|
||||
final manager = VideoFilterManager(player: player, availableVersions: const [], selectedMediaIndex: 0);
|
||||
addTearDown(manager.dispose);
|
||||
|
||||
expect(VideoFilterManager.videoZoomPropertyForScale(1.00008), 0.0);
|
||||
|
||||
manager.setZoomScale(1.00008);
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
player.writes.clear();
|
||||
|
||||
await manager.updateVideoFilter();
|
||||
|
||||
final zoomWrites = player.writes.where((write) => write.key == 'video-zoom').toList();
|
||||
expect(zoomWrites, isNotEmpty);
|
||||
expect(zoomWrites.last.value, '0.0');
|
||||
});
|
||||
|
||||
test('stretch mode applies the initial player size before a resize event', () async {
|
||||
final player = _RecordingPlayer();
|
||||
final manager = VideoFilterManager(
|
||||
|
||||
Reference in New Issue
Block a user