
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<div id="Chapter1_1" class="content-wrap">
<div class="title-box mb25 flex align-center mt40">
<span class="title mr40">1. Hello WORLD</span>
<span class="subtitle">my name is dd</span>
</div>
<div class="flex justify-between align-center">
<div class="pre-btn" @click="goToPage('Chapter2')">
<img src="../../../../resources/img/left.png" alt="" />
</div>
<div class="content title-box">
<p class="title mt25 title-bg">step2</p>
<div class="flex align-center mb30">
<p class="subtitle2 mr20">오늘 배웠던 단어를 말하고 생성된 예문을 따라 읽어보세요</p>
<!-- <button><img src="../../../../resources/img/btn10_s.png" alt="">
</button> -->
</div>
<div>
<img src="http://localhost:8081/client/build/dad67b1726cb2d2b215965b433149ca3.png" data-num="1" />
<p> {{ word }} </p>
<p> {{ mean }} </p>
</div>
<div class="flex justify-center">
<div class="readGroup">
<section>
<div class="imgGroup flex justify-center">
<!-- 녹음 버튼 -->
<div :class="['mic-btn', { notRecording: !isRecording }]" @click="toggleRecording">
<img src="../../../../resources/img/btn11_s.png" alt="" />
</div>
</div>
<article>
<p class="speakText mb25">
<span v-if="transcription === null"
>위의 버튼을 누른 후 오늘 배운 단어를 말해보세요!</span
>
<span v-else-if="!transcription || transcription.trim() === ''"
>다시 말해보세요!</span
>
<span v-else>{{ transcription }}</span>
</p>
<p class="read-ai">
<img style="margin-top: -5px" src="../../../../resources/img/img43_s.png" alt="" />
</p>
</article>
</section>
</div>
</div>
</div>
<div class="next-btn" @click="goToPage('Chapter2_2')">
<img src="../../../../resources/img/right.png" alt="" />
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
import SvgIcon from '@jamescoyle/vue-icon';
import { mdiStop } from '@mdi/js';
export default {
data() {
return {
isRecording: false, // 녹음 중 여부
mediaRecorder: null,
audioChunks: [], // 녹음된 오디오 데이터
audioBlob: null, // 오디오 Blob 객체
transcription: null, // 서버에서 받아온 텍스트 결과
stream: null, // MediaStream 객체
path: mdiStop,
/* audioURL : null // 오디오 URL 객체 */
word : "apple",
mean : "사과",
imageSrc : "http://localhost:8081/client/build/dad67b1726cb2d2b215965b433149ca3.png"
};
},
methods: {
goToPage(page) {
this.$router.push({ name: page });
},
// 녹음 시작/중지 토글
async toggleRecording() {
if (this.isRecording) {
console.log('녹음 그만!');
this.stopRecording(); // 녹음 중이면 중지
} else {
console.log('녹음 시작!');
await this.startRecording(); // 녹음 중이 아니면 녹음 시작
}
},
// 녹음 시작
async startRecording() {
this.audioChunks = []; // 오디오 초기화
this.stream = await navigator.mediaDevices.getUserMedia({ audio: true });
this.mediaRecorder = new MediaRecorder(this.stream);
this.mediaRecorder.ondataavailable = (event) => {
this.audioChunks.push(event.data); // 녹음 데이터 저장
};
this.mediaRecorder.onstop = () => {
this.audioBlob = new Blob(this.audioChunks, { type: 'audio/wav' });
/******************************/
// this.audioURL = URL.createObjectURL(this.audioBlob); // 오디오 URL 생성
// console.log('Audio URL:', this.audioURL);
/******************************/
console.log('Recorded Audio Blob:', this.audioBlob); // 콘솔에 Blob 확인
this.sendAudioToServer(); // 서버로 오디오 전송
};
this.mediaRecorder.start(); // 녹음 시작
this.isRecording = true; // 녹음 상태 변경
},
// 녹음 중지
stopRecording() {
this.mediaRecorder.stop(); // 녹음 중단
if (this.stream) {
this.stream.getTracks().forEach((track) => track.stop()); // 스트림의 모든 트랙 중지
}
this.isRecording = false; // 녹음 상태 변경
},
// 오디오 전송
async sendAudioToServer() {
const formData = new FormData();
formData.append('file', this.audioBlob, 'recording.wav');
try {
const resposne = await axios.post('/api/speechToText.json', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
this.transcription = resposne.data;
console.log(`받은 데이터 : ${this.transcription}`);
} catch (error) {
console.log('파일 전송 실패 : ', error);
}
},
},
watch: {},
computed: {},
components: {
SvgIcon,
},
mounted() {},
};
</script>
<style scoped>
.mic-btn {
cursor: pointer;
}
.mic-btn.notRecording {
background-image: none;
cursor: pointer;
}
.speakText {
background-color: #fff8e9;
border: 0;
}
.speakText span {
font-size: 28px;
}
</style>