fix: prefer preview-compatible audio recording formats
All checks were successful
Build & Deploy to K3s / build-and-deploy (push) Successful in 35s
All checks were successful
Build & Deploy to K3s / build-and-deploy (push) Successful in 35s
This commit is contained in:
parent
800214976f
commit
21cd789a62
@ -18,14 +18,31 @@ export function useAudioRecorder() {
|
|||||||
|
|
||||||
/** Choisit le meilleur mimeType supporté par le navigateur. */
|
/** Choisit le meilleur mimeType supporté par le navigateur. */
|
||||||
const getMimeType = useCallback(() => {
|
const getMimeType = useCallback(() => {
|
||||||
const types = [
|
const audio = document.createElement("audio");
|
||||||
"audio/webm;codecs=opus",
|
const isAppleDevice = /iPhone|iPad|iPod|Mac/.test(navigator.userAgent);
|
||||||
"audio/webm",
|
|
||||||
"audio/mp4",
|
const types = isAppleDevice
|
||||||
"audio/ogg;codecs=opus",
|
? [
|
||||||
];
|
"audio/mp4",
|
||||||
|
"audio/webm;codecs=opus",
|
||||||
|
"audio/webm",
|
||||||
|
"audio/ogg;codecs=opus",
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
"audio/webm;codecs=opus",
|
||||||
|
"audio/webm",
|
||||||
|
"audio/ogg;codecs=opus",
|
||||||
|
"audio/mp4",
|
||||||
|
];
|
||||||
|
|
||||||
for (const type of types) {
|
for (const type of types) {
|
||||||
if (MediaRecorder.isTypeSupported(type)) return type;
|
const baseType = type.split(";")[0];
|
||||||
|
if (
|
||||||
|
MediaRecorder.isTypeSupported(type) &&
|
||||||
|
audio.canPlayType(baseType) !== ""
|
||||||
|
) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ""; // fallback : le navigateur choisira
|
return ""; // fallback : le navigateur choisira
|
||||||
}, []);
|
}, []);
|
||||||
@ -45,7 +62,8 @@ export function useAudioRecorder() {
|
|||||||
audio: {
|
audio: {
|
||||||
echoCancellation: true,
|
echoCancellation: true,
|
||||||
noiseSuppression: true,
|
noiseSuppression: true,
|
||||||
sampleRate: 44100,
|
autoGainControl: true,
|
||||||
|
channelCount: 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
streamRef.current = stream;
|
streamRef.current = stream;
|
||||||
|
|||||||
@ -83,6 +83,7 @@ export default function RecipeForm() {
|
|||||||
const [audioFile, setAudioFile] = useState<File | null>(null)
|
const [audioFile, setAudioFile] = useState<File | null>(null)
|
||||||
const [pageState, setPageState] = useState<PageState>("idle")
|
const [pageState, setPageState] = useState<PageState>("idle")
|
||||||
const [error, setError] = useState("")
|
const [error, setError] = useState("")
|
||||||
|
const [previewError, setPreviewError] = useState("")
|
||||||
const [recordingTime, setRecordingTime] = useState(0)
|
const [recordingTime, setRecordingTime] = useState(0)
|
||||||
const [user, setUser] = useState<User | null>(null)
|
const [user, setUser] = useState<User | null>(null)
|
||||||
const [tipIndex, setTipIndex] = useState(0)
|
const [tipIndex, setTipIndex] = useState(0)
|
||||||
@ -119,6 +120,7 @@ export default function RecipeForm() {
|
|||||||
setAudioFile(file)
|
setAudioFile(file)
|
||||||
setPageState("review")
|
setPageState("review")
|
||||||
setError("")
|
setError("")
|
||||||
|
setPreviewError("")
|
||||||
}, [currentRecording])
|
}, [currentRecording])
|
||||||
|
|
||||||
// Timer
|
// Timer
|
||||||
@ -572,7 +574,9 @@ export default function RecipeForm() {
|
|||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
audio.pause()
|
audio.pause()
|
||||||
} else {
|
} else {
|
||||||
audio.play()
|
audio.play().catch(() => {
|
||||||
|
setPreviewError("Impossible de lire cet aperçu audio sur ce navigateur.")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="h-12 w-12 shrink-0 rounded-full bg-gradient-to-br from-orange-500 to-amber-500 text-white shadow-md flex items-center justify-center hover:shadow-lg hover:scale-105 transition-all"
|
className="h-12 w-12 shrink-0 rounded-full bg-gradient-to-br from-orange-500 to-amber-500 text-white shadow-md flex items-center justify-center hover:shadow-lg hover:scale-105 transition-all"
|
||||||
@ -612,15 +616,20 @@ export default function RecipeForm() {
|
|||||||
<audio
|
<audio
|
||||||
id="review-audio"
|
id="review-audio"
|
||||||
src={audioUrl}
|
src={audioUrl}
|
||||||
|
preload="metadata"
|
||||||
onPlay={() => setIsPlaying(true)}
|
onPlay={() => setIsPlaying(true)}
|
||||||
onPause={() => setIsPlaying(false)}
|
onPause={() => setIsPlaying(false)}
|
||||||
onEnded={() => setIsPlaying(false)}
|
onEnded={() => setIsPlaying(false)}
|
||||||
|
onError={() => setPreviewError("La lecture de l'aperçu audio a échoué.")}
|
||||||
className="hidden"
|
className="hidden"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="mt-3 text-[11px] text-muted-foreground text-right">
|
<div className="mt-3 text-[11px] text-muted-foreground text-right">
|
||||||
{(audioFile.size / 1024).toFixed(0)} KB
|
{(audioFile.size / 1024).toFixed(0)} KB
|
||||||
</div>
|
</div>
|
||||||
|
{previewError && (
|
||||||
|
<p className="mt-2 text-xs text-red-500 text-right">{previewError}</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Actions */}
|
{/* Actions */}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user