fix: blur and music duration
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user