import { Component } from "react"; import * as _VAD from "vad.js/lib/vad.js"; import Percentage from "./percentage"; import Kaburi from "./kaburi"; export default class extends Component { state = { audioContext: new AudioContext(), audioStream: null, left: null, right: null, activity: [] }; componentDidMount() { const audioContext = this.state.audioContext; const leftNode = audioContext.createGain(); const rightNode = audioContext.createGain(); const splitter = audioContext.createChannelSplitter(2); splitter.connect( leftNode, 0 ); splitter.connect( rightNode, 1 ); const putKaburi = () => { if (this.state.left !== null && this.state.right !== null) { this.setState({ activity: [ ...this.state.activity, { ch: "kaburi", startTime: Math.max(this.state.left, this.state.right), endTime: new Date().getTime() } ] }); } }; const start = stream => { this.setState({ audioStream: stream }); audioContext.createMediaStreamSource(stream).connect(splitter); VAD.bind({})({ source: leftNode, voice_stop: () => { putKaburi(); this.setState({ left: null, activity: [ ...this.state.activity, { ch: "l", startTime: this.state.left, endTime: new Date().getTime() } ] }); }, voice_start: () => { this.setState({ left: new Date().getTime() }); } }); VAD.bind({})({ source: rightNode, voice_stop: () => { putKaburi(); this.setState({ right: null, activity: [ ...this.state.activity, { ch: "r", startTime: this.state.right, endTime: new Date().getTime() } ] }); }, voice_start: () => { this.setState({ right: new Date().getTime() }); } }); }; navigator.mediaDevices .getUserMedia({ audio: { echoCancellation: false } }) // モノラル防ぐ .then(start) .catch(console.error); } componentWillUnmount() { this.state.audioStream.getTracks().forEach(t => t.stop()); } render() { return (