forked from
rocksky.app/rocksky
A decentralized music tracking and discovery platform built on AT Protocol 馃幍
1import init, { AudioDecoder } from "../pkg/raichu";
2
3class AudioPlayer {
4 private audioContext: AudioContext | null = null;
5 private sourceNode: AudioBufferSourceNode | null = null;
6 private buffer: AudioBuffer | null = null;
7
8 async load(url: string, ext: string) {
9 const response = await fetch(url);
10 const arrayBuffer = await response.arrayBuffer();
11 const uint8Array = new Uint8Array(arrayBuffer);
12
13 await init(); // Initialize WASM
14 const decoder = new AudioDecoder();
15 decoder.decode(uint8Array, ext);
16
17 const pcmData = decoder.get_pcm_data();
18 const sampleRate = decoder.get_sample_rate();
19 const channels = decoder.get_channels();
20
21 this.audioContext = new window.AudioContext({ sampleRate });
22
23 this.buffer = this.audioContext.createBuffer(
24 channels,
25 pcmData.length / channels,
26 sampleRate,
27 );
28
29 for (let i = 0; i < channels; i++) {
30 const channelData = this.buffer.getChannelData(i);
31 for (let j = 0; j < channelData.length; j++) {
32 channelData[j] = pcmData[j * channels + i];
33 }
34 }
35
36 console.log(">> Audio Loaded Successfully");
37 }
38
39 play(offset = 0) {
40 if (this.audioContext && this.buffer) {
41 this.sourceNode = this.audioContext.createBufferSource();
42 this.sourceNode.buffer = this.buffer;
43 this.sourceNode.connect(this.audioContext.destination);
44 this.sourceNode.start(0, offset);
45 this.sourceNode.loop = false;
46 }
47 }
48
49 pause() {
50 if (this.sourceNode) {
51 this.sourceNode.stop();
52 this.sourceNode = null;
53 }
54 }
55
56 stop() {
57 this.pause();
58 if (this.audioContext) {
59 this.audioContext.close();
60 this.audioContext = null;
61 }
62 }
63}
64export default AudioPlayer;