This repository has been archived on 2022-09-16. You can view files and clone it, but cannot push or open issues/pull-requests.
tlaternet-templates/src/music/MusicPlayer.tsx

95 lines
2.3 KiB
TypeScript

import React from "react";
import { connect } from "react-redux";
import Controls from "./components/controls";
import Visualizer from "./components/visualizer";
import { State } from "./store";
type AudioState = {
audioContext: AudioContext;
audioSource: HTMLAudioElement;
audioSourceNode: MediaElementAudioSourceNode;
audioVolume: GainNode;
};
type MusicPlayerProps = {
playing: boolean;
muted: boolean;
source?: string;
};
class MusicPlayer extends React.Component<MusicPlayerProps, {}> {
private audioState: AudioState;
constructor(props: MusicPlayerProps) {
super(props);
let context = new AudioContext();
let source = new Audio();
let sourceNode = context.createMediaElementSource(source);
let volume = context.createGain();
sourceNode.connect(volume);
volume.connect(context.destination);
this.audioState = {
audioContext: context,
audioSourceNode: sourceNode,
audioSource: source,
audioVolume: volume,
};
}
render() {
return (
<div id="player" style={{ height: "100%", width: "100%" }}>
<Visualizer
audioContext={this.audioState.audioContext}
audioSource={this.audioState.audioSourceNode}
/>
<Controls />
</div>
);
}
componentDidUpdate() {
let context = this.audioState.audioContext;
let source = this.audioState.audioSource;
let volume = this.audioState.audioVolume;
// First, set the audio source (if it changed)
if (this.props.source && source.src != this.props.source) {
source.src = this.props.source;
}
if (this.props.playing) {
source
.play()
.then(() => {
console.info("Started playing audio");
})
.catch((error) => {
console.error(`Could not play audio: ${error}`);
});
} else {
source.pause();
}
if (!this.props.muted) {
volume.gain.setValueAtTime(1, context.currentTime);
} else {
volume.gain.setValueAtTime(0, context.currentTime);
}
}
}
function mapStateToProps(state: State): MusicPlayerProps {
return {
playing: state.musicState.playing,
muted: state.musicState.muted,
source: state.musicState.source,
};
}
export default connect(mapStateToProps)(MusicPlayer);