From ae760a4b9b3bec34edc671720dfe1351b719e39d Mon Sep 17 00:00:00 2001
From: Adrian Castro <22133246+castdrian@users.noreply.github.com>
Date: Fri, 1 Mar 2024 14:47:35 +0100
Subject: [PATCH] feat: playback speed changing
---
.../src/components/player/BottomControls.tsx | 2 +
.../player/PlaybackSpeedSelector.tsx | 71 +++++++++++++++++++
.../src/components/player/VideoPlayer.tsx | 3 +
.../expo/src/hooks/player/usePlaybackSpeed.ts | 18 +++++
4 files changed, 94 insertions(+)
create mode 100644 apps/expo/src/components/player/PlaybackSpeedSelector.tsx
create mode 100644 apps/expo/src/hooks/player/usePlaybackSpeed.ts
diff --git a/apps/expo/src/components/player/BottomControls.tsx b/apps/expo/src/components/player/BottomControls.tsx
index de33acb..be6c49c 100644
--- a/apps/expo/src/components/player/BottomControls.tsx
+++ b/apps/expo/src/components/player/BottomControls.tsx
@@ -6,6 +6,7 @@ import { Text } from "../ui/Text";
import { AudioTrackSelector } from "./AudioTrackSelector";
import { CaptionsSelector } from "./CaptionsSelector";
import { Controls } from "./Controls";
+import { PlaybackSpeedSelector } from "./PlaybackSpeedSelector";
import { ProgressBar } from "./ProgressBar";
import { SeasonSelector } from "./SeasonEpisodeSelector";
import { SourceSelector } from "./SourceSelector";
@@ -62,6 +63,7 @@ export const BottomControls = () => {
+
);
diff --git a/apps/expo/src/components/player/PlaybackSpeedSelector.tsx b/apps/expo/src/components/player/PlaybackSpeedSelector.tsx
new file mode 100644
index 0000000..9cc8ca1
--- /dev/null
+++ b/apps/expo/src/components/player/PlaybackSpeedSelector.tsx
@@ -0,0 +1,71 @@
+import { Pressable, ScrollView, View } from "react-native";
+import Modal from "react-native-modal";
+import { MaterialCommunityIcons } from "@expo/vector-icons";
+
+import colors from "@movie-web/tailwind-config/colors";
+
+import { usePlaybackSpeed } from "~/hooks/player/usePlaybackSpeed";
+import { useBoolean } from "~/hooks/useBoolean";
+import { Button } from "../ui/Button";
+import { Text } from "../ui/Text";
+import { Controls } from "./Controls";
+
+export const PlaybackSpeedSelector = () => {
+ const { currentSpeed, changePlaybackSpeed } = usePlaybackSpeed();
+ const { isTrue, on, off } = useBoolean();
+
+ const speeds = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
+
+ return (
+
+
+
+ }
+ />
+
+
+
+
+ Select speed
+ {speeds.map((speed) => (
+ {
+ changePlaybackSpeed(speed);
+ off();
+ }}
+ >
+ {speed}
+ {speed === currentSpeed.value && (
+
+ )}
+
+ ))}
+
+
+
+ );
+};
diff --git a/apps/expo/src/components/player/VideoPlayer.tsx b/apps/expo/src/components/player/VideoPlayer.tsx
index 43c811c..a65cc1b 100644
--- a/apps/expo/src/components/player/VideoPlayer.tsx
+++ b/apps/expo/src/components/player/VideoPlayer.tsx
@@ -18,6 +18,7 @@ import * as StatusBar from "expo-status-bar";
import { findHighestQuality } from "@movie-web/provider-utils";
import { useBrightness } from "~/hooks/player/useBrightness";
+import { usePlaybackSpeed } from "~/hooks/player/usePlaybackSpeed";
import { usePlayer } from "~/hooks/player/usePlayer";
import { useVolume } from "~/hooks/player/useVolume";
import { useAudioTrackStore } from "~/stores/audio";
@@ -41,6 +42,7 @@ export const VideoPlayer = () => {
setShowVolumeOverlay,
handleVolumeChange,
} = useVolume();
+ const { currentSpeed } = usePlaybackSpeed();
const { dismissFullscreenPlayer } = usePlayer();
const [videoSrc, setVideoSrc] = useState();
const [isLoading, setIsLoading] = useState(true);
@@ -257,6 +259,7 @@ export const VideoPlayer = () => {
shouldPlay={shouldPlay}
resizeMode={resizeMode}
volume={currentVolume.value}
+ rate={currentSpeed.value}
onLoadStart={onVideoLoadStart}
onReadyForDisplay={onReadyForDisplay}
onPlaybackStatusUpdate={setStatus}
diff --git a/apps/expo/src/hooks/player/usePlaybackSpeed.ts b/apps/expo/src/hooks/player/usePlaybackSpeed.ts
new file mode 100644
index 0000000..9fdf9d3
--- /dev/null
+++ b/apps/expo/src/hooks/player/usePlaybackSpeed.ts
@@ -0,0 +1,18 @@
+import { useCallback } from "react";
+import { useSharedValue } from "react-native-reanimated";
+
+export const usePlaybackSpeed = () => {
+ const speed = useSharedValue(1);
+
+ const changePlaybackSpeed = useCallback(
+ (newValue: number) => {
+ speed.value = newValue;
+ },
+ [speed],
+ );
+
+ return {
+ currentSpeed: speed,
+ changePlaybackSpeed,
+ } as const;
+};