-
Notifications
You must be signed in to change notification settings - Fork 3
Feature/#28 webcam preview #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
4c472af
chore:#28 μΈν°λ·° νμ΄μ§ κ²½λ‘ μμ± λ° νμΌ μΆκ°
dc22124
chore:#28 κ²½λ‘ μμ
ce879db
refactor:#28 μ¬μ©μ νλ©΄ μ»΄ν¬λνΈ λΆλ¦¬
964d01c
refactor:#28 μ¬μ©μ μΉμΊ λΆλ¬μ€λ λ‘μ§ λΆλ¦¬
64d6000
chore:#28 λΆνμν νμ
μ€μ μ κ±°
a056735
refactor:#28 λ‘μ§ μμ
5441edc
feat:#28 λ
Ήμ λ²νΌ ꡬν
83845a2
chore:#28 import κ²½λ‘ μμ
ecdb866
rename:#28 λ³μλͺ
μμ
b808169
rename:#28 νμΌλͺ
μΌλ°₯μΌμ΄μ€λ‘ μμ
5c5d990
refactor:#28 url λμ audioBlobμ λ겨주λ κ²μΌλ‘ μμ
2a7d378
refactor:#28 λ
Ήμ λ²νΌ λΆλ¦¬
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import CameraView from '@/features/interview/camera-view'; | ||
| import VoiceInputButton from '@/features/interview/voice-input-button'; | ||
|
|
||
| const InterviewPage = () => { | ||
| return ( | ||
| <div> | ||
| <CameraView /> | ||
| <VoiceInputButton /> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default InterviewPage; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| const InterviewStartPage = () => { | ||
| return <div>InterviewStartPage</div>; | ||
| }; | ||
|
|
||
| export default InterviewStartPage; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| 'use client'; | ||
|
|
||
| import { useWebcamStream } from '@/features/interview/hooks/use-webcam-stream'; | ||
|
|
||
| const CameraView = () => { | ||
| const videoRef = useWebcamStream(); | ||
|
|
||
| return ( | ||
| <div className='w-[300px]'> | ||
| <video ref={videoRef} autoPlay /> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default CameraView; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { useRef, useState } from 'react'; | ||
|
|
||
| export const useAudioRecorder = () => { | ||
| // μ°½μ°λμ μν μ£Όμμ΄λ PR νμλ λΆλ€μ μμΈν μ μ½μΌμ λ λ©λλ€. | ||
|
|
||
| // MediaRecorder μΈμ€ν΄μ€λ₯Ό μ μ₯ν κ³³, λ Ήμ μμ/μ€μ§ λ μ¬μ©λ¨ | ||
| const audioRecorderRef = useRef<MediaRecorder | null>(null); | ||
| // λ Ήμ μ€μΈμ§ μλμ§μ μν | ||
| const [isRecording, setIsRecording] = useState(false); | ||
| // λ Ήμμ΄ λλ λ€, μ¬μνκ±°λ λ€μ΄λ‘λν μ μλλ‘ μ€λμ€ Blobμ μ μ₯ν¨ | ||
| const [audioBlob, setAudioBlob] = useState<Blob | null>(null); | ||
| // MediaRecorderκ° μ λ¬νλ μ€λμ€ λ°μ΄ν°λ₯Ό μμ μ‘°κ°(blob) λ¨μλ‘ λͺ¨μλλ κ³³ | ||
| const audioChunksRef = useRef<Blob[]>([]); | ||
|
|
||
| //λ Ήμ μμ | ||
| const startRecording = async () => { | ||
| try { | ||
| // μ¬μ©μνν λ§μ΄ν¬ μ κ·Ό κΆν μμ², μΉμΈλλ©΄ MediaStreamμ λ°μμ΄ | ||
| const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); | ||
|
|
||
| // μ€λμ€ ν¬λ§· μ€μ (MIME νμ μμ ) | ||
| const mediaRecorder = new MediaRecorder(stream, { | ||
| mimeType: 'audio/webm;codecs=opus', | ||
| }); | ||
| audioRecorderRef.current = mediaRecorder; | ||
| audioChunksRef.current = []; | ||
|
|
||
| // λ Ήμ μ€ MediaRecorderκ° λ°μ΄ν°λ₯Ό μ 곡ν λλ§λ€ μ‘°κ°(chunk)μ audioChunksRefμ μΆκ°ν¨ | ||
| // λ Ήμ μ€ λ°μ΄ν°κ° μͺΌκ°μ Έμ μμ°¨μ μΌλ‘ λ€μ΄μ€λ ꡬ쑰μ | ||
| mediaRecorder.ondataavailable = (e) => { | ||
| audioChunksRef.current.push(e.data); | ||
| }; | ||
|
|
||
| // λ Ήμμ΄ μ’ λ£λλ©΄ μ§κΈκΉμ§ λͺ¨μ μ€λμ€ μ‘°κ°λ€μ νλλ‘ νλ²Όμ BlobμΌλ‘ λ§λ¦ | ||
| // Blobμ λΈλΌμ°μ κ° μ΄ν΄ν μ μλ κ°μ URLλ‘ λ³ν | ||
| mediaRecorder.onstop = () => { | ||
| const blob = new Blob(audioChunksRef.current, { type: 'audio/webm' }); | ||
| setAudioBlob(blob); | ||
| }; | ||
|
|
||
| // μ€μ λ Ήμμ μμν¨ | ||
| mediaRecorder.start(); | ||
| setIsRecording(true); | ||
| } catch (error) { | ||
| console.error('λ§μ΄ν¬ μ κ·Ό μ€λ₯:', error); | ||
| } | ||
| }; | ||
|
|
||
| // λ Ήμ μ€λ¨ | ||
| const stopRecording = () => { | ||
| audioRecorderRef.current?.stop(); | ||
| setIsRecording(false); | ||
| }; | ||
|
|
||
| return { isRecording, audioBlob, startRecording, stopRecording }; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import { useEffect, useRef } from 'react'; | ||
|
|
||
| type StreamCallback = (stream: MediaStream) => void; | ||
|
|
||
| export const useWebcamStream = () => { | ||
| const videoRef = useRef<HTMLVideoElement | null>(null); | ||
|
|
||
| const getWebcam = async (onStreamReady: StreamCallback) => { | ||
| try { | ||
| const constraints = { video: { width: { ideal: 1280 }, height: { ideal: 720 } }, audio: false }; | ||
| const stream = await navigator.mediaDevices.getUserMedia(constraints); | ||
|
|
||
| onStreamReady(stream); | ||
| } catch (error) { | ||
| console.error(error); | ||
| } | ||
| }; | ||
|
|
||
| useEffect(() => { | ||
| getWebcam((stream) => { | ||
| if (videoRef.current) { | ||
| videoRef.current.srcObject = stream; | ||
| } | ||
| }); | ||
| }, []); | ||
|
|
||
| return videoRef; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| 'use client'; | ||
|
|
||
| import { useAudioRecorder } from '@/features/interview/hooks/use-audio-recorder'; | ||
|
|
||
| const VoiceInputButton = () => { | ||
| const { isRecording, audioBlob, startRecording, stopRecording } = useAudioRecorder(); | ||
|
|
||
| return ( | ||
| <> | ||
| <button onClick={isRecording ? stopRecording : startRecording}> | ||
| {isRecording ? 'λ΅λ³ μλ£νκΈ°' : 'λ΅λ³νκΈ°'} | ||
| </button> | ||
| {audioBlob && <audio controls src={URL.createObjectURL(audioBlob)} />} | ||
| </> | ||
| ); | ||
| }; | ||
|
|
||
| export default VoiceInputButton; |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.