"use client"; import { useEffect, useRef, useState } from 'react'; import MidiPlayer from 'midi-player-js'; import Soundfont from 'soundfont-player'; export default function HomePage() { const audioCtxRef = useRef(null); const instrumentRef = useRef(null); const playerRef = useRef(null); const [soundfontLoading, setSoundfontLoading] = useState(true); const [fileLoaded, setFileLoaded] = useState(false); const [isPlaying, setIsPlaying] = useState(false); const [tempo, setTempo] = useState(120); const [fileFormat, setFileFormat] = useState(null); const [progress, setProgress] = useState(0); useEffect(() => { const AudioContext = window.AudioContext || (window as any).webkitAudioContext; const audioCtx = new AudioContext(); audioCtxRef.current = audioCtx; Soundfont.instrument(audioCtx, 'acoustic_grand_piano').then(instrument => { instrumentRef.current = instrument; const player = new MidiPlayer.Player((event: any) => { if (!instrumentRef.current) return; if (event.name === 'Note on' && event.velocity > 0) { instrumentRef.current.play(event.noteName, audioCtx.currentTime, { gain: 1 }); } else if ((event.name === 'Note on' && event.velocity === 0) || event.name === 'Note off') { instrumentRef.current.stop(event.noteName, audioCtx.currentTime); } }); player.on('endOfFile', () => { setIsPlaying(false); setProgress(0); }); player.on('fileLoaded', () => { try { setFileFormat(player.getFormat()); } catch { setFileFormat(null); } setTempo(120); setFileLoaded(true); setProgress(0); }); playerRef.current = player; setSoundfontLoading(false); }); return () => { audioCtx.close(); }; }, []); useEffect(() => { if (!playerRef.current) return; let interval: any; if (isPlaying) { interval = setInterval(() => { const remaining = playerRef.current.getSongPercentRemaining(); setProgress(100 - (remaining || 0)); }, 200); } return () => clearInterval(interval); }, [isPlaying]); const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file && playerRef.current) { const reader = new FileReader(); reader.onload = () => { const arrayBuffer = reader.result; if (!arrayBuffer) return; playerRef.current.stop(); playerRef.current.loadArrayBuffer(arrayBuffer); }; reader.readAsArrayBuffer(file); } }; const handlePlayPause = () => { if (isPlaying) { playerRef.current.pause(); } else { playerRef.current.play(); } setIsPlaying(!isPlaying); }; const handleStop = () => { playerRef.current.stop(); setIsPlaying(false); setProgress(0); }; const handleTempoChange = (newTempo: number) => { playerRef.current.pause(); playerRef.current.setTempo(newTempo); playerRef.current.play(); setTempo(newTempo); setIsPlaying(true); }; return (

♬ MidiPlayerJS

{soundfontLoading ? "Loading soundfont..." : ( )} handleTempoChange(Number(e.target.value))} />
MIDI Format: {fileFormat}
Progress: {progress}%
); }