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

95 lines
2.4 KiB
TypeScript
Raw Normal View History

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;
};
2021-04-07 23:14:42 +01:00
class MusicPlayer extends React.Component<MusicPlayerProps, State> {
private audioState: AudioState;
constructor(props: MusicPlayerProps) {
2021-04-07 23:23:21 +01:00
super(props);
2021-04-07 23:23:21 +01:00
const context = new AudioContext();
const source = new Audio();
const sourceNode = context.createMediaElementSource(source);
const volume = context.createGain();
2021-04-07 23:23:21 +01:00
sourceNode.connect(volume);
volume.connect(context.destination);
2021-04-07 23:23:21 +01:00
this.audioState = {
audioContext: context,
audioSourceNode: sourceNode,
audioSource: source,
audioVolume: volume,
};
}
render() {
2021-04-07 23:23:21 +01:00
return (
<div id="player" style={{ height: "100%", width: "100%" }}>
<Visualizer
audioContext={this.audioState.audioContext}
audioSource={this.audioState.audioSourceNode}
/>
<Controls />
</div>
);
}
componentDidUpdate() {
2021-04-07 23:23:21 +01:00
const context = this.audioState.audioContext;
const source = this.audioState.audioSource;
const volume = this.audioState.audioVolume;
2021-04-07 23:23:21 +01:00
// First, set the audio source (if it changed)
if (this.props.source && source.src != this.props.source) {
source.src = this.props.source;
}
2021-04-07 23:23:21 +01:00
if (this.props.playing) {
source
.play()
.then(() => {
console.info("Started playing audio");
})
.catch((error) => {
console.error(`Could not play audio: ${error}`);
});
} else {
source.pause();
}
2021-04-07 23:23:21 +01:00
if (!this.props.muted) {
volume.gain.setValueAtTime(1, context.currentTime);
} else {
volume.gain.setValueAtTime(0, context.currentTime);
}
}
}
function mapStateToProps(state: State): MusicPlayerProps {
2021-04-07 23:23:21 +01:00
return {
playing: state.musicState.playing,
muted: state.musicState.muted,
source: state.musicState.source,
};
}
export default connect(mapStateToProps)(MusicPlayer);