2023-06-26 15:27:47 +00:00
|
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
2024-12-04 21:03:46 +00:00
|
|
|
import 'package:native_video_player/native_video_player.dart';
|
2023-06-26 15:27:47 +00:00
|
|
|
|
2024-03-06 03:42:22 +00:00
|
|
|
enum VideoPlaybackState {
|
|
|
|
initializing,
|
|
|
|
paused,
|
|
|
|
playing,
|
|
|
|
buffering,
|
|
|
|
completed,
|
|
|
|
}
|
2023-06-26 15:27:47 +00:00
|
|
|
|
2024-03-06 03:42:22 +00:00
|
|
|
class VideoPlaybackValue {
|
|
|
|
/// The current position of the video
|
2023-06-26 15:27:47 +00:00
|
|
|
final Duration position;
|
2024-03-06 03:42:22 +00:00
|
|
|
|
|
|
|
/// The total duration of the video
|
2023-06-26 15:27:47 +00:00
|
|
|
final Duration duration;
|
2024-03-06 03:42:22 +00:00
|
|
|
|
|
|
|
/// The current state of the video playback
|
|
|
|
final VideoPlaybackState state;
|
|
|
|
|
|
|
|
/// The volume of the video
|
|
|
|
final double volume;
|
|
|
|
|
2024-12-04 21:03:46 +00:00
|
|
|
const VideoPlaybackValue({
|
2024-03-06 03:42:22 +00:00
|
|
|
required this.position,
|
|
|
|
required this.duration,
|
|
|
|
required this.state,
|
|
|
|
required this.volume,
|
|
|
|
});
|
|
|
|
|
2024-12-04 21:03:46 +00:00
|
|
|
factory VideoPlaybackValue.fromNativeController(
|
|
|
|
NativeVideoPlayerController controller,
|
|
|
|
) {
|
|
|
|
final playbackInfo = controller.playbackInfo;
|
|
|
|
final videoInfo = controller.videoInfo;
|
|
|
|
|
|
|
|
if (playbackInfo == null || videoInfo == null) {
|
|
|
|
return videoPlaybackValueDefault;
|
2024-03-06 03:42:22 +00:00
|
|
|
}
|
|
|
|
|
2024-12-04 21:03:46 +00:00
|
|
|
final VideoPlaybackState status = switch (playbackInfo.status) {
|
|
|
|
PlaybackStatus.playing => VideoPlaybackState.playing,
|
|
|
|
PlaybackStatus.paused => VideoPlaybackState.paused,
|
|
|
|
PlaybackStatus.stopped => VideoPlaybackState.completed,
|
|
|
|
};
|
|
|
|
|
2024-03-06 03:42:22 +00:00
|
|
|
return VideoPlaybackValue(
|
2024-12-04 21:03:46 +00:00
|
|
|
position: Duration(seconds: playbackInfo.position),
|
|
|
|
duration: Duration(seconds: videoInfo.duration),
|
|
|
|
state: status,
|
|
|
|
volume: playbackInfo.volume,
|
2024-03-06 03:42:22 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-12-04 21:03:46 +00:00
|
|
|
VideoPlaybackValue copyWith({
|
|
|
|
Duration? position,
|
|
|
|
Duration? duration,
|
|
|
|
VideoPlaybackState? state,
|
|
|
|
double? volume,
|
|
|
|
}) {
|
2024-03-06 03:42:22 +00:00
|
|
|
return VideoPlaybackValue(
|
2024-12-04 21:03:46 +00:00
|
|
|
position: position ?? this.position,
|
|
|
|
duration: duration ?? this.duration,
|
|
|
|
state: state ?? this.state,
|
|
|
|
volume: volume ?? this.volume,
|
2024-03-06 03:42:22 +00:00
|
|
|
);
|
|
|
|
}
|
2023-06-26 15:27:47 +00:00
|
|
|
}
|
|
|
|
|
2024-12-04 21:03:46 +00:00
|
|
|
const VideoPlaybackValue videoPlaybackValueDefault = VideoPlaybackValue(
|
|
|
|
position: Duration.zero,
|
|
|
|
duration: Duration.zero,
|
|
|
|
state: VideoPlaybackState.initializing,
|
|
|
|
volume: 0.0,
|
|
|
|
);
|
|
|
|
|
2023-06-26 15:27:47 +00:00
|
|
|
final videoPlaybackValueProvider =
|
|
|
|
StateNotifierProvider<VideoPlaybackValueState, VideoPlaybackValue>((ref) {
|
|
|
|
return VideoPlaybackValueState(ref);
|
|
|
|
});
|
|
|
|
|
|
|
|
class VideoPlaybackValueState extends StateNotifier<VideoPlaybackValue> {
|
2024-12-04 21:03:46 +00:00
|
|
|
VideoPlaybackValueState(this.ref) : super(videoPlaybackValueDefault);
|
2023-06-26 15:27:47 +00:00
|
|
|
|
|
|
|
final Ref ref;
|
|
|
|
|
|
|
|
VideoPlaybackValue get value => state;
|
|
|
|
|
|
|
|
set value(VideoPlaybackValue value) {
|
|
|
|
state = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
set position(Duration value) {
|
2024-12-04 21:03:46 +00:00
|
|
|
if (state.position == value) return;
|
2024-03-06 03:42:22 +00:00
|
|
|
state = VideoPlaybackValue(
|
|
|
|
position: value,
|
|
|
|
duration: state.duration,
|
|
|
|
state: state.state,
|
|
|
|
volume: state.volume,
|
|
|
|
);
|
2023-06-26 15:27:47 +00:00
|
|
|
}
|
2024-12-04 21:03:46 +00:00
|
|
|
|
|
|
|
set status(VideoPlaybackState value) {
|
|
|
|
if (state.state == value) return;
|
|
|
|
state = VideoPlaybackValue(
|
|
|
|
position: state.position,
|
|
|
|
duration: state.duration,
|
|
|
|
state: value,
|
|
|
|
volume: state.volume,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void reset() {
|
|
|
|
state = videoPlaybackValueDefault;
|
|
|
|
}
|
2023-06-26 15:27:47 +00:00
|
|
|
}
|