fix: blur and music duration

This commit is contained in:
2025-11-04 14:10:43 +01:00
parent 47187bd6d8
commit af47934477
10 changed files with 323 additions and 81 deletions
+103 -2
View File
@@ -2,7 +2,7 @@
import { useFocusEffect } from "@react-navigation/native";
import { BlurView } from "expo-blur";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { Image, Platform, Pressable, Text, View } from "react-native";
import { Image, Pressable, Text, View } from "react-native";
import { responsiveHeight } from "react-native-responsive-dimensions";
import { background, icons } from "../../assets";
import alert from "../../components/Alert";
@@ -35,6 +35,9 @@ const SongReady = () => {
0: { pos: 0, dur: 0 },
1: { pos: 0, dur: 0 },
});
console.log("progress info", JSON.stringify(progressInfo, null, 2));
const player0 = useSharedAudioPlayer(
musicUrls[0] ? { uri: musicUrls[0] } : undefined,
{
@@ -66,6 +69,10 @@ const SongReady = () => {
}
);
const wasPlayingBeforeSeek = useRef({ 0: false, 1: false });
const prefetchedRef = useRef({
0: { url: null, done: false },
1: { url: null, done: false },
});
// Sync URLs from provider's selectedProject
useEffect(() => {
@@ -75,6 +82,100 @@ const SongReady = () => {
setMusicUrls(urls);
}, [selectedProject?.musicUrls]);
const firstUrl = musicUrls[0] ?? null;
const secondUrl = musicUrls[1] ?? null;
useEffect(() => {
let isCancelled = false;
const waitForDuration = async (index) => {
const getDurationSeconds = () => {
const targetPlayer = index === 0 ? player0 : player1;
if (!targetPlayer) return 0;
const raw = Number(targetPlayer.duration || 0);
return Number.isFinite(raw) ? raw : 0;
};
const start = Date.now();
while (!isCancelled) {
const durationSeconds = getDurationSeconds();
if (durationSeconds > 0) {
const durationMs = Math.round(durationSeconds * 1000);
setProgressInfo((prev) => {
const current = prev?.[index] || { pos: 0, dur: 0 };
if (Math.abs(current.dur - durationMs) < 5) return prev;
return {
...prev,
[index]: {
...current,
dur: durationMs,
},
};
});
return true;
}
if (Date.now() - start > 6000) {
break;
}
await new Promise((resolve) => setTimeout(resolve, 150));
}
return false;
};
const prefetch = async () => {
const entries = [
[0, firstUrl, player0],
[1, secondUrl, player1],
];
for (const [idx, url, player] of entries) {
const cacheEntry = prefetchedRef.current[idx];
if (!url || !player?.load) {
if (cacheEntry) {
cacheEntry.url = url ?? null;
cacheEntry.done = false;
}
continue;
}
if (cacheEntry && cacheEntry.url === url && cacheEntry.done) {
continue;
}
if (cacheEntry) {
cacheEntry.url = url;
cacheEntry.done = false;
}
try {
await player.load({ startPositionMs: 0 });
const resolved = await waitForDuration(idx);
if (cacheEntry && !isCancelled) {
cacheEntry.done = resolved;
}
} catch (err) {
if (cacheEntry) {
cacheEntry.done = false;
}
if (!isCancelled) {
console.log("SongReady preload error", err?.message);
}
}
if (isCancelled) {
break;
}
}
};
prefetch();
return () => {
isCancelled = true;
};
}, [firstUrl, secondUrl, player0, player1]);
// Sync progression depuis les players
useEffect(() => {
// Ensure we consistently work with milliseconds whatever the platform
@@ -264,7 +365,7 @@ const SongReady = () => {
]}
>
<BlurView
intensity={Platform.OS !== "ios" ? 10 : 40}
intensity={40}
tint="dark"
style={{
borderRadius: 18,