opt: PlPlayerController (#1832)

* opt: audio uri

* opt: PlPlayerController
This commit is contained in:
My-Responsitories
2026-02-10 16:33:02 +08:00
committed by GitHub
parent ed2bd069ee
commit 9411785d26
6 changed files with 91 additions and 132 deletions

View File

@@ -57,7 +57,7 @@ class _PlDanmakuState extends State<PlDanmaku> {
} else { } else {
_plDanmakuController.queryDanmaku( _plDanmakuController.queryDanmaku(
PlDanmakuController.calcSegment( PlDanmakuController.calcSegment(
playerController.position.value.inMilliseconds, playerController.position.inMilliseconds,
), ),
); );
} }

View File

@@ -499,8 +499,7 @@ class VideoDetailController extends GetxController
bool get preInitPlayer => plPlayerController.preInitPlayer; bool get preInitPlayer => plPlayerController.preInitPlayer;
@override @override
int get currPosInMilliseconds => int get currPosInMilliseconds =>
defaultST?.inMilliseconds ?? defaultST?.inMilliseconds ?? plPlayerController.position.inMilliseconds;
plPlayerController.position.value.inMilliseconds;
@override @override
Future<void> seekTo(Duration duration, {required bool isSeek}) => Future<void> seekTo(Duration duration, {required bool isSeek}) =>
plPlayerController.seekTo(duration, isSeek: isSeek); plPlayerController.seekTo(duration, isSeek: isSeek);
@@ -583,7 +582,7 @@ class VideoDetailController extends GetxController
return SendDanmakuPanel( return SendDanmakuPanel(
cid: cid.value, cid: cid.value,
bvid: bvid, bvid: bvid,
progress: plPlayerController.position.value.inMilliseconds, progress: plPlayerController.position.inMilliseconds,
initialValue: savedDanmaku, initialValue: savedDanmaku,
onSave: (danmaku) => savedDanmaku = danmaku, onSave: (danmaku) => savedDanmaku = danmaku,
onSuccess: (danmakuModel) { onSuccess: (danmakuModel) {
@@ -634,7 +633,7 @@ class VideoDetailController extends GetxController
final currentVideoQa = this.currentVideoQa.value; final currentVideoQa = this.currentVideoQa.value;
if (currentVideoQa == null) return; if (currentVideoQa == null) return;
_autoPlay.value = true; _autoPlay.value = true;
playedTime = plPlayerController.position.value; playedTime = plPlayerController.position;
plPlayerController plPlayerController
..removeListeners() ..removeListeners()
..isBuffering.value = false ..isBuffering.value = false
@@ -960,7 +959,7 @@ class VideoDetailController extends GetxController
PostSegmentModel( PostSegmentModel(
segment: Pair( segment: Pair(
first: 0, first: 0,
second: plPlayerController.position.value.inMilliseconds / 1000, second: plPlayerController.position.inMilliseconds / 1000,
), ),
category: SegmentType.sponsor, category: SegmentType.sponsor,
actionType: ActionType.skip, actionType: ActionType.skip,
@@ -1177,7 +1176,7 @@ class VideoDetailController extends GetxController
? -1 ? -1
: playedTime!.inSeconds : playedTime!.inSeconds
: playedTime!.inSeconds, : playedTime!.inSeconds,
type: HeartBeatType.status, type: HeartBeatType.completed,
isManual: true, isManual: true,
aid: aid, aid: aid,
bvid: bvid, bvid: bvid,

View File

@@ -184,10 +184,9 @@ class _PostPanelState extends State<PostPanel>
late final List<PostSegmentModel> list = videoDetailController.postList; late final List<PostSegmentModel> list = videoDetailController.postList;
late final double videoDuration = late final double videoDuration =
plPlayerController.durationSeconds.value.inMilliseconds / 1000; plPlayerController.duration.value.inMilliseconds / 1000;
double get currentPos => double currentPos() => plPlayerController.position.inMilliseconds / 1000;
plPlayerController.position.value.inMilliseconds / 1000;
@override @override
Widget buildPage(ThemeData theme) { Widget buildPage(ThemeData theme) {
@@ -211,7 +210,7 @@ class _PostPanelState extends State<PostPanel>
PostSegmentModel( PostSegmentModel(
segment: Pair( segment: Pair(
first: 0, first: 0,
second: currentPos, second: currentPos(),
), ),
category: SegmentType.sponsor, category: SegmentType.sponsor,
actionType: ActionType.skip, actionType: ActionType.skip,
@@ -350,7 +349,7 @@ class _PostPanelState extends State<PostPanel>
PostPanel.segmentWidget( PostPanel.segmentWidget(
theme, theme,
item: item, item: item,
currentPos: () => currentPos, currentPos: currentPos,
videoDuration: videoDuration, videoDuration: videoDuration,
), ),
Wrap( Wrap(

View File

@@ -83,18 +83,17 @@ class PlPlayerController with BlockConfigMixin {
/// 响应数据 /// 响应数据
/// 带有Seconds的变量只在秒数更新时更新以避免频繁触发重绘 /// 带有Seconds的变量只在秒数更新时更新以避免频繁触发重绘
// 播放位置 // 播放位置
final Rx<Duration> position = Rx(Duration.zero); Duration position = Duration.zero;
final RxInt positionSeconds = 0.obs; final RxInt positionSeconds = 0.obs;
/// 进度条位置 /// 进度条位置
final Rx<Duration> sliderPosition = Rx(Duration.zero); Duration sliderPosition = Duration.zero;
final RxInt sliderPositionSeconds = 0.obs; final RxInt sliderPositionSeconds = 0.obs;
// 展示使用 // 展示使用
final Rx<Duration> sliderTempPosition = Rx(Duration.zero); final Rx<Duration> sliderTempPosition = Rx(Duration.zero);
/// 视频时长 /// 视频时长
final Rx<Duration> duration = Rx(Duration.zero); final Rx<Duration> duration = Rx(Duration.zero);
final Rx<Duration> durationSeconds = Duration.zero.obs;
/// 视频缓冲 /// 视频缓冲
final Rx<Duration> buffered = Rx(Duration.zero); final Rx<Duration> buffered = Rx(Duration.zero);
@@ -118,9 +117,6 @@ class PlPlayerController with BlockConfigMixin {
/// 是否展示控制条 /// 是否展示控制条
final RxBool showControls = false.obs; final RxBool showControls = false.obs;
/// 音量控制条展示/隐藏
final RxBool showVolumeStatus = false.obs;
/// 亮度控制条展示/隐藏 /// 亮度控制条展示/隐藏
final RxBool showBrightnessStatus = false.obs; final RxBool showBrightnessStatus = false.obs;
@@ -182,7 +178,6 @@ class PlPlayerController with BlockConfigMixin {
Timer? _timer; Timer? _timer;
Timer? _timerForSeek; Timer? _timerForSeek;
Timer? _timerForShowingVolume;
Box setting = GStorage.setting; Box setting = GStorage.setting;
@@ -460,25 +455,19 @@ class PlPlayerController with BlockConfigMixin {
} }
void updateSliderPositionSecond() { void updateSliderPositionSecond() {
int newSecond = sliderPosition.value.inSeconds; int newSecond = sliderPosition.inSeconds;
if (sliderPositionSeconds.value != newSecond) { if (sliderPositionSeconds.value != newSecond) {
sliderPositionSeconds.value = newSecond; sliderPositionSeconds.value = newSecond;
} }
} }
void updatePositionSecond() { void updatePositionSecond() {
int newSecond = position.value.inSeconds; int newSecond = position.inSeconds;
if (positionSeconds.value != newSecond) { if (positionSeconds.value != newSecond) {
positionSeconds.value = newSecond; positionSeconds.value = newSecond;
} }
} }
void updateDurationSecond() {
if (durationSeconds.value != duration.value) {
durationSeconds.value = duration.value;
}
}
void updateBufferedSecond() { void updateBufferedSecond() {
int newSecond = buffered.value.inSeconds; int newSecond = buffered.value.inSeconds;
if (bufferedSeconds.value != newSecond) { if (bufferedSeconds.value != newSecond) {
@@ -653,9 +642,7 @@ class PlPlayerController with BlockConfigMixin {
); );
// 获取视频时长 00:00 // 获取视频时长 00:00
this.duration.value = duration ?? _videoPlayerController!.state.duration; this.duration.value = duration ?? _videoPlayerController!.state.duration;
position.value = buffered.value = sliderPosition.value = position = buffered.value = sliderPosition = seekTo ?? Duration.zero;
seekTo ?? Duration.zero;
updateDurationSecond();
updatePositionSecond(); updatePositionSecond();
updateSliderPositionSecond(); updateSliderPositionSecond();
updateBufferedSecond(); updateBufferedSecond();
@@ -766,7 +753,7 @@ class PlPlayerController with BlockConfigMixin {
isBuffering.value = false; isBuffering.value = false;
buffered.value = Duration.zero; buffered.value = Duration.zero;
_heartDuration = 0; _heartDuration = 0;
position.value = Duration.zero; position = Duration.zero;
// 初始化时清空弹幕,防止上次重叠 // 初始化时清空弹幕,防止上次重叠
danmakuController?.clear(); danmakuController?.clear();
@@ -817,6 +804,8 @@ class PlPlayerController with BlockConfigMixin {
} }
} }
final Map<String, String> extras = {};
// 音轨 // 音轨
final String audioUri; final String audioUri;
if (isFileSource) { if (isFileSource) {
@@ -825,12 +814,12 @@ class PlPlayerController with BlockConfigMixin {
: path.join(dirPath!, typeTag!, PathUtils.audioNameType2); : path.join(dirPath!, typeTag!, PathUtils.audioNameType2);
} else if (dataSource.audioSource?.isNotEmpty == true) { } else if (dataSource.audioSource?.isNotEmpty == true) {
audioUri = Platform.isWindows audioUri = Platform.isWindows
? dataSource.audioSource!.replaceAll(';', '\\;') ? dataSource.audioSource!.replaceAll(';', r'\;')
: dataSource.audioSource!.replaceAll(':', '\\:'); : dataSource.audioSource!.replaceAll(':', r'\:');
} else { } else {
audioUri = ''; audioUri = '';
} }
await pp.setProperty('audio-files', audioUri); if (audioUri.isNotEmpty) extras['audio-files'] = '"$audioUri"';
_videoController ??= VideoController( _videoController ??= VideoController(
player, player,
@@ -843,8 +832,7 @@ class PlPlayerController with BlockConfigMixin {
player.setPlaylistMode(looping); player.setPlaylistMode(looping);
final Map<String, String>? filters; if (kDebugMode || Platform.isAndroid) {
if (Platform.isAndroid) {
String audioNormalization = AudioNormalization.getParamFromConfig( String audioNormalization = AudioNormalization.getParamFromConfig(
Pref.audioNormalization, Pref.audioNormalization,
); );
@@ -867,11 +855,9 @@ class PlPlayerController with BlockConfigMixin {
AudioNormalization.getParamFromConfig(Pref.fallbackNormalization), AudioNormalization.getParamFromConfig(Pref.fallbackNormalization),
); );
} }
filters = audioNormalization.isEmpty if (audioNormalization.isNotEmpty) {
? null extras['lavfi-complex'] = '"[aid1] $audioNormalization [ao]"';
: {'lavfi-complex': '"[aid1] $audioNormalization [ao]"'}; }
} else {
filters = null;
} }
// if (kDebugMode) debugPrint(filters.toString()); // if (kDebugMode) debugPrint(filters.toString());
@@ -895,7 +881,7 @@ class PlPlayerController with BlockConfigMixin {
videoUri, videoUri,
httpHeaders: dataSource.httpHeaders, httpHeaders: dataSource.httpHeaders,
start: seekTo, start: seekTo,
extras: filters, extras: extras.isEmpty ? null : extras,
), ),
play: false, play: false,
); );
@@ -915,23 +901,22 @@ class PlPlayerController with BlockConfigMixin {
SmartDialog.showToast('视频源为空,请重新进入本页面'); SmartDialog.showToast('视频源为空,请重新进入本页面');
return false; return false;
} }
String? audioUri;
if (!isLive) { if (!isLive) {
if (dataSource.audioSource.isNullOrEmpty) { if (dataSource.audioSource.isNullOrEmpty) {
SmartDialog.showToast('音频源为空'); SmartDialog.showToast('音频源为空');
} else { } else {
await (_videoPlayerController!.platform!).setProperty( audioUri = Platform.isWindows
'audio-files', ? dataSource.audioSource!.replaceAll(';', '\\;')
Platform.isWindows : dataSource.audioSource!.replaceAll(':', '\\:');
? dataSource.audioSource!.replaceAll(';', '\\;')
: dataSource.audioSource!.replaceAll(':', '\\:'),
);
} }
} }
await _videoPlayerController!.open( await _videoPlayerController!.open(
Media( Media(
dataSource.videoSource!, dataSource.videoSource!,
httpHeaders: dataSource.httpHeaders, httpHeaders: dataSource.httpHeaders,
start: position.value, start: position,
extras: audioUri == null ? null : {'audio-files': '"$audioUri"'},
), ),
play: true, play: true,
); );
@@ -1038,10 +1023,10 @@ class PlPlayerController with BlockConfigMixin {
makeHeartBeat(positionSeconds.value, type: HeartBeatType.completed); makeHeartBeat(positionSeconds.value, type: HeartBeatType.completed);
}), }),
controllerStream.position.listen((event) { controllerStream.position.listen((event) {
position.value = event; position = event;
updatePositionSecond(); updatePositionSecond();
if (!isSliderMoving.value) { if (!isSliderMoving.value) {
sliderPosition.value = event; sliderPosition = event;
updateSliderPositionSecond(); updateSliderPositionSecond();
} }
@@ -1069,7 +1054,7 @@ class PlPlayerController with BlockConfigMixin {
if (kDebugMode) if (kDebugMode)
controllerStream.log.listen(((PlayerLog log) { controllerStream.log.listen(((PlayerLog log) {
if (log.level == 'error' || log.level == 'fatal') { if (log.level == 'error' || log.level == 'fatal') {
Utils.reportError('${log.prefix}: ${log.text}', null); Utils.reportError('${log.level}: ${log.prefix}: ${log.text}', null);
} else { } else {
debugPrint(log.toString()); debugPrint(log.toString());
} }
@@ -1140,12 +1125,8 @@ class PlPlayerController with BlockConfigMixin {
isLive, isLive,
); );
}), }),
position.listen((Duration event) { positionSeconds.listen((int event) {
EasyThrottle.throttle( videoPlayerServiceHandler!.onPositionChange(Duration(seconds: event));
'mediaServicePosition',
const Duration(seconds: 1),
() => videoPlayerServiceHandler!.onPositionChange(event),
);
}), }),
], ],
}; };
@@ -1167,7 +1148,7 @@ class PlPlayerController with BlockConfigMixin {
if (position < Duration.zero) { if (position < Duration.zero) {
position = Duration.zero; position = Duration.zero;
} }
this.position.value = position; this.position = position;
updatePositionSecond(); updatePositionSecond();
_heartDuration = position.inSeconds; _heartDuration = position.inSeconds;
if (duration.value.inSeconds != 0) { if (duration.value.inSeconds != 0) {
@@ -1194,7 +1175,7 @@ class PlPlayerController with BlockConfigMixin {
if (_playerCount == 0) { if (_playerCount == 0) {
_timerForSeek?.cancel(); _timerForSeek?.cancel();
_timerForSeek = null; _timerForSeek = null;
} else if (duration.value.inSeconds != 0) { } else if (duration.value != Duration.zero) {
try { try {
await _videoPlayerController?.stream.buffer.first; await _videoPlayerController?.stream.buffer.first;
danmakuController?.clear(); danmakuController?.clear();
@@ -1288,8 +1269,8 @@ class PlPlayerController with BlockConfigMixin {
} }
/// 调整播放时间 /// 调整播放时间
void onChangedSlider(double v) { void onChangedSlider(int v) {
sliderPosition.value = Duration(seconds: v.floor()); sliderPosition = Duration(seconds: v);
updateSliderPositionSecond(); updateSliderPositionSecond();
} }
@@ -1305,7 +1286,7 @@ class PlPlayerController with BlockConfigMixin {
void onUpdatedSliderProgress(Duration value) { void onUpdatedSliderProgress(Duration value) {
sliderTempPosition.value = value; sliderTempPosition.value = value;
sliderPosition.value = value; sliderPosition = value;
updateSliderPositionSecond(); updateSliderPositionSecond();
} }
@@ -1350,14 +1331,6 @@ class PlPlayerController with BlockConfigMixin {
}); });
} }
void volumeUpdated() {
showVolumeStatus.value = true;
_timerForShowingVolume?.cancel();
_timerForShowingVolume = Timer(const Duration(seconds: 1), () {
showVolumeStatus.value = false;
});
}
/// Toggle Change the videofit accordingly /// Toggle Change the videofit accordingly
void toggleVideoFit(VideoFitType value) { void toggleVideoFit(VideoFitType value) {
videoFit.value = value; videoFit.value = value;
@@ -1440,7 +1413,7 @@ class PlPlayerController with BlockConfigMixin {
bool get _isCompleted => bool get _isCompleted =>
videoPlayerController!.state.completed || videoPlayerController!.state.completed ||
(duration.value - position.value).inMilliseconds <= 50; (duration.value - position).inMilliseconds <= 50;
// 双击播放、暂停 // 双击播放、暂停
Future<void> onDoubleTapCenter() async { Future<void> onDoubleTapCenter() async {
@@ -1464,11 +1437,11 @@ class PlPlayerController with BlockConfigMixin {
} }
void onForward(Duration duration) { void onForward(Duration duration) {
onForwardBackward(position.value + duration); onForwardBackward(position + duration);
} }
void onBackward(Duration duration) { void onBackward(Duration duration) {
onForwardBackward(position.value - duration); onForwardBackward(position - duration);
} }
void onForwardBackward(Duration duration) { void onForwardBackward(Duration duration) {
@@ -1604,7 +1577,7 @@ class PlPlayerController with BlockConfigMixin {
} }
// 记录播放记录 // 记录播放记录
Future<void> makeHeartBeat( Future<void>? makeHeartBeat(
int progress, { int progress, {
HeartBeatType type = HeartBeatType.playing, HeartBeatType type = HeartBeatType.playing,
bool isManual = false, bool isManual = false,
@@ -1615,41 +1588,26 @@ class PlPlayerController with BlockConfigMixin {
dynamic seasonId, dynamic seasonId,
dynamic pgcType, dynamic pgcType,
VideoType? videoType, VideoType? videoType,
}) async { }) {
if (isLive) { if (isLive) {
return; return null;
} }
if (!enableHeart || MineController.anonymity.value || progress == 0) { if (!enableHeart || MineController.anonymity.value || progress == 0) {
return; return null;
} else if (playerStatus.isPaused) { } else if (playerStatus.isPaused) {
if (!isManual) { if (!isManual) {
return; return null;
} }
} }
bool isComplete = bool isComplete =
playerStatus.isCompleted || type == HeartBeatType.completed; playerStatus.isCompleted || type == HeartBeatType.completed;
if ((durationSeconds.value - position.value).inMilliseconds > 1000) { if ((duration.value - position).inMilliseconds > 1000) {
isComplete = false; isComplete = false;
} }
// 播放状态变化时,更新 // 播放状态变化时,更新
if (type == HeartBeatType.status || type == HeartBeatType.completed) { Future<void> send() {
await VideoHttp.heartBeat( return VideoHttp.heartBeat(
aid: aid ?? _aid,
bvid: bvid ?? _bvid,
cid: cid ?? this.cid,
progress: isComplete ? -1 : progress,
epid: epid ?? _epid,
seasonId: seasonId ?? _seasonId,
subType: pgcType ?? _pgcType,
videoType: videoType ?? _videoType,
);
return;
}
// 正常播放时间隔5秒更新一次
else if (progress - _heartDuration >= 5) {
_heartDuration = progress;
await VideoHttp.heartBeat(
aid: aid ?? _aid, aid: aid ?? _aid,
bvid: bvid ?? _bvid, bvid: bvid ?? _bvid,
cid: cid ?? this.cid, cid: cid ?? this.cid,
@@ -1660,6 +1618,23 @@ class PlPlayerController with BlockConfigMixin {
videoType: videoType ?? _videoType, videoType: videoType ?? _videoType,
); );
} }
switch (type) {
case HeartBeatType.playing:
if (progress - _heartDuration >= 5) {
_heartDuration = progress;
return send();
}
case HeartBeatType.status:
if (progress - _heartDuration >= 2) {
_heartDuration = progress;
return send();
}
case HeartBeatType.completed:
if (isComplete) progress = -1;
return send();
}
return null;
} }
void setPlayRepeat(PlayRepeat type) { void setPlayRepeat(PlayRepeat type) {
@@ -1705,7 +1680,6 @@ class PlPlayerController with BlockConfigMixin {
Utils.channel.setMethodCallHandler(null); Utils.channel.setMethodCallHandler(null);
_timer?.cancel(); _timer?.cancel();
_timerForSeek?.cancel(); _timerForSeek?.cancel();
_timerForShowingVolume?.cancel();
// _position.close(); // _position.close();
// _playerEventSubs?.cancel(); // _playerEventSubs?.cancel();
// _sliderPosition.close(); // _sliderPosition.close();
@@ -1775,9 +1749,7 @@ class PlPlayerController with BlockConfigMixin {
return; return;
} }
if (videoShot case Success(:final response)) { if (videoShot case Success(:final response)) {
if (!showPreview.value) { showPreview.value = true;
showPreview.value = true;
}
previewIndex.value = max( previewIndex.value = max(
0, 0,
(response.index.where((item) => item <= seconds).length - 2), (response.index.where((item) => item <= seconds).length - 2),

View File

@@ -400,7 +400,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Obx( Obx(
() => Text( () => Text(
DurationUtils.formatDuration( DurationUtils.formatDuration(
plPlayerController.durationSeconds.value.inSeconds, plPlayerController.duration.value.inSeconds,
), ),
style: const TextStyle( style: const TextStyle(
color: Color(0xFFD0D0D0), color: Color(0xFFD0D0D0),
@@ -1016,15 +1016,12 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
if (plPlayerController.isLive) return; if (plPlayerController.isLive) return;
final int curSliderPosition = final int curSliderPosition =
plPlayerController.sliderPosition.value.inMilliseconds; plPlayerController.sliderPosition.inMilliseconds;
final int newPos = final int newPos =
(curSliderPosition + (curSliderPosition +
(plPlayerController.sliderScale * delta.dx / maxWidth) (plPlayerController.sliderScale * delta.dx / maxWidth)
.round()) .round())
.clamp( .clamp(0, plPlayerController.duration.value.inMilliseconds);
0,
plPlayerController.duration.value.inMilliseconds,
);
final Duration result = Duration(milliseconds: newPos); final Duration result = Duration(milliseconds: newPos);
final height = maxHeight * 0.125; final height = maxHeight * 0.125;
if (details.localFocalPoint.dy <= height && if (details.localFocalPoint.dy <= height &&
@@ -1133,11 +1130,11 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
if (plPlayerController.isSliderMoving.value) { if (plPlayerController.isSliderMoving.value) {
if (plPlayerController.cancelSeek == true) { if (plPlayerController.cancelSeek == true) {
plPlayerController.onUpdatedSliderProgress( plPlayerController.onUpdatedSliderProgress(
plPlayerController.position.value, plPlayerController.position,
); );
} else { } else {
plPlayerController.seekTo( plPlayerController.seekTo(
plPlayerController.sliderPosition.value, plPlayerController.sliderPosition,
isSeek: false, isSeek: false,
); );
} }
@@ -1308,15 +1305,12 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Offset delta = event.localPanDelta; Offset delta = event.localPanDelta;
final int curSliderPosition = final int curSliderPosition =
plPlayerController.sliderPosition.value.inMilliseconds; plPlayerController.sliderPosition.inMilliseconds;
final int newPos = final int newPos =
(curSliderPosition + (curSliderPosition +
(plPlayerController.sliderScale * delta.dx / maxWidth) (plPlayerController.sliderScale * delta.dx / maxWidth)
.round()) .round())
.clamp( .clamp(0, plPlayerController.duration.value.inMilliseconds);
0,
plPlayerController.duration.value.inMilliseconds,
);
final Duration result = Duration(milliseconds: newPos); final Duration result = Duration(milliseconds: newPos);
if (plPlayerController.cancelSeek == true) { if (plPlayerController.cancelSeek == true) {
plPlayerController plPlayerController
@@ -1504,10 +1498,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
() { () {
return Text( return Text(
DurationUtils.formatDuration( DurationUtils.formatDuration(
plPlayerController plPlayerController.duration.value.inSeconds,
.durationSeconds
.value
.inSeconds,
), ),
style: textStyle, style: textStyle,
); );
@@ -1754,7 +1745,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
final int value = final int value =
plPlayerController.sliderPositionSeconds.value; plPlayerController.sliderPositionSeconds.value;
final int max = final int max =
plPlayerController.durationSeconds.value.inSeconds; plPlayerController.duration.value.inSeconds;
final int buffer = final int buffer =
plPlayerController.bufferedSeconds.value; plPlayerController.bufferedSeconds.value;
return ProgressBar( return ProgressBar(
@@ -1923,8 +1914,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
), ),
if (plPlayerController.isBuffering.value) if (plPlayerController.isBuffering.value)
Obx(() { Obx(() {
if (plPlayerController.buffered.value == if (plPlayerController.bufferedSeconds.value == 0) {
Duration.zero) {
return const Text( return const Text(
'加载中...', '加载中...',
style: TextStyle( style: TextStyle(
@@ -2088,8 +2078,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
late final segment = Pair( late final segment = Pair(
first: plPlayerController.position.value.inMilliseconds / 1000.0, first: plPlayerController.position.inMilliseconds / 1000.0,
second: plPlayerController.position.value.inMilliseconds / 1000.0, second: plPlayerController.position.inMilliseconds / 1000.0,
); );
Future<void> screenshotWebp() async { Future<void> screenshotWebp() async {
@@ -2103,8 +2093,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
final ctr = plPlayerController; final ctr = plPlayerController;
final theme = Theme.of(context); final theme = Theme.of(context);
final currentPos = ctr.position.value.inMilliseconds / 1000.0; final currentPos = ctr.position.inMilliseconds / 1000.0;
final duration = ctr.durationSeconds.value.inMilliseconds / 1000.0; final duration = ctr.duration.value.inMilliseconds / 1000.0;
final model = PostSegmentModel( final model = PostSegmentModel(
segment: segment, segment: segment,
category: SegmentType.sponsor, category: SegmentType.sponsor,

View File

@@ -30,20 +30,20 @@ class BottomControl extends StatelessWidget {
controller.onChangedSliderStart(duration.timeStamp); controller.onChangedSliderStart(duration.timeStamp);
} }
void onDragUpdate(ThumbDragDetails duration, int max) { void onDragUpdate(ThumbDragDetails duration) {
if (!controller.isFileSource && controller.showSeekPreview) { if (!controller.isFileSource && controller.showSeekPreview) {
controller.updatePreviewIndex(duration.timeStamp.inSeconds); controller.updatePreviewIndex(duration.timeStamp.inSeconds);
} }
controller.onUpdatedSliderProgress(duration.timeStamp); controller.onUpdatedSliderProgress(duration.timeStamp);
} }
void onSeek(Duration duration, int max) { void onSeek(Duration duration) {
if (controller.showSeekPreview) { if (controller.showSeekPreview) {
controller.showPreview.value = false; controller.showPreview.value = false;
} }
controller controller
..onChangedSliderEnd() ..onChangedSliderEnd()
..onChangedSlider(duration.inSeconds.toDouble()) ..onChangedSlider(duration.inSeconds)
..seekTo(Duration(seconds: duration.inSeconds), isSeek: false); ..seekTo(Duration(seconds: duration.inSeconds), isSeek: false);
} }
@@ -72,8 +72,7 @@ class BottomControl extends StatelessWidget {
children: [ children: [
Obx(() { Obx(() {
final int value = controller.sliderPositionSeconds.value; final int value = controller.sliderPositionSeconds.value;
final int max = final int max = controller.duration.value.inSeconds;
controller.durationSeconds.value.inSeconds;
return ProgressBar( return ProgressBar(
progress: Duration(seconds: value), progress: Duration(seconds: value),
buffered: Duration( buffered: Duration(
@@ -89,8 +88,8 @@ class BottomControl extends StatelessWidget {
thumbRadius: 7, thumbRadius: 7,
thumbGlowRadius: 25, thumbGlowRadius: 25,
onDragStart: onDragStart, onDragStart: onDragStart,
onDragUpdate: (e) => onDragUpdate(e, max), onDragUpdate: onDragUpdate,
onSeek: (e) => onSeek(e, max), onSeek: onSeek,
); );
}), }),
if (controller.enableBlock && if (controller.enableBlock &&