fix playback mobile
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 281 KiB |
@@ -13,7 +13,10 @@ const MusicLandHeader = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<View style={{ alignItems: "center", gap: 16 }}>
|
<View style={{ alignItems: "center", gap: 16 }}>
|
||||||
<Image source={icons.musicLandLogo} />
|
<Image
|
||||||
|
source={icons.musicLandLogo}
|
||||||
|
style={{ alignSelf: "center", height: 150, resizeMode: "contain" }}
|
||||||
|
/>
|
||||||
<View style={{ width: "100%", ...Style.containerRow, gap: 16 }}>
|
<View style={{ width: "100%", ...Style.containerRow, gap: 16 }}>
|
||||||
<Pressable
|
<Pressable
|
||||||
style={{ width: 24, height: 24, ...Style.containerCenter }}
|
style={{ width: 24, height: 24, ...Style.containerCenter }}
|
||||||
|
|||||||
@@ -217,7 +217,10 @@ const HitParade = () => {
|
|||||||
blurIntensity={isWeb ? 0 : 0}
|
blurIntensity={isWeb ? 0 : 0}
|
||||||
>
|
>
|
||||||
<View style={{ gap: 12, flex: 1 }}>
|
<View style={{ gap: 12, flex: 1 }}>
|
||||||
<Image source={icons.musicLandLogo} style={{ alignSelf: "center" }} />
|
<Image
|
||||||
|
source={icons.musicLandLogo}
|
||||||
|
style={{ alignSelf: "center", height: 150, resizeMode: "contain" }}
|
||||||
|
/>
|
||||||
<View style={{ flex: 1, gap: 24 }}>
|
<View style={{ flex: 1, gap: 24 }}>
|
||||||
<View style={{ gap: 11 }}>
|
<View style={{ gap: 11 }}>
|
||||||
<Pressable style={{ position: "absolute", right: 8, top: 20 }}>
|
<Pressable style={{ position: "absolute", right: 8, top: 20 }}>
|
||||||
|
|||||||
@@ -58,7 +58,10 @@ const Library = () => {
|
|||||||
return (
|
return (
|
||||||
<Page backgroundImg={background.libraryBG} headerType="NONE">
|
<Page backgroundImg={background.libraryBG} headerType="NONE">
|
||||||
<View style={{ gap: 17, paddingBottom: 20 }}>
|
<View style={{ gap: 17, paddingBottom: 20 }}>
|
||||||
<Image source={icons.musicLandLogo} style={{ alignSelf: "center" }} />
|
<Image
|
||||||
|
source={icons.musicLandLogo}
|
||||||
|
style={{ alignSelf: "center", height: 150, resizeMode: "contain" }}
|
||||||
|
/>
|
||||||
<Pressable onPress={() => navigate(Routes.Research)}>
|
<Pressable onPress={() => navigate(Routes.Research)}>
|
||||||
<SearchBar
|
<SearchBar
|
||||||
textInputProps={{
|
textInputProps={{
|
||||||
|
|||||||
@@ -135,7 +135,10 @@ const Library = () => {
|
|||||||
<View
|
<View
|
||||||
style={{ gap: 17, paddingBottom: 20, zIndex: dropdownVisible ? 40 : 1 }}
|
style={{ gap: 17, paddingBottom: 20, zIndex: dropdownVisible ? 40 : 1 }}
|
||||||
>
|
>
|
||||||
<Image source={icons.musicLandLogo} style={{ alignSelf: "center" }} />
|
<Image
|
||||||
|
source={icons.musicLandLogo}
|
||||||
|
style={{ alignSelf: "center", height: 150, resizeMode: "contain" }}
|
||||||
|
/>
|
||||||
<View
|
<View
|
||||||
ref={searchWrapperRef}
|
ref={searchWrapperRef}
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -23,11 +23,16 @@ import { FONT_FAMILY } from "../../styles/Fonts";
|
|||||||
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
|
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
|
||||||
|
|
||||||
const TIME_BEFORE_INCREMENT_MS = 20000; // 20s
|
const TIME_BEFORE_INCREMENT_MS = 20000; // 20s
|
||||||
|
const LOG_PREFIX = "[RecordPlayback]";
|
||||||
|
const log =
|
||||||
|
typeof __DEV__ === "undefined" || __DEV__
|
||||||
|
? (...args) => console.log(LOG_PREFIX, ...args)
|
||||||
|
: () => {};
|
||||||
|
|
||||||
const RecordPlayback = ({ route }) => {
|
const RecordPlayback = ({ route }) => {
|
||||||
const { top, bottom } = useSafeAreaInsets();
|
const { top, bottom } = useSafeAreaInsets();
|
||||||
const { project } = route.params || {};
|
const { project } = route.params || {};
|
||||||
console.log("project is : ", JSON.stringify(project, null, 2));
|
log("Route params received", { hasProject: !!project });
|
||||||
const projectId = project?.id;
|
const projectId = project?.id;
|
||||||
const songIndex = project?.songIndex;
|
const songIndex = project?.songIndex;
|
||||||
// Permissions
|
// Permissions
|
||||||
@@ -41,6 +46,8 @@ const RecordPlayback = ({ route }) => {
|
|||||||
const stopRequestedRef = useRef(false);
|
const stopRequestedRef = useRef(false);
|
||||||
const startedRef = useRef(false); // empêche les doubles démarrages
|
const startedRef = useRef(false); // empêche les doubles démarrages
|
||||||
const countdownActiveRef = useRef(false); // évite le déclenchement avant 1er tick
|
const countdownActiveRef = useRef(false); // évite le déclenchement avant 1er tick
|
||||||
|
const playbackStartedRef = useRef(false); // devient vrai lorsque l'audio progresse réellement
|
||||||
|
const progressLogRef = useRef({ bucket: -1, lastPos: -1, lastDur: -1 });
|
||||||
|
|
||||||
// Compteurs vues
|
// Compteurs vues
|
||||||
const listenedMsRef = useRef(0);
|
const listenedMsRef = useRef(0);
|
||||||
@@ -69,6 +76,10 @@ const RecordPlayback = ({ route }) => {
|
|||||||
metadata: { projectId, screen: "RecordPlayback" },
|
metadata: { projectId, screen: "RecordPlayback" },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
log("Screen params", { projectId, songUrl, songIndex });
|
||||||
|
}, [projectId, songUrl, songIndex]);
|
||||||
|
|
||||||
const musicIndex = useMemo(() => {
|
const musicIndex = useMemo(() => {
|
||||||
const i = Number(songIndex);
|
const i = Number(songIndex);
|
||||||
return Number.isFinite(i) && i >= 0 ? i : 0;
|
return Number.isFinite(i) && i >= 0 ? i : 0;
|
||||||
@@ -140,6 +151,9 @@ const RecordPlayback = ({ route }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
listenedMsRef.current = 0;
|
listenedMsRef.current = 0;
|
||||||
incrementDoneRef.current = false;
|
incrementDoneRef.current = false;
|
||||||
|
progressLogRef.current = { bucket: -1, lastPos: -1, lastDur: -1 };
|
||||||
|
playbackStartedRef.current = false;
|
||||||
|
log("Song URL changed, reset counters", { songUrl });
|
||||||
}, [songUrl]);
|
}, [songUrl]);
|
||||||
|
|
||||||
// Poll player -> progress ring
|
// Poll player -> progress ring
|
||||||
@@ -149,7 +163,39 @@ const RecordPlayback = ({ route }) => {
|
|||||||
try {
|
try {
|
||||||
const dur = (player?.duration || 0) * 1000;
|
const dur = (player?.duration || 0) * 1000;
|
||||||
const pos = (player?.currentTime || 0) * 1000;
|
const pos = (player?.currentTime || 0) * 1000;
|
||||||
setProgressInfo({ pos, dur });
|
if (!playbackStartedRef.current && (player?.playing || pos > 0)) {
|
||||||
|
playbackStartedRef.current = true;
|
||||||
|
log("Playback detected", { pos, dur });
|
||||||
|
}
|
||||||
|
setProgressInfo((prev) => {
|
||||||
|
if (prev.pos === pos && prev.dur === dur) return prev;
|
||||||
|
return { pos, dur };
|
||||||
|
});
|
||||||
|
if (dur <= 0) {
|
||||||
|
if (progressLogRef.current.lastDur !== 0) {
|
||||||
|
progressLogRef.current = { bucket: -1, lastPos: pos, lastDur: 0 };
|
||||||
|
log("Progress waiting for duration", {
|
||||||
|
pos,
|
||||||
|
playing: player?.playing,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
progressLogRef.current.lastPos = pos;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const pct = Math.max(0, Math.min(1, pos / dur));
|
||||||
|
const bucket = Math.floor(pct * 10);
|
||||||
|
const { bucket: prevBucket } = progressLogRef.current;
|
||||||
|
if (bucket !== prevBucket) {
|
||||||
|
log("Progress update", {
|
||||||
|
bucket,
|
||||||
|
pct: Number.isFinite(pct) ? Number(pct.toFixed(2)) : pct,
|
||||||
|
pos,
|
||||||
|
dur,
|
||||||
|
playing: player?.playing,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
progressLogRef.current = { bucket, lastPos: pos, lastDur: dur };
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}, 250);
|
}, 250);
|
||||||
return () => clearInterval(id);
|
return () => clearInterval(id);
|
||||||
@@ -172,7 +218,12 @@ const RecordPlayback = ({ route }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
if (!cameraPermission?.granted) await requestCameraPermission();
|
if (!cameraPermission?.granted) {
|
||||||
|
log("Requesting camera permission on mount");
|
||||||
|
await requestCameraPermission();
|
||||||
|
} else {
|
||||||
|
log("Camera permission already granted on mount");
|
||||||
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
})();
|
})();
|
||||||
return () => {
|
return () => {
|
||||||
@@ -183,6 +234,7 @@ const RecordPlayback = ({ route }) => {
|
|||||||
countdownTimerRef.current = null;
|
countdownTimerRef.current = null;
|
||||||
listenTimerRef.current = null;
|
listenTimerRef.current = null;
|
||||||
checkSongEndRef.current = null;
|
checkSongEndRef.current = null;
|
||||||
|
log("Cleanup on unmount, cleared timers");
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
};
|
};
|
||||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
@@ -197,10 +249,12 @@ const RecordPlayback = ({ route }) => {
|
|||||||
if (listenTimerRef.current) {
|
if (listenTimerRef.current) {
|
||||||
clearInterval(listenTimerRef.current);
|
clearInterval(listenTimerRef.current);
|
||||||
listenTimerRef.current = null;
|
listenTimerRef.current = null;
|
||||||
|
log("listenTimerRef cleared");
|
||||||
}
|
}
|
||||||
if (checkSongEndRef.current) {
|
if (checkSongEndRef.current) {
|
||||||
clearInterval(checkSongEndRef.current);
|
clearInterval(checkSongEndRef.current);
|
||||||
checkSongEndRef.current = null;
|
checkSongEndRef.current = null;
|
||||||
|
log("checkSongEndRef cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
startedRef.current = false;
|
startedRef.current = false;
|
||||||
@@ -208,6 +262,9 @@ const RecordPlayback = ({ route }) => {
|
|||||||
countdownActiveRef.current = false;
|
countdownActiveRef.current = false;
|
||||||
listenedMsRef.current = 0;
|
listenedMsRef.current = 0;
|
||||||
incrementDoneRef.current = false;
|
incrementDoneRef.current = false;
|
||||||
|
playbackStartedRef.current = false;
|
||||||
|
progressLogRef.current = { bucket: -1, lastPos: -1, lastDur: -1 };
|
||||||
|
log("Session reset");
|
||||||
|
|
||||||
setIsPreparing(false);
|
setIsPreparing(false);
|
||||||
setIsRecording(false);
|
setIsRecording(false);
|
||||||
@@ -225,6 +282,7 @@ const RecordPlayback = ({ route }) => {
|
|||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
|
log("Screen focused, resetting session");
|
||||||
void resetSession();
|
void resetSession();
|
||||||
return () => {};
|
return () => {};
|
||||||
}, [resetSession])
|
}, [resetSession])
|
||||||
@@ -232,7 +290,11 @@ const RecordPlayback = ({ route }) => {
|
|||||||
|
|
||||||
// Lancer le compte à rebours (le tick décrémente uniquement)
|
// Lancer le compte à rebours (le tick décrémente uniquement)
|
||||||
const startCountdownThenRecord = async () => {
|
const startCountdownThenRecord = async () => {
|
||||||
if (!songUrl) return;
|
if (!songUrl) {
|
||||||
|
log("startCountdownThenRecord aborted: missing song URL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log("startCountdownThenRecord invoked", { projectId, songUrl });
|
||||||
await resetSession();
|
await resetSession();
|
||||||
setIsPreparing(true);
|
setIsPreparing(true);
|
||||||
setShowProgress(false);
|
setShowProgress(false);
|
||||||
@@ -247,6 +309,7 @@ const RecordPlayback = ({ route }) => {
|
|||||||
setCountdown((c) => Math.max(0, c - 1));
|
setCountdown((c) => Math.max(0, c - 1));
|
||||||
}, 1000);
|
}, 1000);
|
||||||
countdownActiveRef.current = true;
|
countdownActiveRef.current = true;
|
||||||
|
log("Countdown timer armed");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Quand le compteur a réellement démarré ET atteint 0, on démarre
|
// Quand le compteur a réellement démarré ET atteint 0, on démarre
|
||||||
@@ -255,6 +318,7 @@ const RecordPlayback = ({ route }) => {
|
|||||||
if (!countdownActiveRef.current) return; // évite l'auto-start
|
if (!countdownActiveRef.current) return; // évite l'auto-start
|
||||||
|
|
||||||
if (countdown === 0 && !startedRef.current) {
|
if (countdown === 0 && !startedRef.current) {
|
||||||
|
log("Countdown complete, launching recording sequence");
|
||||||
startedRef.current = true;
|
startedRef.current = true;
|
||||||
if (countdownTimerRef.current) {
|
if (countdownTimerRef.current) {
|
||||||
clearInterval(countdownTimerRef.current);
|
clearInterval(countdownTimerRef.current);
|
||||||
@@ -278,20 +342,88 @@ const RecordPlayback = ({ route }) => {
|
|||||||
|
|
||||||
setIsRecording(true);
|
setIsRecording(true);
|
||||||
setShowProgress(true);
|
setShowProgress(true);
|
||||||
const recordPromise = cameraRef.current?.recordAsync?.({
|
playbackStartedRef.current = false;
|
||||||
mute: true,
|
progressLogRef.current = { bucket: -1, lastPos: -1, lastDur: -1 };
|
||||||
maxDuration: 600,
|
log("startRecordingWithMusic", {
|
||||||
|
hasPlayer: !!player,
|
||||||
|
songUrl,
|
||||||
|
hasCamera: !!cameraRef.current,
|
||||||
});
|
});
|
||||||
|
const recordPromise = (() => {
|
||||||
|
const camera = cameraRef.current;
|
||||||
|
if (!camera) throw new Error("Caméra indisponible");
|
||||||
|
|
||||||
|
if (typeof camera.recordAsync === "function") {
|
||||||
|
log("Camera supports recordAsync");
|
||||||
|
return camera.recordAsync({ mute: true, maxDuration: 600 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof camera.startRecording === "function") {
|
||||||
|
// Expo CameraView (SDK 52) expose startRecording au lieu de recordAsync
|
||||||
|
log("Camera using startRecording fallback");
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let settled = false;
|
||||||
|
try {
|
||||||
|
camera.startRecording({
|
||||||
|
mute: true,
|
||||||
|
maxDuration: 600,
|
||||||
|
onRecordingFinished: (video) => {
|
||||||
|
settled = true;
|
||||||
|
log("Camera onRecordingFinished", { hasUri: !!video?.uri });
|
||||||
|
resolve(video);
|
||||||
|
},
|
||||||
|
onRecordingError: (error) => {
|
||||||
|
if (settled) return;
|
||||||
|
log("Camera onRecordingError", {
|
||||||
|
message: error?.message || String(error || ""),
|
||||||
|
});
|
||||||
|
const err =
|
||||||
|
error instanceof Error
|
||||||
|
? error
|
||||||
|
: new Error(String(error || "Recording error"));
|
||||||
|
reject(err);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
log("Camera startRecording threw", {
|
||||||
|
message: error?.message || String(error || ""),
|
||||||
|
});
|
||||||
|
reject(
|
||||||
|
error instanceof Error
|
||||||
|
? error
|
||||||
|
: new Error(String(error || "Recording start failed"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(
|
||||||
|
"L'enregistrement vidéo n'est pas supporté sur cet appareil."
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
|
||||||
if (player && songUrl) {
|
if (player && songUrl) {
|
||||||
try {
|
try {
|
||||||
|
log("Seeking player to start");
|
||||||
await player.seekTo?.(0);
|
await player.seekTo?.(0);
|
||||||
} catch (_) {}
|
} catch (error) {
|
||||||
await player.play?.();
|
log("player.seekTo failed", {
|
||||||
|
message: error?.message || String(error || ""),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await player.play?.();
|
||||||
|
log("player.play invoked");
|
||||||
|
} catch (error) {
|
||||||
|
log("player.play failed", {
|
||||||
|
message: error?.message || String(error || ""),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incrément des vues
|
// Incrément des vues
|
||||||
if (!listenTimerRef.current && project?.id) {
|
if (!listenTimerRef.current && project?.id) {
|
||||||
|
log("listenTimerRef armed", { projectId: project.id });
|
||||||
listenTimerRef.current = setInterval(async () => {
|
listenTimerRef.current = setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
if (player?.playing) {
|
if (player?.playing) {
|
||||||
@@ -301,10 +433,12 @@ const RecordPlayback = ({ route }) => {
|
|||||||
listenedMsRef.current >= TIME_BEFORE_INCREMENT_MS
|
listenedMsRef.current >= TIME_BEFORE_INCREMENT_MS
|
||||||
) {
|
) {
|
||||||
incrementDoneRef.current = true;
|
incrementDoneRef.current = true;
|
||||||
|
log("Views increment threshold reached");
|
||||||
try {
|
try {
|
||||||
await projectsRef
|
await projectsRef
|
||||||
.doc(project.id)
|
.doc(project.id)
|
||||||
.set({ views: increment(1) }, { merge: true });
|
.set({ views: increment(1) }, { merge: true });
|
||||||
|
log("Views incremented");
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,15 +448,31 @@ const RecordPlayback = ({ route }) => {
|
|||||||
|
|
||||||
// Fin du morceau -> stop recording
|
// Fin du morceau -> stop recording
|
||||||
if (!checkSongEndRef.current) {
|
if (!checkSongEndRef.current) {
|
||||||
|
log("Song end watcher armed");
|
||||||
checkSongEndRef.current = setInterval(() => {
|
checkSongEndRef.current = setInterval(() => {
|
||||||
try {
|
try {
|
||||||
if (!player) return;
|
if (!player || stopRequestedRef.current) return;
|
||||||
const duration = (player?.duration || 0) * 1000;
|
const duration = (player?.duration || 0) * 1000;
|
||||||
const currentTime = (player?.currentTime || 0) * 1000;
|
const currentTime = (player?.currentTime || 0) * 1000;
|
||||||
if (
|
if (
|
||||||
(!player.playing && !stopRequestedRef.current) ||
|
!playbackStartedRef.current &&
|
||||||
(duration > 0 && currentTime >= duration - 600)
|
(player?.playing || currentTime > 0)
|
||||||
) {
|
) {
|
||||||
|
playbackStartedRef.current = true;
|
||||||
|
}
|
||||||
|
const nearEnd = duration > 0 && currentTime >= duration - 600;
|
||||||
|
const playbackEnded =
|
||||||
|
playbackStartedRef.current &&
|
||||||
|
!player.playing &&
|
||||||
|
currentTime > 1200;
|
||||||
|
|
||||||
|
if (nearEnd || playbackEnded) {
|
||||||
|
log("Requesting stopRecording", {
|
||||||
|
reason: nearEnd ? "nearEnd" : "playbackEnded",
|
||||||
|
duration,
|
||||||
|
currentTime,
|
||||||
|
playing: player?.playing,
|
||||||
|
});
|
||||||
stopRequestedRef.current = true;
|
stopRequestedRef.current = true;
|
||||||
if (checkSongEndRef.current) {
|
if (checkSongEndRef.current) {
|
||||||
clearInterval(checkSongEndRef.current);
|
clearInterval(checkSongEndRef.current);
|
||||||
@@ -330,6 +480,7 @@ const RecordPlayback = ({ route }) => {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
cameraRef.current?.stopRecording?.();
|
cameraRef.current?.stopRecording?.();
|
||||||
|
log("stopRecording triggered");
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
@@ -337,10 +488,12 @@ const RecordPlayback = ({ route }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const video = await recordPromise;
|
const video = await recordPromise;
|
||||||
|
log("Recording promise resolved", { hasVideo: !!video?.uri });
|
||||||
|
|
||||||
if (checkSongEndRef.current) {
|
if (checkSongEndRef.current) {
|
||||||
clearInterval(checkSongEndRef.current);
|
clearInterval(checkSongEndRef.current);
|
||||||
checkSongEndRef.current = null;
|
checkSongEndRef.current = null;
|
||||||
|
log("checkSongEndRef cleared");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (player?.playing) await player.pause?.();
|
if (player?.playing) await player.pause?.();
|
||||||
@@ -348,15 +501,30 @@ const RecordPlayback = ({ route }) => {
|
|||||||
if (listenTimerRef.current) {
|
if (listenTimerRef.current) {
|
||||||
clearInterval(listenTimerRef.current);
|
clearInterval(listenTimerRef.current);
|
||||||
listenTimerRef.current = null;
|
listenTimerRef.current = null;
|
||||||
|
log("listenTimerRef cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsRecording(false);
|
setIsRecording(false);
|
||||||
setShowProgress(false);
|
setShowProgress(false);
|
||||||
|
log("Recording flow completed", { hasVideo: !!video?.uri });
|
||||||
|
playbackStartedRef.current = false;
|
||||||
|
progressLogRef.current = { bucket: -1, lastPos: -1, lastDur: -1 };
|
||||||
|
|
||||||
if (video?.uri)
|
if (video?.uri) {
|
||||||
|
log("Navigating to RecordedPlayback with video", {
|
||||||
|
uriLength: video.uri.length,
|
||||||
|
});
|
||||||
navigate(Routes.RecordedPlayback, { videoUri: video.uri, project });
|
navigate(Routes.RecordedPlayback, { videoUri: video.uri, project });
|
||||||
else navigate(Routes.RecordedPlayback, { project });
|
} else {
|
||||||
|
log("Navigating to RecordedPlayback without video", {
|
||||||
|
hasVideo: !!video,
|
||||||
|
});
|
||||||
|
navigate(Routes.RecordedPlayback, { project });
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
log("startRecordingWithMusic error", {
|
||||||
|
message: e?.message || String(e || ""),
|
||||||
|
});
|
||||||
console.log("RecordPlayback error:", e);
|
console.log("RecordPlayback error:", e);
|
||||||
setIsRecording(false);
|
setIsRecording(false);
|
||||||
setIsPreparing(false);
|
setIsPreparing(false);
|
||||||
@@ -364,11 +532,15 @@ const RecordPlayback = ({ route }) => {
|
|||||||
if (listenTimerRef.current) {
|
if (listenTimerRef.current) {
|
||||||
clearInterval(listenTimerRef.current);
|
clearInterval(listenTimerRef.current);
|
||||||
listenTimerRef.current = null;
|
listenTimerRef.current = null;
|
||||||
|
log("listenTimerRef cleared (error path)");
|
||||||
}
|
}
|
||||||
if (checkSongEndRef.current) {
|
if (checkSongEndRef.current) {
|
||||||
clearInterval(checkSongEndRef.current);
|
clearInterval(checkSongEndRef.current);
|
||||||
checkSongEndRef.current = null;
|
checkSongEndRef.current = null;
|
||||||
|
log("checkSongEndRef cleared (error path)");
|
||||||
}
|
}
|
||||||
|
playbackStartedRef.current = false;
|
||||||
|
progressLogRef.current = { bucket: -1, lastPos: -1, lastDur: -1 };
|
||||||
// Inform the user when using a simulator where recording isn't supported
|
// 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)) {
|
if (/not supported on the simulator/i.test(msg)) {
|
||||||
@@ -393,6 +565,10 @@ const RecordPlayback = ({ route }) => {
|
|||||||
|
|
||||||
const permissionsGranted = !!cameraPermission?.granted;
|
const permissionsGranted = !!cameraPermission?.granted;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
log("Camera permission state updated", { granted: permissionsGranted });
|
||||||
|
}, [permissionsGranted]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1 }}>
|
||||||
<CameraView
|
<CameraView
|
||||||
@@ -400,6 +576,7 @@ const RecordPlayback = ({ route }) => {
|
|||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
facing="front"
|
facing="front"
|
||||||
mode="video"
|
mode="video"
|
||||||
|
mute
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
Reference in New Issue
Block a user