import React, { useState, useCallback } from "react";
const AudioRecord = () => {
const [stream, setStream] = useState();
const [media, setMedia] = useState();
const [onRec, setOnRec] = useState(true);
const [source, setSource] = useState();
const [analyser, setAnalyser] = useState();
const [audioUrl, setAudioUrl] = useState();
const onRecAudio = () => {
// 음원정보를 담은 노드를 생성하거나 음원을 실행또는 디코딩 시키는 일을 한다
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// 자바스크립트를 통해 음원의 진행상태에 직접접근에 사용된다.
const analyser = audioCtx.createScriptProcessor(0, 1, 1);
setAnalyser(analyser);
function makeSound(stream) {
// 내 컴퓨터의 마이크나 다른 소스를 통해 발생한 오디오 스트림의 정보를 보여준다.
const source = audioCtx.createMediaStreamSource(stream);
setSource(source);
source.connect(analyser);
analyser.connect(audioCtx.destination);
}
// 마이크 사용 권한 획득
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();
setStream(stream);
setMedia(mediaRecorder);
makeSound(stream);
analyser.onaudioprocess = function (e) {
// 3분(180초) 지나면 자동으로 음성 저장 및 녹음 중지
if (e.playbackTime > 180) {
stream.getAudioTracks().forEach(function (track) {
track.stop();
});
mediaRecorder.stop();
// 메서드가 호출 된 노드 연결 해제
analyser.disconnect();
audioCtx.createMediaStreamSource(stream).disconnect();
mediaRecorder.ondataavailable = function (e) {
setAudioUrl(e.data);
setOnRec(true);
};
} else {
setOnRec(false);
}
};
});
};
// 사용자가 음성 녹음을 중지했을 때
const offRecAudio = () => {
// dataavailable 이벤트로 Blob 데이터에 대한 응답을 받을 수 있음
media.ondataavailable = function (e) {
setAudioUrl(e.data);
setOnRec(true);
};
// 모든 트랙에서 stop()을 호출해 오디오 스트림을 정지
stream.getAudioTracks().forEach(function (track) {
track.stop();
});
// 미디어 캡처 중지
media.stop();
// 메서드가 호출 된 노드 연결 해제
analyser.disconnect();
source.disconnect();
};
const onSubmitAudioFile = useCallback(() => {
if (audioUrl) {
console.log(URL.createObjectURL(audioUrl)); // 출력된 링크에서 녹음된 오디오 확인 가능
}
// File 생성자를 사용해 파일로 변환
const sound = new File([audioUrl], "soundBlob", { lastModified: new Date().getTime(), type: "audio" });
console.log(sound); // File 정보 출력
}, [audioUrl]);
return (
<>
<button onClick={onRec ? onRecAudio : offRecAudio}>녹음</button>
<button onClick={onSubmitAudioFile}>결과 확인</button>
</>
);
};
export default AudioRecord;
+ 녹음 후 재생 할 수 있는 기능까지 넣어서 코드를 수정했다.
import React, { useState, useCallback } from "react";
const AudioRecord = () => {
const [stream, setStream] = useState();
const [media, setMedia] = useState();
const [onRec, setOnRec] = useState(true);
const [source, setSource] = useState();
const [analyser, setAnalyser] = useState();
const [audioUrl, setAudioUrl] = useState();
const [sound, setSound] = useState();
const onRecAudio = () => {
// 음원정보를 담은 노드를 생성하거나 음원을 실행또는 디코딩 시키는 일을 한다
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// 자바스크립트를 통해 음원의 진행상태에 직접접근에 사용된다.
const analyser = audioCtx.createScriptProcessor(0, 1, 1);
setAnalyser(analyser);
function makeSound(stream) {
// 내 컴퓨터의 마이크나 다른 소스를 통해 발생한 오디오 스트림의 정보를 보여준다.
const source = audioCtx.createMediaStreamSource(stream);
setSource(source);
source.connect(analyser);
analyser.connect(audioCtx.destination);
}
// 마이크 사용 권한 획득
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();
setStream(stream);
setMedia(mediaRecorder);
makeSound(stream);
analyser.onaudioprocess = function (e) {
// 3분(180초) 지나면 자동으로 음성 저장 및 녹음 중지
if (e.playbackTime > 180) {
stream.getAudioTracks().forEach(function (track) {
track.stop();
});
mediaRecorder.stop();
// 메서드가 호출 된 노드 연결 해제
analyser.disconnect();
audioCtx.createMediaStreamSource(stream).disconnect();
mediaRecorder.ondataavailable = function (e) {
setAudioUrl(e.data);
setOnRec(true);
};
} else {
setOnRec(false);
}
};
});
};
// 사용자가 음성 녹음을 중지 했을 때
const offRecAudio = () => {
// dataavailable 이벤트로 Blob 데이터에 대한 응답을 받을 수 있음
media.ondataavailable = function (e) {
setAudioUrl(e.data);
setOnRec(true);
};
// 모든 트랙에서 stop()을 호출해 오디오 스트림을 정지
stream.getAudioTracks().forEach(function (track) {
track.stop();
});
// 미디어 캡처 중지
media.stop();
// 메서드가 호출 된 노드 연결 해제
analyser.disconnect();
source.disconnect();
};
const onSubmitAudioFile = useCallback(() => {
if (audioUrl) {
setSound(URL.createObjectURL(audioUrl)); // 출력된 링크에서 녹음된 오디오 확인 가능
}
// File 생성자를 사용해 파일로 변환
const sound = new File([audioUrl], "soundBlob", {
lastModified: new Date().getTime(),
type: "audio",
});
console.log(sound); // File 정보 출력
}, [audioUrl]);
// 😀😀😀
const play = ()=>{
const audio = new Audio(sound);
audio.loop = false;
audio.volume = 1;
audio.play();
}
// 😀😀😀
return (
<>
<button onClick={onRec ? onRecAudio : offRecAudio}>녹음</button>
<button onClick={onSubmitAudioFile}>결과 확인</button>
// 😀😀😀
<button onClick={play}>재생</button>
// 😀😀😀
</>
);
};
export default AudioRecord;
현재 코드에서는 녹음 → 녹음 → 결과 확인 → 재생을 해야 녹음한 소리가 재생된다. 추후 수정이 필요 할 것 같다.
+ 수정한 코드 (녹음 → 재생)
import "./App.css";
import React, { useState, useCallback } from "react";
function App() {
const [stream, setStream] = useState();
const [media, setMedia] = useState();
const [onRec, setOnRec] = useState(true);
const [source, setSource] = useState();
const [analyser, setAnalyser] = useState();
const [audioUrl, setAudioUrl] = useState();
const [disabled, setDisabled] = useState(true); // 😀😀😀
const onRecAudio = () => {
setDisabled(true) // 😀😀😀
// 음원정보를 담은 노드를 생성하거나 음원을 실행또는 디코딩 시키는 일을 한다
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// 자바스크립트를 통해 음원의 진행상태에 직접접근에 사용된다.
const analyser = audioCtx.createScriptProcessor(0, 1, 1);
setAnalyser(analyser);
function makeSound(stream) {
// 내 컴퓨터의 마이크나 다른 소스를 통해 발생한 오디오 스트림의 정보를 보여준다.
const source = audioCtx.createMediaStreamSource(stream);
setSource(source);
source.connect(analyser);
analyser.connect(audioCtx.destination);
}
// 마이크 사용 권한 획득
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();
setStream(stream);
setMedia(mediaRecorder);
makeSound(stream);
analyser.onaudioprocess = function (e) {
// 3분(180초) 지나면 자동으로 음성 저장 및 녹음 중지
if (e.playbackTime > 180) {
stream.getAudioTracks().forEach(function (track) {
track.stop();
});
mediaRecorder.stop();
// 메서드가 호출 된 노드 연결 해제
analyser.disconnect();
audioCtx.createMediaStreamSource(stream).disconnect();
mediaRecorder.ondataavailable = function (e) {
setAudioUrl(e.data);
setOnRec(true);
};
} else {
setOnRec(false);
}
};
});
};
// 사용자가 음성 녹음을 중지 했을 때
const offRecAudio = () => {
// dataavailable 이벤트로 Blob 데이터에 대한 응답을 받을 수 있음
media.ondataavailable = function (e) {
setAudioUrl(e.data);
setOnRec(true);
};
// 모든 트랙에서 stop()을 호출해 오디오 스트림을 정지
stream.getAudioTracks().forEach(function (track) {
track.stop();
});
// 미디어 캡처 중지
media.stop();
// 메서드가 호출 된 노드 연결 해제
analyser.disconnect();
source.disconnect();
if (audioUrl) {
URL.createObjectURL(audioUrl); // 출력된 링크에서 녹음된 오디오 확인 가능
}
// File 생성자를 사용해 파일로 변환
const sound = new File([audioUrl], "soundBlob", {
lastModified: new Date().getTime(),
type: "audio",
});
// 😀😀😀
setDisabled(false);
console.log(sound); // File 정보 출력
};
const play = () => {
const audio = new Audio(URL.createObjectURL(audioUrl)); // 😀😀😀
audio.loop = false;
audio.volume = 1;
audio.play();
};
// 😀😀😀
return (
<>
<button onClick={onRec ? onRecAudio : offRecAudio}>녹음</button>
<button onClick={play} disabled={disabled}>재생</button>
</>
);
}
export default App;
+ audio 파일 서버(node.js)로 보내는 방법
이미지 파일을 서버에 보낼 때는 contentType에 multipart/formed-data로 설정을 했는 데
이번 프로젝트에서는 오디오 파일을 서버에 보내야 해서 찾아보니 contentType 설정 방법이 여러가지가 있고 그 중에서 MP3 파일을 전송 해야 하기 때문에 audio/mpeg를 사용하면 될 것 같다!!!
(출처)
https://juyoung-1008.tistory.com/4
'더 알아보기 > 기능' 카테고리의 다른 글
Toggle Switch 기능 만들기 [1탄] (0) | 2021.12.27 |
---|---|
Modal 팝업창 만들기 (0) | 2021.12.27 |
버블 차트 만들기 (라이브러리 X) (0) | 2021.12.24 |
리액트에서 워드 클라우드 만들기 (0) | 2021.12.24 |
Audio 기능 (0) | 2021.12.22 |
댓글