Skip to content

Commit

Permalink
Change on_percent to on_position - send back position,duration,percen…
Browse files Browse the repository at this point in the history
…t - throttle configurable
  • Loading branch information
syleishere committed Dec 13, 2024
1 parent 52b0f0a commit 8d93d6e
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 25 deletions.
37 changes: 21 additions & 16 deletions packages/flet_video/lib/src/video.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class VideoControl extends StatefulWidget {

class _VideoControlState extends State<VideoControl> with FletStoreMixin {
int _lastProcessedIndex = -1;
int _lastPercent = -1;
Duration _lastEmittedPosition = Duration.zero;
late final playerConfig = PlayerConfiguration(
title: widget.control.attrString("title", "Flet Video")!,
muted: widget.control.attrBool("muted", false)!,
Expand Down Expand Up @@ -98,13 +98,18 @@ class _VideoControlState extends State<VideoControl> with FletStoreMixin {
.triggerControlEvent(widget.control.id, "track_changed", message ?? "");
}

void _onPercentChanged(String? message) {
// Let's not debug print this, cause to much traffic on console
// debugPrint("Video onPercentChanged: $message");
widget.backend
.triggerControlEvent(widget.control.id, "percent_changed", message ?? "");
void _onPositionChanged(Duration position, Duration duration, int percent) {
// commenting out, may be too verbose to display every 1 second
// debugPrint("New Position is ${position} and duration is ${duration} and percent is ${percent}");
final data = {
"position": position.inSeconds, // Send position in seconds
"duration": duration.inSeconds, // Send duration in seconds
"percent": percent,
};
widget.backend.triggerControlEvent(widget.control.id, "positionChanged", jsonEncode(data));
}


@override
Widget build(BuildContext context) {
debugPrint("Video build: ${widget.control.id}");
Expand Down Expand Up @@ -136,7 +141,9 @@ class _VideoControlState extends State<VideoControl> with FletStoreMixin {
bool onError = widget.control.attrBool("onError", false)!;
bool onCompleted = widget.control.attrBool("onCompleted", false)!;
bool onTrackChanged = widget.control.attrBool("onTrackChanged", false)!;
bool onPercentChanged = widget.control.attrBool("onPercentChanged", false)!;
bool onPositionChanged = widget.control.attrBool("onPositionChanged", false)!;
int throttle = widget.control.attrInt("throttle", 1000)!;


double? volume = widget.control.attrDouble("volume");
double? pitch = widget.control.attrDouble("pitch");
Expand Down Expand Up @@ -311,18 +318,16 @@ class _VideoControlState extends State<VideoControl> with FletStoreMixin {
}
});
// Send percentage position change between 0-100 to use with flet slider.
// This will make flet event loop less busy sending round int numbers
// as well as throttling to 1 second to not overload flet socket
player.stream.position.throttleTime(const Duration(seconds: 1)).listen((position) {
if (onPercentChanged) {
player.stream.position.throttleTime(Duration(milliseconds: throttle)).listen((position) {
if (onPositionChanged && position.inSeconds != _lastEmittedPosition.inSeconds) {
try {
final int percent = (position.inMilliseconds / player.state.duration.inMilliseconds * 100).toInt();
if (percent != _lastPercent) {
_lastPercent = percent;
_onPercentChanged(percent.toString());
}
final duration = player.state.duration;
final int percent = (position.inMilliseconds / duration.inMilliseconds * 100).toInt();
_lastEmittedPosition = position;
_onPositionChanged(position, duration, percent);
} catch (e) {
debugPrint("Error calculating percentage: $e");
debugPrint("Error in OnPositionChanged: $e");
}
}
});
Expand Down
46 changes: 37 additions & 9 deletions sdk/python/packages/flet/src/flet/core/video.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import dataclasses
import json
from enum import Enum
from typing import Any, Dict, List, Optional, Union, cast

Expand All @@ -8,6 +9,8 @@
from flet.core.box import FilterQuality
from flet.core.constrained_control import ConstrainedControl
from flet.core.control import OptionalNumber
from flet.core.control_event import ControlEvent
from flet.core.event_handler import EventHandler
from flet.core.ref import Ref
from flet.core.text_style import TextStyle
from flet.core.tooltip import TooltipValue
Expand Down Expand Up @@ -58,6 +61,14 @@ class VideoSubtitleConfiguration:
padding: Optional[PaddingValue] = dataclasses.field(default=None)
visible: Optional[bool] = dataclasses.field(default=None)

class VideoPositionChangedEvent(ControlEvent):
def __init__(self, e: ControlEvent):
super().__init__(e.target, e.name, e.data, e.control, e.page)
d = json.loads(e.data)
self.position: int = d.get("position")
self.duration: int = d.get("duration")
self.percent: int = d.get("percent")


class Video(ConstrainedControl):
"""
Expand All @@ -81,6 +92,7 @@ def __init__(
playlist_mode: Optional[PlaylistMode] = None,
shuffle_playlist: Optional[bool] = None,
volume: OptionalNumber = None,
throttle: Optional[int] = None,
playback_rate: OptionalNumber = None,
alignment: Optional[Alignment] = None,
filter_quality: Optional[FilterQuality] = None,
Expand All @@ -96,7 +108,7 @@ def __init__(
on_error: OptionalControlEventCallable = None,
on_completed: OptionalControlEventCallable = None,
on_track_changed: OptionalControlEventCallable = None,
on_percent_changed: OptionalControlEventCallable = None,
on_position_changed: OptionalControlEventCallable = None,
#
# ConstrainedControl
#
Expand Down Expand Up @@ -165,6 +177,7 @@ def __init__(
self.pitch = pitch
self.fill_color = fill_color
self.volume = volume
self.throttle = throttle
self.playback_rate = playback_rate
self.alignment = alignment
self.wakelock = wakelock
Expand All @@ -183,7 +196,13 @@ def __init__(
self.on_error = on_error
self.on_completed = on_completed
self.on_track_changed = on_track_changed
self.on_percent_changed = on_percent_changed
self.__on_position_changed = EventHandler(
lambda e: VideoPositionChangedEvent(e)
)
self._add_event_handler(
"positionChanged", self.__on_position_changed.get_handler()
)
self.on_position_changed = on_position_changed

def _get_control_name(self):
return "video"
Expand Down Expand Up @@ -418,6 +437,15 @@ def volume(self, value: OptionalNumber):
assert value is None or 0 <= value <= 100, "volume must be between 0 and 100"
self._set_attr("volume", value)

# throttle
@property
def throttle(self) -> Optional[int]:
return self._get_attr("throttle", data_type="int")

@throttle.setter
def throttle(self, value: Optional[int]):
self._set_attr("throttle", value)

# playback_rate
@property
def playback_rate(self) -> OptionalNumber:
Expand Down Expand Up @@ -553,12 +581,12 @@ def on_track_changed(self, handler: OptionalControlEventCallable):
self._set_attr("onTrackChanged", True if handler is not None else None)
self._add_event_handler("track_changed", handler)

# on_pos_changed
# on_position_changed
@property
def on_percent_changed(self) -> OptionalControlEventCallable:
return self._get_event_handler("percent_changed")
def on_position_changed(self,) -> OptionalEventCallable[VideoPositionChangedEvent]:
return self.__on_position_changed.handler

@on_percent_changed.setter
def on_percent_changed(self, handler: OptionalControlEventCallable):
self._set_attr("onPercentChanged", True if handler is not None else None)
self._add_event_handler("percent_changed", handler)
@on_position_changed.setter
def on_position_changed(self, handler: OptionalEventCallable[VideoPositionChangedEvent]):
self.__on_position_changed.handler = handler
self._set_attr("onPositionChanged", True if handler is not None else None)

0 comments on commit 8d93d6e

Please sign in to comment.