diff --git a/src/navigation/MainStack.js b/src/navigation/MainStack.js
index 17a2aa2..6ab9e40 100644
--- a/src/navigation/MainStack.js
+++ b/src/navigation/MainStack.js
@@ -16,7 +16,7 @@ import ChooseDecor from "../screens/Playback/ChooseDecor";
import CreatingDecor from "../screens/Playback/CreatingDecor";
import Playback from "../screens/Playback/Playback";
import PlaybackOnboarding from "../screens/Playback/PlaybackOnboarding";
-import RecordPlayback from "../screens/Playback/RecordPlayback";
+import RecordPlayback from "../screens/Playback/RecordPlayback.web";
import RecordedPlayback from "../screens/Playback/RecordedPlayback";
import VideoFinalize from "../screens/Playback/VideoFinalize";
import PrivacyPolicy from "../screens/PrivacyPolicy";
diff --git a/src/screens/Playback/RecordPlayback.js b/src/screens/Playback/RecordPlayback.js
index 1100b26..2af04ac 100644
--- a/src/screens/Playback/RecordPlayback.js
+++ b/src/screens/Playback/RecordPlayback.js
@@ -1,25 +1,25 @@
-import { useFocusEffect } from '@react-navigation/native';
-import { useAudioPlayer } from 'expo-audio';
-import { CameraView, useCameraPermissions } from 'expo-camera';
+import { useFocusEffect } from "@react-navigation/native";
+import { useAudioPlayer } from "expo-audio";
+import { CameraView, useCameraPermissions } from "expo-camera";
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
-} from 'react';
-import { Alert, Text, View } from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import Svg, { Circle } from 'react-native-svg';
-import GradientButton from '../../components/GradientButton';
-import KaraokeLyrics from '../../components/KaraokeLyrics';
-import MusicLandHeader from '../../components/MusicLandHeader';
-import { increment, projectsRef } from '../../config/firebase';
-import { Routes } from '../../navigation';
-import { goBack, navigate } from '../../navigation/NavigationService';
-import { gutters, Palette } from '../../styles';
-import { FONT_FAMILY } from '../../styles/Fonts';
-import CreateLyricsHeader from '../Writing/components/CreateLyricsHeader';
+} from "react";
+import { Alert, Text, View } from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import Svg, { Circle } from "react-native-svg";
+import GradientButton from "../../components/GradientButton";
+import KaraokeLyrics from "../../components/KaraokeLyrics";
+import MusicLandHeader from "../../components/MusicLandHeader";
+import { increment, projectsRef } from "../../config/firebase";
+import { Routes } from "../../navigation";
+import { goBack, navigate } from "../../navigation/NavigationService";
+import { gutters, Palette } from "../../styles";
+import { FONT_FAMILY } from "../../styles/Fonts";
+import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
const TIME_BEFORE_INCREMENT_MS = 20000; // 20s
@@ -65,7 +65,7 @@ const RecordPlayback = ({ route }) => {
const arr = Array.isArray(ts?.alignedWords) ? ts.alignedWords : [];
return arr.map((w) => ({
- word: String(w?.word ?? ''),
+ word: String(w?.word ?? ""),
startS: Number(w?.startS ?? 0),
endS: Number(w?.endS ?? 0),
}));
@@ -77,16 +77,16 @@ const RecordPlayback = ({ route }) => {
let buf = [];
let start = null;
const clean = (txt) =>
- String(txt || '')
- .replace(/\s+/g, ' ')
+ String(txt || "")
+ .replace(/\s+/g, " ")
.trim();
- const isSentenceEnd = (txt) => /[.!?]$/.test((txt || '').trim());
+ const isSentenceEnd = (txt) => /[.!?]$/.test((txt || "").trim());
const isSectionTag = (txt) =>
- /^\s*\[[^\]]+\]\s*$/i.test((txt || '').trim());
+ /^\s*\[[^\]]+\]\s*$/i.test((txt || "").trim());
for (let i = 0; i < alignedWords.length; i++) {
const w = alignedWords[i];
- const original = String(w.word || '');
- const textNoNewline = original.replace(/\n/g, ' ');
+ const original = String(w.word || "");
+ const textNoNewline = original.replace(/\n/g, " ");
const gapToNext =
i < alignedWords.length - 1
? Math.max(0, alignedWords[i + 1].startS - w.endS)
@@ -113,7 +113,7 @@ const RecordPlayback = ({ route }) => {
const isLast = i === alignedWords.length - 1;
if (eolByNewline || eolByPause || eolByPunct || isLast) {
- const joined = clean(buf.join(' '));
+ const joined = clean(buf.join(" "));
if (joined)
out.push({ text: joined, startS: start ?? w.startS, endS: w.endS });
buf = [];
@@ -343,7 +343,7 @@ const RecordPlayback = ({ route }) => {
navigate(Routes.RecordedPlayback, { videoUri: video.uri, project });
else navigate(Routes.RecordedPlayback, { project });
} catch (e) {
- console.log('RecordPlayback error:', e);
+ console.log("RecordPlayback error:", e);
setIsRecording(false);
setIsPreparing(false);
setShowProgress(false);
@@ -356,14 +356,14 @@ const RecordPlayback = ({ route }) => {
checkSongEndRef.current = null;
}
// Inform the user when using a simulator where recording isn't supported
- const msg = String(e?.message || e || '');
+ const msg = String(e?.message || e || "");
if (/not supported on the simulator/i.test(msg)) {
Alert.alert(
- 'Indisponible sur simulateur',
- 'L’enregistrement vidéo n’est pas disponible sur le simulateur. Merci d’utiliser un appareil réel.',
+ "Indisponible sur simulateur",
+ "L’enregistrement vidéo n’est pas disponible sur le simulateur. Merci d’utiliser un appareil réel.",
[
{
- text: 'OK',
+ text: "OK",
onPress: () => {
try {
goBack();
@@ -384,15 +384,17 @@ const RecordPlayback = ({ route }) => {
+ facing="front"
+ mode="video"
+ >
+ }}
+ >
@@ -400,20 +402,22 @@ const RecordPlayback = ({ route }) => {
{isPreparing && countdown >= 1 && !showProgress && (
+ alignItems: "center",
+ justifyContent: "center",
+ }}
+ >
+ }}
+ >
{countdown}
@@ -423,14 +427,15 @@ const RecordPlayback = ({ route }) => {
{!permissionsGranted && (
+ }}
+ >
{
try {
if (!cameraPermission?.granted)
@@ -445,8 +450,8 @@ const RecordPlayback = ({ route }) => {
{/* Start button */}
{permissionsGranted && !isPreparing && !isRecording && (
@@ -456,21 +461,23 @@ const RecordPlayback = ({ route }) => {
{permissionsGranted && (isRecording || showProgress) && (
+ alignItems: "center",
+ justifyContent: "center",
+ }}
+ >
+ alignItems: "center",
+ justifyContent: "center",
+ }}
+ >
{
/>
{
{/* CreateLyricsHeader overlay outside of CameraView */}
+ }}
+ >
{(isRecording || showProgress) && alignedWords?.length > 0 ? (
{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterMedium,
- }}>
+ }}
+ >
L'enregistrement de ta vidéo commencera lorsque tu lanceras ta
musique, et s'arrêtera à la fin du morceau.
@@ -538,20 +547,21 @@ const ProgressRing = ({ size = 50, strokeWidth = 12, progress = 0 }) => {
width={size}
height={size}
style={{
- transform: [{ rotate: '-90deg' }],
- backgroundColor: '#ffffff3d',
+ transform: [{ rotate: "-90deg" }],
+ backgroundColor: "#ffffff3d",
borderRadius: 55,
- }}>
+ }}
+ >
);
@@ -561,10 +571,10 @@ export default RecordPlayback;
// Render previous/current/next line to reduce jumpiness
const KaraokeLines = ({ lines = [], currentLineIdx = -1 }) => {
- const prev = currentLineIdx > 0 ? lines[currentLineIdx - 1]?.text : '';
- const curr = currentLineIdx >= 0 ? lines[currentLineIdx]?.text : '';
+ const prev = currentLineIdx > 0 ? lines[currentLineIdx - 1]?.text : "";
+ const curr = currentLineIdx >= 0 ? lines[currentLineIdx]?.text : "";
const next =
- currentLineIdx + 1 < lines.length ? lines[currentLineIdx + 1]?.text : '';
+ currentLineIdx + 1 < lines.length ? lines[currentLineIdx + 1]?.text : "";
return (
{/* {prev ? (
@@ -576,19 +586,21 @@ const KaraokeLines = ({ lines = [], currentLineIdx = -1 }) => {
style={{
color: Palette.white,
fontSize: 18,
- textAlign: 'center',
+ textAlign: "center",
fontFamily: FONT_FAMILY.InterSemiBold,
- }}>
+ }}
+ >
{curr}
{next ? (
+ }}
+ >
{next}
) : null}
diff --git a/src/screens/Playback/RecordPlayback.web.js b/src/screens/Playback/RecordPlayback.web.js
new file mode 100644
index 0000000..8e2ea22
--- /dev/null
+++ b/src/screens/Playback/RecordPlayback.web.js
@@ -0,0 +1,630 @@
+import { useFocusEffect } from "@react-navigation/native";
+import { useAudioPlayer } from "expo-audio";
+import { CameraView, useCameraPermissions } from "expo-camera";
+import React, {
+ useCallback,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
+import { Alert, Text, View } from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import Svg, { Circle } from "react-native-svg";
+import GradientButton from "../../components/GradientButton";
+import KaraokeLyrics from "../../components/KaraokeLyrics";
+import MusicLandHeader from "../../components/MusicLandHeader";
+import { increment, projectsRef } from "../../config/firebase";
+import { isWeb } from "../../hooks/useLayoutType";
+import Page from "../../layouts/Page";
+import { Routes } from "../../navigation";
+import { goBack, navigate } from "../../navigation/NavigationService";
+import { gutters, Palette } from "../../styles";
+import { FONT_FAMILY } from "../../styles/Fonts";
+import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
+
+const TIME_BEFORE_INCREMENT_MS = 20000; // 20s
+
+const RecordPlayback = ({ route }) => {
+ const { top, bottom } = useSafeAreaInsets();
+ const { project } = route.params || {};
+ const projectId = project?.id;
+ const songIndex = project?.songIndex;
+ // Permissions
+ const [cameraPermission, requestCameraPermission] = useCameraPermissions();
+
+ // Refs
+ const cameraRef = useRef(null);
+ const countdownTimerRef = useRef(null);
+ const listenTimerRef = useRef(null);
+ const checkSongEndRef = useRef(null);
+ const stopRequestedRef = useRef(false);
+ const startedRef = useRef(false); // empêche les doubles démarrages
+ const countdownActiveRef = useRef(false); // évite le déclenchement avant 1er tick
+
+ // Compteurs vues
+ const listenedMsRef = useRef(0);
+ const incrementDoneRef = useRef(false);
+
+ // UI / state
+ const [isPreparing, setIsPreparing] = useState(false);
+ const [countdown, setCountdown] = useState(0);
+ const [isRecording, setIsRecording] = useState(false);
+ const [showProgress, setShowProgress] = useState(false);
+ const [progressInfo, setProgressInfo] = useState({ pos: 0, dur: 0 });
+
+ // Musique
+ const songUrl = project?.songUrl || null;
+ const player = useAudioPlayer(songUrl ? { uri: songUrl } : undefined);
+
+ const musicIndex = useMemo(() => {
+ const i = Number(songIndex);
+ return Number.isFinite(i) && i >= 0 ? i : 0;
+ }, [songIndex]);
+
+ const alignedWords = useMemo(() => {
+ const ts = project?.musicTimestamps?.[musicIndex];
+
+ const arr = Array.isArray(ts?.alignedWords) ? ts.alignedWords : [];
+ return arr.map((w) => ({
+ word: String(w?.word ?? ""),
+ startS: Number(w?.startS ?? 0),
+ endS: Number(w?.endS ?? 0),
+ }));
+ }, [project?.musicTimestamps, musicIndex]);
+
+ // Build line groups to display line-by-line
+ const lines = useMemo(() => {
+ const out = [];
+ let buf = [];
+ let start = null;
+ const clean = (txt) =>
+ String(txt || "")
+ .replace(/\s+/g, " ")
+ .trim();
+ const isSentenceEnd = (txt) => /[.!?]$/.test((txt || "").trim());
+ const isSectionTag = (txt) =>
+ /^\s*\[[^\]]+\]\s*$/i.test((txt || "").trim());
+ for (let i = 0; i < alignedWords.length; i++) {
+ const w = alignedWords[i];
+ const original = String(w.word || "");
+ const textNoNewline = original.replace(/\n/g, " ");
+ const gapToNext =
+ i < alignedWords.length - 1
+ ? Math.max(0, alignedWords[i + 1].startS - w.endS)
+ : 0;
+
+ // If buffer empty, mark start
+ if (buf.length === 0) start = w.startS;
+
+ // Section tag becomes its own line
+ if (isSectionTag(textNoNewline)) {
+ const joined = clean(textNoNewline);
+ if (joined)
+ out.push({ text: joined, startS: start ?? w.startS, endS: w.endS });
+ buf = [];
+ start = null;
+ continue;
+ }
+
+ buf.push(textNoNewline);
+
+ const eolByNewline = /\n/.test(original);
+ const eolByPause = gapToNext >= 0.6;
+ const eolByPunct = isSentenceEnd(textNoNewline);
+ const isLast = i === alignedWords.length - 1;
+
+ if (eolByNewline || eolByPause || eolByPunct || isLast) {
+ const joined = clean(buf.join(" "));
+ if (joined)
+ out.push({ text: joined, startS: start ?? w.startS, endS: w.endS });
+ buf = [];
+ start = null;
+ }
+ }
+ return out;
+ }, [alignedWords]);
+ // console.log("alignedWords:", alignedWords);
+ useEffect(() => {
+ listenedMsRef.current = 0;
+ incrementDoneRef.current = false;
+ }, [songUrl]);
+
+ // Poll player -> progress ring
+ useEffect(() => {
+ if (!player) return;
+ const id = setInterval(() => {
+ try {
+ const dur = (player?.duration || 0) * 1000;
+ const pos = (player?.currentTime || 0) * 1000;
+ setProgressInfo({ pos, dur });
+ } catch (_) {}
+ }, 250);
+ return () => clearInterval(id);
+ }, [player]);
+
+ // Compute current line index from playback time
+ const currentTimeS = (progressInfo?.pos || 0) / 1000;
+ const currentLineIdx = useMemo(() => {
+ if (!lines || lines.length === 0) return -1;
+ for (let i = 0; i < lines.length; i++) {
+ const L = lines[i];
+ if (currentTimeS >= L.startS && currentTimeS <= L.endS) return i;
+ }
+ if (currentTimeS > (lines[lines.length - 1]?.endS || 0))
+ return lines.length - 1;
+ return -1;
+ }, [lines, currentTimeS]);
+
+ // Permissions au mount + cleanup
+ useEffect(() => {
+ (async () => {
+ try {
+ if (!cameraPermission?.granted) await requestCameraPermission();
+ } catch (_) {}
+ })();
+ return () => {
+ try {
+ if (countdownTimerRef.current) clearInterval(countdownTimerRef.current);
+ if (listenTimerRef.current) clearInterval(listenTimerRef.current);
+ if (checkSongEndRef.current) clearInterval(checkSongEndRef.current);
+ countdownTimerRef.current = null;
+ listenTimerRef.current = null;
+ checkSongEndRef.current = null;
+ } catch (_) {}
+ };
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
+
+ // Reset complet
+ const resetSession = useCallback(async () => {
+ try {
+ if (countdownTimerRef.current) {
+ clearInterval(countdownTimerRef.current);
+ countdownTimerRef.current = null;
+ }
+ if (listenTimerRef.current) {
+ clearInterval(listenTimerRef.current);
+ listenTimerRef.current = null;
+ }
+ if (checkSongEndRef.current) {
+ clearInterval(checkSongEndRef.current);
+ checkSongEndRef.current = null;
+ }
+
+ startedRef.current = false;
+ stopRequestedRef.current = false;
+ countdownActiveRef.current = false;
+ listenedMsRef.current = 0;
+ incrementDoneRef.current = false;
+
+ setIsPreparing(false);
+ setIsRecording(false);
+ setShowProgress(false);
+ setCountdown(0);
+
+ if (player) {
+ try {
+ if (player.playing) await player.pause?.();
+ await player.seekTo?.(0);
+ } catch (_) {}
+ }
+ } catch (_) {}
+ }, [player]);
+
+ useFocusEffect(
+ useCallback(() => {
+ void resetSession();
+ return () => {};
+ }, [resetSession])
+ );
+
+ // Lancer le compte à rebours (le tick décrémente uniquement)
+ const startCountdownThenRecord = async () => {
+ if (!songUrl) return;
+ await resetSession();
+ setIsPreparing(true);
+ setShowProgress(false);
+ setCountdown(5);
+
+ // On démarre l'intervalle puis on active le flag
+ if (countdownTimerRef.current) {
+ clearInterval(countdownTimerRef.current);
+ countdownTimerRef.current = null;
+ }
+ countdownTimerRef.current = setInterval(() => {
+ setCountdown((c) => Math.max(0, c - 1));
+ }, 1000);
+ countdownActiveRef.current = true;
+ };
+
+ // Quand le compteur a réellement démarré ET atteint 0, on démarre
+ useEffect(() => {
+ if (!isPreparing) return;
+ if (!countdownActiveRef.current) return; // évite l'auto-start
+
+ if (countdown === 0 && !startedRef.current) {
+ startedRef.current = true;
+ if (countdownTimerRef.current) {
+ clearInterval(countdownTimerRef.current);
+ countdownTimerRef.current = null;
+ }
+ countdownActiveRef.current = false;
+ // Bascule après rendu de la frame courante
+ requestAnimationFrame(() => {
+ setIsPreparing(false);
+ setShowProgress(true);
+ void startRecordingWithMusic();
+ });
+ }
+ }, [countdown, isPreparing]);
+
+ const startRecordingWithMusic = async () => {
+ try {
+ stopRequestedRef.current = false;
+ listenedMsRef.current = 0;
+ incrementDoneRef.current = false;
+
+ setIsRecording(true);
+ setShowProgress(true);
+ const recordPromise = cameraRef.current?.recordAsync?.({
+ mute: true,
+ maxDuration: 600,
+ });
+
+ if (player && songUrl) {
+ try {
+ await player.seekTo?.(0);
+ } catch (_) {}
+ await player.play?.();
+ }
+
+ // Incrément des vues
+ if (!listenTimerRef.current && project?.id) {
+ listenTimerRef.current = setInterval(async () => {
+ try {
+ if (player?.playing) {
+ listenedMsRef.current += 500;
+ if (
+ !incrementDoneRef.current &&
+ listenedMsRef.current >= TIME_BEFORE_INCREMENT_MS
+ ) {
+ incrementDoneRef.current = true;
+ try {
+ await projectsRef
+ .doc(project.id)
+ .set({ views: increment(1) }, { merge: true });
+ } catch (_) {}
+ }
+ }
+ } catch (_) {}
+ }, 500);
+ }
+
+ // Fin du morceau -> stop recording
+ if (!checkSongEndRef.current) {
+ checkSongEndRef.current = setInterval(() => {
+ try {
+ if (!player) return;
+ const duration = (player?.duration || 0) * 1000;
+ const currentTime = (player?.currentTime || 0) * 1000;
+ if (
+ (!player.playing && !stopRequestedRef.current) ||
+ (duration > 0 && currentTime >= duration - 600)
+ ) {
+ stopRequestedRef.current = true;
+ if (checkSongEndRef.current) {
+ clearInterval(checkSongEndRef.current);
+ checkSongEndRef.current = null;
+ }
+ try {
+ cameraRef.current?.stopRecording?.();
+ } catch (_) {}
+ }
+ } catch (_) {}
+ }, 500);
+ }
+
+ const video = await recordPromise;
+
+ if (checkSongEndRef.current) {
+ clearInterval(checkSongEndRef.current);
+ checkSongEndRef.current = null;
+ }
+ try {
+ if (player?.playing) await player.pause?.();
+ } catch (_) {}
+ if (listenTimerRef.current) {
+ clearInterval(listenTimerRef.current);
+ listenTimerRef.current = null;
+ }
+
+ setIsRecording(false);
+ setShowProgress(false);
+
+ if (video?.uri)
+ navigate(Routes.RecordedPlayback, { videoUri: video.uri, project });
+ else navigate(Routes.RecordedPlayback, { project });
+ } catch (e) {
+ console.log("RecordPlayback error:", e);
+ setIsRecording(false);
+ setIsPreparing(false);
+ setShowProgress(false);
+ if (listenTimerRef.current) {
+ clearInterval(listenTimerRef.current);
+ listenTimerRef.current = null;
+ }
+ if (checkSongEndRef.current) {
+ clearInterval(checkSongEndRef.current);
+ checkSongEndRef.current = null;
+ }
+ // Inform the user when using a simulator where recording isn't supported
+ const msg = String(e?.message || e || "");
+ if (/not supported on the simulator/i.test(msg)) {
+ Alert.alert(
+ "Indisponible sur simulateur",
+ "L’enregistrement vidéo n’est pas disponible sur le simulateur. Merci d’utiliser un appareil réel.",
+ [
+ {
+ text: "OK",
+ onPress: () => {
+ try {
+ goBack();
+ } catch (_) {}
+ },
+ },
+ ],
+ { cancelable: false }
+ );
+ }
+ }
+ };
+
+ const permissionsGranted = !!cameraPermission?.granted;
+
+ return (
+
+
+
+
+
+
+ {/* Overlay de compte à rebours : on affiche 5→1 pour éviter l'effet visuel à 1 */}
+ {isPreparing && countdown >= 1 && !showProgress && (
+
+
+ {countdown}
+
+
+ )}
+
+ {/* Permission prompt */}
+ {!permissionsGranted && (
+
+ {
+ try {
+ if (!cameraPermission?.granted)
+ await requestCameraPermission();
+ } catch (_) {}
+ }}
+ />
+
+ )}
+
+
+ {/* Start button */}
+ {permissionsGranted && !isPreparing && !isRecording && (
+
+ )}
+
+ {/* Progress circulaire */}
+ {permissionsGranted && (isRecording || showProgress) && (
+
+
+
+
+
+
+ )}
+
+
+ {/* CreateLyricsHeader overlay outside of CameraView */}
+
+
+ {(isRecording || showProgress) && alignedWords?.length > 0 ? (
+
+ ) : (
+
+ L'enregistrement de ta vidéo commencera lorsque tu lanceras ta
+ musique, et s'arrêtera à la fin du morceau.
+
+ )}
+
+
+
+
+ );
+};
+
+// Progress ring SVG
+const ProgressRing = ({ size = 50, strokeWidth = 12, progress = 0 }) => {
+ const r = size / 2 - strokeWidth / 2;
+ const c = 2 * Math.PI * r;
+ const clamped = Math.max(0, Math.min(1, progress || 0));
+ const offset = c * (1 - clamped);
+ return (
+
+ );
+};
+
+export default RecordPlayback;
+
+// Render previous/current/next line to reduce jumpiness
+const KaraokeLines = ({ lines = [], currentLineIdx = -1 }) => {
+ const prev = currentLineIdx > 0 ? lines[currentLineIdx - 1]?.text : "";
+ const curr = currentLineIdx >= 0 ? lines[currentLineIdx]?.text : "";
+ const next =
+ currentLineIdx + 1 < lines.length ? lines[currentLineIdx + 1]?.text : "";
+ return (
+
+ {/* {prev ? (
+
+ {prev}
+
+ ) : null} */}
+
+ {curr}
+
+ {next ? (
+
+ {next}
+
+ ) : null}
+
+ );
+};
diff --git a/src/screens/Studio/SongReady.js b/src/screens/Studio/SongReady.js
index fe9068c..5569a1e 100644
--- a/src/screens/Studio/SongReady.js
+++ b/src/screens/Studio/SongReady.js
@@ -35,10 +35,10 @@ const SongReady = () => {
1: { pos: 0, dur: 0 },
});
const player0 = useAudioPlayer(
- musicUrls[0] ? { uri: musicUrls[0] } : undefined,
+ musicUrls[0] ? { uri: musicUrls[0] } : undefined
);
const player1 = useAudioPlayer(
- musicUrls[1] ? { uri: musicUrls[1] } : undefined,
+ musicUrls[1] ? { uri: musicUrls[1] } : undefined
);
const wasPlayingBeforeSeek = useRef({ 0: false, 1: false });
@@ -146,7 +146,7 @@ const SongReady = () => {
player1?.pause?.();
} catch {}
};
- }, [player0, player1]),
+ }, [player0, player1])
);
useEffect(() => {
@@ -230,7 +230,7 @@ const SongReady = () => {
} catch (e) {
console.log(
"SongReady pause on seek start",
- e?.message,
+ e?.message
);
}
}}