@@ -182,8 +182,9 @@ DurationLocale _getDurationLocale() {
|
||||
|
||||
/// Formats the clock time at which media will finish playing, given the remaining duration.
|
||||
/// Returns a localized time string like "6:12 PM" or "18:12" depending on locale.
|
||||
String formatFinishTime(Duration remaining) {
|
||||
final finishTime = DateTime.now().add(remaining);
|
||||
String formatFinishTime(Duration remaining, {double rate = 1.0}) {
|
||||
final adjustedRemaining = remaining * (1.0 / rate);
|
||||
final finishTime = DateTime.now().add(adjustedRemaining);
|
||||
final formatter = DateFormat.jm(LocaleSettings.currentLocale.languageCode);
|
||||
return formatter.format(finishTime);
|
||||
}
|
||||
|
||||
@@ -544,16 +544,23 @@ class DesktopVideoControlsState extends State<DesktopVideoControls> {
|
||||
stream: widget.player.streams.duration,
|
||||
initialData: widget.player.state.duration,
|
||||
builder: (context, durSnap) {
|
||||
final position = posSnap.data ?? Duration.zero;
|
||||
final duration = durSnap.data ?? Duration.zero;
|
||||
final remaining = duration - position;
|
||||
if (remaining.inSeconds <= 0) return const SizedBox.shrink();
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Text(
|
||||
t.videoControls.endsAt(time: formatFinishTime(remaining)),
|
||||
style: const TextStyle(color: Colors.white70, fontSize: 13),
|
||||
),
|
||||
return StreamBuilder<double>(
|
||||
stream: widget.player.streams.rate,
|
||||
initialData: widget.player.state.rate,
|
||||
builder: (context, rateSnap) {
|
||||
final position = posSnap.data ?? Duration.zero;
|
||||
final duration = durSnap.data ?? Duration.zero;
|
||||
final remaining = duration - position;
|
||||
final rate = rateSnap.data ?? 1.0;
|
||||
if (remaining.inSeconds <= 0) return const SizedBox.shrink();
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Text(
|
||||
t.videoControls.endsAt(time: formatFinishTime(remaining, rate: rate)),
|
||||
style: const TextStyle(color: Colors.white70, fontSize: 13),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -111,8 +111,15 @@ class VideoTimelineBar extends StatelessWidget {
|
||||
if (!showFinishTime || remaining.inSeconds >= 0) {
|
||||
return _buildTimestamp(remaining);
|
||||
}
|
||||
final text = '${formatDurationTimestamp(remaining)} · ${formatFinishTime(remaining.abs())}';
|
||||
return Text(text, style: const TextStyle(color: Colors.white, fontSize: 14));
|
||||
return StreamBuilder<double>(
|
||||
stream: player.streams.rate,
|
||||
initialData: player.state.rate,
|
||||
builder: (context, rateSnap) {
|
||||
final rate = rateSnap.data ?? 1.0;
|
||||
final text = '${formatDurationTimestamp(remaining)} · ${formatFinishTime(remaining.abs(), rate: rate)}';
|
||||
return Text(text, style: const TextStyle(color: Colors.white, fontSize: 14));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSlider(Duration position, Duration duration) {
|
||||
|
||||
Reference in New Issue
Block a user