Unable to use voice-controlled audio player #12153
-
Description---
title: "Home Based Exercise Program"
format: html
---
```{=html}
<div>
<audio id="myAudio" controls>
<source src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
<button id="startVoice" >Start Voice Control</button>
<script>
document.addEventListener("DOMContentLoaded", function() {
// Get references to elements.
const audioElement = document.getElementById("myAudio");
const startButton = document.getElementById("startVoice");
// Flag to ensure metadata is loaded.
let metadataLoaded = false;
audioElement.addEventListener("loadedmetadata", () => {
metadataLoaded = true;
console.log(`Metadata loaded. Duration: ${audioElement.duration.toFixed(2)} seconds.`);
});
// Check for Web Speech API support.
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SpeechRecognition) {
alert("Your browser does not support the Web Speech API!");
throw new Error("Web Speech API not supported");
}
// Set up speech recognition.
const recognition = new SpeechRecognition();
recognition.continuous = true;
recognition.lang = "en-US";
recognition.interimResults = false;
// Debounce settings to avoid processing duplicate commands quickly.
let lastCommand = "";
let lastCommandTime = 0;
const debounceDelay = 1000; // milliseconds
function processCommand(transcript) {
const now = Date.now();
if (transcript === lastCommand && (now - lastCommandTime) < debounceDelay) {
console.log(`Ignoring duplicate command: "${transcript}"`);
return;
}
lastCommand = transcript;
lastCommandTime = now;
console.log(`Processing command: "${transcript}"`);
// Ensure that the audio metadata is loaded.
if (!metadataLoaded) {
console.log("Audio metadata not loaded yet.");
return;
}
if (transcript.includes("play")) {
audioElement.play();
}
else if (transcript.includes("stop")) {
audioElement.pause();
}
else if (transcript.includes("forward")) {
const beforeTime = audioElement.currentTime;
// Add 5 seconds but do not exceed the duration.
const newTime = Math.min(audioElement.duration, beforeTime + 5);
console.log(`Forward command: currentTime ${beforeTime.toFixed(2)} → ${newTime.toFixed(2)}`);
audioElement.currentTime = newTime;
audioElement.play();
}
else if (transcript.includes("rewind") || transcript.includes("back")) {
const beforeTime = audioElement.currentTime;
// Subtract 5 seconds but do not go below 0.
const newTime = Math.max(0, beforeTime - 5);
console.log(`Rewind command: currentTime ${beforeTime.toFixed(2)} → ${newTime.toFixed(2)}`);
audioElement.currentTime = newTime;
audioElement.play();
}
else {
console.log(`Unrecognized command: "${transcript}"`);
}
}
recognition.onresult = (event) => {
// Process only the latest result.
const resultIndex = event.resultIndex;
const transcript = event.results[resultIndex][0].transcript.toLowerCase().trim();
console.log(`Voice input: "${transcript}"`);
processCommand(transcript);
};
recognition.onerror = (event) => {
console.log(`Speech recognition error: ${event.error}`);
};
// Start recognition when user clicks the button.
startButton.addEventListener("click", () => {
recognition.start();
console.log("Voice recognition started.");
});
});
</script>
```
I am trying to create a voice-controlled audio player. The user's commands are recorded after he clicks on "Start Voice Control". The commands "play" and "stop" work as expected, but for commands "forward" or "rewind", instead of moving the currentTIme accordingly, the audio gets reset to 0 and starts playing from the beginning. FYI, the audio file is around 50 seconds long. I assume this is related to Quarto's rendering. Is there a solution for this? Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 13 replies
-
Why did you close the discussion?
Before assuming, did you try your code outside of Quarto in a simple HTML page? Also, take a look at the documentation on how to include raw code:
Finally, could you share a small self-contained "working" (reproducible) example to work with, i.e., a complete Quarto document or a Git repository? The goal is to make it as easy as possible for us to recreate your problem so that we can fix it: please help us help you! Thanks. You can share a self-contained "working" (reproducible) Quarto document using the following syntax, i.e., using more backticks than you have in your document (usually four If you have multiple files (and if it is absolutely required to have multiple files), please share as a Git repository.
Additionally and if not already given, please share the output of |
Beta Was this translation helpful? Give feedback.
Hi, I was able to resolve my issue. In my _quarto.yml file, I specified "instant: false" under format: html. This caused full page reloads and prevented my audio element from being re-initialized. Thank you so much for your help and time. I really appreciate it!