1. 프론트에서 firebase storage 음성 업로드 기능
초기 기획에서 프론트에서 음성을 업로드하는 형태는 박스를 클릭 혹은 박스에 드래그앤 드롭으로 동작해야하며
다음과 같은 반응이 추가시켰다.
- 업로드가 진행중인 표시가 나타나게
- 파일이 정상적으로 업로드가 완료되면 완료 표시, 실패시 실패 표시
- 파일 확장자가 wav, mp3 인지
- 파일 크기가 15 mb 미만인지
이를 위해 <input> 과 <div> 태그를 이용해 간략하게 드래그앤드롭 및 css 등을 구성하였다.
해당 코드는 간략하게 다음과 같다.
<div
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onDragOver={handleDragOver}
onDrop={handleDrop}
onClick={handleDivClick}
>
<input
type={"file"}
ref={inputRef}
onChange={handleFileChange}
style={{ display: "none" }}
/>
{state.origin_file.url ? (
<div>
<p>{state.origin_file.filename}</p>
<p>업로드 성공</p>
</div>
) : uploadLoading ? (
<p>
uploading 진행중
</p>
) : (
<p>
클릭 혹은 드래그하여 파일을 업로드해주세요.
</p>
)}
</div>
input 태그의 handleFileChange 가 작동되면
validation 함수를 통해 유저가 로그인되어있는지, 파일크기나 확정자 확인 후 전부 만족하면
firebase storage 에 저장 후 저장이 성공적으로 이뤄지면 firestore 에 유저와 storage url 이 저장된다.
이를 위해 addStorageData 함수와, addData 함수를 firebaes/storage, firebase/firestore에 각 각 작성해주고
export default async function addStorageData(file, point) {
let storageRef = ref(storage, point);
let url = null;
let error = null;
let fileName = null;
try {
await uploadBytes(storageRef, file);
url = await getDownloadURL(storageRef);
fileName = storageRef.name;
} catch (e) {
error = e;
}
return { url, fileName, error };
}
[addData 생략]
다음과 같이 handleUpload 를 통해 위의 과정을 수행하였다.
const handleUpload = async (file) => {
try {
const sanitizeName = sanitizeFileName(file.fileName);
// 1. storage에 저장
const uploadPath = "audio/" + id + "/" + sanitizeName
const saveStorageResult = await addStorageData(
file,
uploadPath
);
if(saveStorageResult.error){
alert('데이터베이스 삽입 시 에러가 발생했습니다.')
return;
}
// 2. context api 에 저장
dispatch({
type: 'SET_ORIGIN_FILE_INFO',
...
upload_path : uploadPath,
})
// 3. database 에 저장
const audioData = {
...
uploadPath: uploadPath,
};
const addDataResult = await addData("audio",audioData);
if (addDataResult.error) {
alert("에러가 발생했습니다.");
return;
}
} catch (e) {
...
}
};
이런식으로 빠르고 간단하게 storage 를 이용하여 audio 파일을 저장하고,
해당 url 을 firestore 에 저장, 필요한 상황에 쿼리를 통해 audio 파일을 다운로드 하거나, 재생할 수 있게 구현을 완료하였다.
audio 파일을 재생 할 때에는 wavesurfer.js 라이브러리를 통해 간략하게 디자인해서 다음과 같이
재생, 볼륨조절, 삭제 + 저장버튼 이 존재하는 컴포넌트를 구현하였고,
저장 버튼을 누르면 firebase/storage 의 getDownloadURL 메소드를 통해 다운로드 될수 있게 - 코드는 다음과 같다
// wavesurfer player component 중 download
const onClickDownload = () => {
downloadData(state.remix_upload_path)
}
// downloadData
export default function downloadData(uploadPath){
getDownloadURL(ref(storage, uploadPath))
.then((url) => {
const fileName = uploadPath.fileName
// This can be downloaded directly:
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = (event) => {
const blob = xhr.response;
const reader = new FileReader();
reader.onloadend = () => {
// `reader.result` contains the file content as a data URL
const dataURL = reader.result;
// Create a new anchor element
const link = document.createElement('a');
link.href = dataURL;
link.download = fileName
// Simulate a click event to trigger the download
link.dispatchEvent(new MouseEvent('click'));
};
reader.readAsDataURL(blob);
};
xhr.open('GET', url);
xhr.send();
})
.catch((error) => {
alert('다운로드 실패')
...
});
그냥 아주 간략하게 구상한 부분과 코드 일부분을 기억하기 위해 작성하였으니
궁금하신 분은 댓글을 통해 물어봐주세요
'AI 활용' 카테고리의 다른 글
[AI 음성변환] melodyswap - React,next.js,firebase auth - (1) (0) | 2023.08.14 |
---|---|
[AI 음성변환] melodSwap - (0) (0) | 2023.08.13 |