#javascript #reactjs #setinterval #howler.js
Вопрос:
Проблема с пакетом React js и Howler js при воспроизведении звуков через несколько секунд
Здравствуйте и спасибо, что ответили на мою проблему, надеюсь, вы это понимаете, мой английский не самый лучший.
Здесь я загрузил видео, которое точно показывает, в чем моя проблема: https://youtu.be/BvuK0zDGvgY
Таким образом, через несколько секунд программа просто начинает обрезать и отставать от моего компьютера. Проблемы, которые, я думаю, могут возникнуть, заключаются в следующем:
- Аудиофайл html5 исчерпан. Кто-нибудь знает решение для этого?
setInterval()
Функция, которую я использовал для итерации в миллисекундах, имитирует темп. Я думаю, что это может быть проблемой, потому что даже если я нажму кнопку воспроизведения драм-машины без какого-либо звука внутри стойки, через несколько секунд приложение столкнется с той же проблемой.- Много рендеров. Так как я использую React js и крючок react
useState()
для запуска нового рендеринга. Я использовалsetInterval()
для изменения крючка состояния, который увеличивает число с каждым интервалом. Может быть, если темп высокий (это означает более быстрые интервалы), браузер или компьютер перегружаются? и если да, то знает ли кто-нибудь альтернативуsetInterval()
увеличению числа с течением времени?.
это мой код, я думаю, что в нем нет необходимости, но на всякий случай
import React, {useState} from 'react'
import {IoMdMusicalNote} from "react-icons/io"
import {AiFillCaretDown} from "react-icons/ai"
import {BsFillPlayFill, BsPauseFill} from "react-icons/bs"
//sounds
import Kick from "./sounds/kick.mp3"
import Button_sound from "./sounds/sound_fx/play_button.mp3"
import Snare from "./sounds/snare.mp3"
import Hat from "./sounds/hat.mp3"
import crash from "./sounds/cymbal.mp3"
import tom from "./sounds/tom.mp3"
import jump from "./sounds/jump.mp3"
//
import {Howl} from 'howler';
import "./App.css"
const App = () => {
//A value that increases by the tempo.
const [currentStep, setStep] = useState(undefined)
//a bool to know when the drum machine is running
const [isPlaying, setIsPlaying] = useState(null)
//to clear the interval later
const [intervalState, setIntervalState] = useState(null)
//tempo value, it is set with an input below
const [tempo, setTempo] = useState(undefined)
//set sounds to later use
const sounds = {
kick: new Howl({src: [Kick]}),
snare: new Howl({src: [Snare]}),
hat: new Howl({src: [Hat]}),
crash: new Howl({src: [crash]}),
tom: new Howl({src: [tom]}),
jump: new Howl({src: [jump]}),
pebbel: new Howl({src: [Button_sound]}),
}
//creates the rack of slots
const createSteps = () => {
let arr = new Array(32)
for (let i = 0 ; i < 32; i ){
arr[i] = 0
}
return arr
}
//the instruments
const [instrumental, setInstrumental] = useState([
{name:"kick", steps: createSteps(), audio: sounds.kick},
{name: "hat", steps: createSteps(), audio: sounds.hat},
{name: "snare", steps: createSteps(), audio: sounds.snare},
{name: "crash", steps: createSteps(), audio: sounds.crash},
{name: "tom", steps: createSteps(), audio: sounds.tom},
{name: "jump", steps: createSteps(), audio: sounds.jump},
]);
//turn on a slot to make it sound when play, it receives stepIndex to modify the specified indexed element and instrument name refers to the specific instrument of the instrumental array
const toggleSound = (stepIndex, instrumentName) => {
const stepsState = instrumental.find(instrument => instrument.name === instrumentName).steps
stepsState[stepIndex] = stepsState[stepIndex] === 1 ? 0 : 1;
const newInstrumentState = {...instrumental.find(instrument => instrument.name === instrumentName), steps: stepsState}
let newInstrumentalState = [...instrumental]
newInstrumentalState[newInstrumentalState.find(
instrument => instrument.name === instrumentName
)] = newInstrumentState
setInstrumental(newInstrumentalState)
}
//id del set interval
let intervalo;
//plays the interval and increases the currentStep state
const play = () =>{
sounds.pebbel.play();
let step = -1
console.log("started")
const stepper = () => {
if (step === 31){
step = 0
} else {
step = 1
}
setStep(step)
}
intervalo = setInterval(stepper,tempo)
setIntervalState(intervalo)
setIsPlaying(true)
}
//clear interval to stop
const stop = () => {
sounds.pebbel.play();
clearInterval(intervalState)
setIsPlaying(false)
console.log("stoped")
}
return (
<>
<h1 className="title">D R U M S</h1>
<div className="drum-machine">
<div className="buttons-container">
{isPlaying ? <BsPauseFill className="btn danger" onClick={() =>{stop()}}/> :<BsFillPlayFill className="btn success" onClick={() =>{ play();}}/>}
<input type="number" onKeyPress={(e) => e.key === "Enter" ? setTempo(15000 / parseInt(e.target.value)) : undefined}/>
</div>
<div className="instruments-container">
{instrumental.map((instrument, instrumentIndex)=>{
return <div key={instrumentIndex} className="instrument-container">
<p className="instrument-name">{instrument.name}</p>
<div className="bulb" style={{background: `${instrument.steps[currentStep] === 1 ? "#a95013" : "none"}`}}></div>
<div className="instrument-rack">
{instrument.steps.map((step, stepIndex)=>{
let lit = "";
let jump = "0";
if (stepIndex === currentStep){
lit = "#a33e2a"
if (step === 1 amp;amp; isPlaying){
instrument.audio.play()
jump = "-6px"
}
}
return (
<div
className="slot"
style={{background: lit, marginLeft: `${stepIndex % 4 === 0 ? "8px" : "0px"}`, transform: `translateY(${jump})` }}
onClick={() => {toggleSound(stepIndex, instrument.name); instrument.audio.play()}}
key={stepIndex}
>
{step === 1 ? <IoMdMusicalNote className="beat-btn"/> : <AiFillCaretDown className="slot-btn"/> }
</div>
)
})}
</div>
</div>
})}
</div>
</div>
</>
)
}
export default App