import useSharedAudioPlayer from "../../hooks/useSharedAudioPlayer"; import React, { useEffect, useMemo, useRef, useState } from "react"; import { Text, View } from "react-native"; import { background } from "../../assets"; import BorderGradientButton from "../../components/BorderGradientButton"; import GradientButton from "../../components/GradientButton"; import MusicLandHeader from "../../components/MusicLandHeader"; import Slider from "../../components/Slider"; import Page from "../../layouts/Page"; import { Routes } from "../../navigation"; import { goBack, navigate } from "../../navigation/NavigationService"; import { gutters, Palette } from "../../styles"; const fmtSeconds = (s) => { const total = Math.max(0, Math.floor(Number(s || 0))); const m = Math.floor(total / 60).toString(); const sec = (total % 60).toString().padStart(2, "0"); return `${m}:${sec}`; }; const toSeconds = (value) => { const n = Number(value ?? 0); if (!Number.isFinite(n) || n < 0) return 0; return n > 10000 ? n / 1000 : n; // heuristique ms → s }; const RecordedPlayback = ({ route }) => { const { videoUri, project } = route.params || {}; const songUrl = project?.songUrl || null; console.log("video uri is : ", videoUri); // AUDIO PLAYER (expo-audio → seconds) const audioPlayer = useSharedAudioPlayer(songUrl ? { uri: songUrl } : undefined, { id: project?.id ? `recorded-${project.id}` : songUrl ? `recorded-${songUrl}` : undefined, title: typeof project?.title === "string" ? project.title : "Sans titre", artist: typeof project?.userName === "string" ? project.userName : "MusicLand", artwork: project?.coverUrl || null, coverUrl: project?.coverUrl || null, metadata: { projectId: project?.id, screen: "RecordedPlayback" }, }); // Optionnel: si tu veux quand même un rendu vidéo sur web si tu as une source const videoElRef = useRef(null); const [progress, setProgress] = useState({ posS: 0, // secondes durS: 0, // secondes playing: false, }); // Démarrage / arrêt useEffect(() => { let mounted = true; const start = async () => { try { if (audioPlayer && songUrl) { await audioPlayer.play?.(); } if (videoElRef.current && videoUri) { // Lecture vidéo HTML5 (muet pour éviter les policies) videoElRef.current.muted = true; videoElRef.current.play().catch(() => {}); } } catch {} }; start(); return () => { mounted = false; try { if (audioPlayer?.playing) audioPlayer.pause?.(); } catch {} try { if (videoElRef.current) { videoElRef.current.pause(); } } catch {} }; }, [audioPlayer, songUrl, videoUri]); // Boucle de progression + éventuelle sync de la vidéo si fournie useEffect(() => { const id = setInterval(() => { try { const durS = toSeconds(audioPlayer?.duration); // secondes const posS = toSeconds(audioPlayer?.currentTime); // secondes setProgress({ posS, durS, playing: !!audioPlayer?.playing, }); // Sync vidéo si on a une source vidéo if ( videoElRef.current && videoUri && !Number.isNaN(videoElRef.current.currentTime) ) { const v = Number(videoElRef.current.currentTime || 0); const drift = Math.abs(v - posS); if (drift > 0.35) { videoElRef.current.currentTime = Math.max(0, posS); } } } catch {} }, 250); return () => clearInterval(id); }, [audioPlayer, videoUri]); // Slider: ratio 0..1 const sliderProgress = useMemo(() => { return progress.durS > 0 ? Math.min(1, progress.posS / progress.durS) : 0; }, [progress]); const onSeek = async (ratio) => { try { const durS = Number(progress.durS || 0); const target = durS * ratio; // secondes if (audioPlayer && durS > 0) { await audioPlayer.seekTo?.(Math.floor(target)); // seek en secondes } if (videoElRef.current && videoUri) { videoElRef.current.currentTime = Math.max(0, target); } } catch {} }; const wasPlayingRef = useRef(false); const onSeekStart = async () => { try { wasPlayingRef.current = !!audioPlayer?.playing; if (audioPlayer?.playing) await audioPlayer.pause?.(); if (videoElRef.current && !videoElRef.current.paused) { videoElRef.current.pause(); } } catch {} }; const onSeekEnd = async () => { try { if (wasPlayingRef.current) { if (audioPlayer) await audioPlayer.play?.(); if (videoElRef.current && videoUri) videoElRef.current.play().catch(() => {}); } } catch {} }; return ( {/* Bloc vidéo optionnel si jamais tu as un videoUri sur web */} {videoUri ? ( ) : ( // Placeholder quand pas de vidéo sur web Aperçu vidéo non disponible sur le web )} { navigate(Routes.DownloadSongs, { action: "playback", uri: videoUri || null, // peut être null sur web project, }); }} /> { try { if (audioPlayer?.playing) audioPlayer.pause?.(); } catch {} try { if (videoElRef.current && !videoElRef.current.paused) videoElRef.current.pause(); } catch {} navigate(Routes.RecordPlayback, { project }); }} /> ); }; export default RecordedPlayback;