fix(reels): garder le son d'origine de la vidéo quand aucune musique n'est choisie

Sans musique (bouton « Passer »), la bande son de la vidéo était supprimée
dès que la voix était activée. Elle sert désormais de fond sonore : conservée
telle quelle, baissée automatiquement sous la voix, puis normalisée avec le
reste. Une musique choisie la remplace toujours.

Même comportement dans l'aperçu, le rendu Remotion et le rendu FFmpeg de
secours. Le bouton indique « Passer (garder le son de la vidéo) ».

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Ze4bs7tpF1KGWUk6ZZSZ4
This commit is contained in:
Claude committed 2026-09-28 08:57:38 +00:00
1 parent 1d47763b29
commit f3113a0f5a
4 files changed
+91 -38

No files matched your search

+2 -2
View File
@@ -694,7 +694,7 @@ export default function NewReel() {
setSelectedTrack(null);
setCurrentStep('text');
}}>
Passer
Passer (garder le son de la vidéo)
</Button>
<Button onClick={() => setCurrentStep('text')}>
Continuer
@@ -1052,7 +1052,7 @@ export default function NewReel() {
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">Musique</span>
<span>{selectedTrack ? selectedTrack.title : 'Aucune'}</span>
<span>{selectedTrack ? selectedTrack.title : 'Son de la vidéo'}</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">Texte</span>
+10 -3
View File
@@ -36,9 +36,16 @@ export const ReelVideo: React.FC<ReelVideoProps> = (props) => {
const videoFrames = Math.max(1, Math.floor(videoDuration * fps));
const totalFrames = Math.max(1, Math.round(totalDuration * fps));
const hasAddedAudio = Boolean(mixedAudioUrl || voiceUrl || musicUrl);
// Le son d'origine est remplacé par la musique choisie ; sans musique, il reste
// en fond (baissé sous la voix). Au rendu final, il est déjà dans la piste mixée.
const keepVideoSound = !mixedAudioUrl && !musicUrl;
const video = (
<OffthreadVideo src={videoUrl} muted={hasAddedAudio} style={{ width: "100%", height: "100%", objectFit: "cover" }} />
<OffthreadVideo
src={videoUrl}
muted={!keepVideoSound}
volume={keepVideoSound && voiceUrl ? (frame) => previewMusicVolume(frame / fps, words, 1, fadeStart) : 1}
style={{ width: "100%", height: "100%", objectFit: "cover" }}
/>
);
return (
@@ -78,7 +85,7 @@ export const ReelVideo: React.FC<ReelVideoProps> = (props) => {
);
};
/** Aperçu : la musique baisse pendant la parole et s'éteint avec le fondu final. */
/** Aperçu : le fond sonore (musique ou son d'origine) baisse pendant la parole et s'éteint avec le fondu final. */
function previewMusicVolume(time: number, words: TimedWord[], base: number, fadeStart: number | null): number {
const speaking = words.some((w) => time >= w.start - 0.2 && time <= w.end + 0.3);
const fade =