mirror of
https://github.com/R0m1k3/podcastic.git
synced 2026-10-11 17:26:20 +02:00
fix: podcasts ne lisent pas à cause du blocage CORS
crossOrigin="anonymous" sur <audio> forçait le navigateur à exiger les headers CORS des serveurs audio. Les hébergeurs sans Access-Control-Allow-Origin bloquaient le chargement entièrement. - Retire crossOrigin="anonymous" de l'élément <audio> - Ajoute visualisation simulée dans l'egaliseur quand les données de fréquence réelles sont indisponibles (audio cross-origin) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
1 parent
e7e971dbae
commit
ee04841d9e
3 files changed
+38
-16
No files matched your search
@@ -14,7 +14,12 @@
|
|||||||
"Bash(git pull *)",
|
"Bash(git pull *)",
|
||||||
"Bash(git stash *)",
|
"Bash(git stash *)",
|
||||||
"Bash(git fetch *)",
|
"Bash(git fetch *)",
|
||||||
"Bash(rtk npx *)"
|
"Bash(rtk npx *)",
|
||||||
|
"Bash(echo \"EXIT:$?\")",
|
||||||
|
"Bash(git -c core.editor=\"echo\" rebase --continue)",
|
||||||
|
"Bash(cat .git/rebase-merge/interactive)",
|
||||||
|
"Bash(ls .git/rebase-merge/)",
|
||||||
|
"Bash(git *)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,7 @@ export default function AudioVisualizer({ height = 80 }: AudioVisualizerProps) {
|
|||||||
const playingRef = useRef(isPlaying);
|
const playingRef = useRef(isPlaying);
|
||||||
const getDataRef = useRef(getFrequencyData);
|
const getDataRef = useRef(getFrequencyData);
|
||||||
const timeRef = useRef({ currentTime, duration });
|
const timeRef = useRef({ currentTime, duration });
|
||||||
|
const hasRealDataRef = useRef(false);
|
||||||
|
|
||||||
useEffect(() => { playingRef.current = isPlaying; }, [isPlaying]);
|
useEffect(() => { playingRef.current = isPlaying; }, [isPlaying]);
|
||||||
useEffect(() => { getDataRef.current = getFrequencyData; }, [getFrequencyData]);
|
useEffect(() => { getDataRef.current = getFrequencyData; }, [getFrequencyData]);
|
||||||
@@ -54,21 +55,38 @@ export default function AudioVisualizer({ height = 80 }: AudioVisualizerProps) {
|
|||||||
const progress = dur > 0 ? ct / dur : 0;
|
const progress = dur > 0 ? ct / dur : 0;
|
||||||
const playing = playingRef.current;
|
const playing = playingRef.current;
|
||||||
|
|
||||||
// Update heights from frequency data (every frame for fluidity)
|
// Detect if real frequency data is available (CORS allows it)
|
||||||
if (raw && playing) {
|
if (raw && playing) {
|
||||||
for (let i = 0; i < NUM_POINTS; i++) {
|
const sum = raw.reduce((a, b) => a + b, 0);
|
||||||
const bucketSize = raw.length / NUM_POINTS;
|
hasRealDataRef.current = sum > 0;
|
||||||
const startIdx = Math.floor(i * bucketSize);
|
}
|
||||||
const endIdx = Math.floor((i + 1) * bucketSize);
|
|
||||||
let sum = 0;
|
// Update heights
|
||||||
let count = 0;
|
if (playing) {
|
||||||
for (let j = startIdx; j < endIdx && j < raw.length; j++) {
|
if (raw && hasRealDataRef.current) {
|
||||||
sum += raw[j];
|
// Real frequency data from Web Audio API
|
||||||
count++;
|
for (let i = 0; i < NUM_POINTS; i++) {
|
||||||
|
const bucketSize = raw.length / NUM_POINTS;
|
||||||
|
const startIdx = Math.floor(i * bucketSize);
|
||||||
|
const endIdx = Math.floor((i + 1) * bucketSize);
|
||||||
|
let sum = 0;
|
||||||
|
let count = 0;
|
||||||
|
for (let j = startIdx; j < endIdx && j < raw.length; j++) {
|
||||||
|
sum += raw[j];
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
const avg = count > 0 ? sum / count : 0;
|
||||||
|
const target = (avg / 255) * MAX_AMPLITUDE;
|
||||||
|
hts[i] += (target - hts[i]) * 0.25;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Simulated visualization for cross-origin audio (no CORS)
|
||||||
|
for (let i = 0; i < NUM_POINTS; i++) {
|
||||||
|
const wave = Math.sin(frame * 0.04 + i * 0.35) * 0.5 + 0.5;
|
||||||
|
const noise = Math.sin(frame * 0.07 + i * 1.7) * 0.3 + 0.7;
|
||||||
|
const target = MAX_AMPLITUDE * 0.6 * (0.5 + wave * noise);
|
||||||
|
hts[i] += (target - hts[i]) * 0.18;
|
||||||
}
|
}
|
||||||
const avg = count > 0 ? sum / count : 0;
|
|
||||||
const target = (avg / 255) * MAX_AMPLITUDE;
|
|
||||||
hts[i] += (target - hts[i]) * 0.25;
|
|
||||||
}
|
}
|
||||||
} else if (!playing) {
|
} else if (!playing) {
|
||||||
for (let i = 0; i < NUM_POINTS; i++) {
|
for (let i = 0; i < NUM_POINTS; i++) {
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ export function AudioProvider({ children }: { children: ReactNode }) {
|
|||||||
|
|
||||||
const getFrequencyData = () => {
|
const getFrequencyData = () => {
|
||||||
if (!analyserRef.current || !dataArrayRef.current) return null;
|
if (!analyserRef.current || !dataArrayRef.current) return null;
|
||||||
analyserRef.current.getByteFrequencyData(dataArrayRef.current);
|
analyserRef.current.getByteFrequencyData(dataArrayRef.current as Uint8Array<ArrayBuffer>);
|
||||||
return dataArrayRef.current;
|
return dataArrayRef.current;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -208,7 +208,6 @@ export function AudioProvider({ children }: { children: ReactNode }) {
|
|||||||
key={currentEpisode._id}
|
key={currentEpisode._id}
|
||||||
ref={audioRef}
|
ref={audioRef}
|
||||||
src={currentEpisode.audioUrl}
|
src={currentEpisode.audioUrl}
|
||||||
crossOrigin="anonymous"
|
|
||||||
onTimeUpdate={() => audioRef.current && setCurrentTime(audioRef.current.currentTime)}
|
onTimeUpdate={() => audioRef.current && setCurrentTime(audioRef.current.currentTime)}
|
||||||
onLoadedMetadata={() => audioRef.current && setDuration(audioRef.current.duration)}
|
onLoadedMetadata={() => audioRef.current && setDuration(audioRef.current.duration)}
|
||||||
onPlay={() => setIsPlaying(true)}
|
onPlay={() => setIsPlaying(true)}
|
||||||
|
|||||||
Reference in new issue
Block a user