diff --git a/apps/api/src/entity/summary.entity.ts b/apps/api/src/entity/summary.entity.ts
index db14a8fd..58dd928d 100644
--- a/apps/api/src/entity/summary.entity.ts
+++ b/apps/api/src/entity/summary.entity.ts
@@ -17,7 +17,7 @@ export class Summary {
@Column('varchar')
audioUrl: string;
- @Column('json', { nullable: true })
+ @Column('text', { nullable: true })
summaryText: string[];
@CreateDateColumn({ type: 'timestamp', name: 'created_at' })
diff --git a/apps/api/src/stream/stream.controller.ts b/apps/api/src/stream/stream.controller.ts
index 9d00f36f..84997326 100644
--- a/apps/api/src/stream/stream.controller.ts
+++ b/apps/api/src/stream/stream.controller.ts
@@ -19,7 +19,7 @@ export class StreamController {
@Get('summary/:ticleId')
async getSummaryByTicleId(@Param('ticleId') ticleId: number) {
- const text = await this.streamService.getSummaryText(ticleId);
- return { summary: text };
+ const summary = await this.streamService.getSummary(ticleId);
+ return summary;
}
}
diff --git a/apps/api/src/stream/stream.service.ts b/apps/api/src/stream/stream.service.ts
index 77e1924f..4e9bfb6e 100644
--- a/apps/api/src/stream/stream.service.ts
+++ b/apps/api/src/stream/stream.service.ts
@@ -103,11 +103,12 @@ export class StreamService {
}
}
- async getSummaryText(ticleId: number) {
+ async getSummary(ticleId: number) {
const summary = await this.summaryRepository.findOne({
where: { ticle: { id: ticleId } },
});
- return summary.summaryText;
+
+ return summary;
}
async updateSummaryText(summary: Summary, summaryText: string[]) {
diff --git a/apps/web/src/components/dashboard/AiSummaryDialog.tsx b/apps/web/src/components/dashboard/AiSummaryDialog.tsx
index 34bd5a65..70573089 100644
--- a/apps/web/src/components/dashboard/AiSummaryDialog.tsx
+++ b/apps/web/src/components/dashboard/AiSummaryDialog.tsx
@@ -17,15 +17,23 @@ function AiSummaryDialog({ isOpen, onClose, ticleId }: AiSummaryDialogProps) {
AI 음성 요약
- {!data || data?.summary.length === 0 ? (
+ {!data && (
AI 요약을 처리중이에요.
- ) : (
- {data?.summary[0]}
+ )}
+ {data && !data.summaryText && (
+
+
+ AI 요약 결과가 없어요.
+
+
+ )}
+ {data && data.summaryText && (
+ {data.summaryText}
)}
diff --git a/apps/web/src/components/live/SettingDialog/SelectMedia.tsx b/apps/web/src/components/live/SettingDialog/SelectMedia.tsx
index 78152dfe..73fb42f4 100644
--- a/apps/web/src/components/live/SettingDialog/SelectMedia.tsx
+++ b/apps/web/src/components/live/SettingDialog/SelectMedia.tsx
@@ -18,7 +18,7 @@ function SelectMedia() {
stream?.getTracks().forEach((track) => track.stop());
- const cameraStream = await getCameraStream({ video: { deviceId: selectedVideoDeviceId } });
+ const cameraStream = await getCameraStream({ deviceId: selectedVideoDeviceId });
videoRef.current.srcObject = cameraStream;
@@ -28,6 +28,12 @@ function SelectMedia() {
getStream();
}, [selectedVideoDeviceId]);
+ useEffect(() => {
+ return () => {
+ stream?.getTracks().forEach((track) => track.stop());
+ };
+ }, [stream]);
+
return (
diff --git a/apps/web/src/hooks/useMediaTracks.ts b/apps/web/src/hooks/useMediaTracks.ts
index 53bb6f09..41c7787c 100644
--- a/apps/web/src/hooks/useMediaTracks.ts
+++ b/apps/web/src/hooks/useMediaTracks.ts
@@ -31,18 +31,11 @@ const useMediaTracks = () => {
);
const getCameraTrack = async () => {
- if (!selectedVideoDeviceId) {
- return;
- }
+ const options = selectedVideoDeviceId ? { deviceId: selectedVideoDeviceId } : {};
- const stream = await getCameraStream({
- video: { deviceId: selectedVideoDeviceId },
- });
+ const stream = await getCameraStream(options);
const track = stream.getVideoTracks()[0];
-
- if (!track) {
- return;
- }
+ if (!track) return;
setVideo({ stream, paused: true });
@@ -50,24 +43,13 @@ const useMediaTracks = () => {
};
const getAudioTrack = async () => {
- if (!selectedAudioDeviceId) {
- return;
- }
+ const options = selectedAudioDeviceId ? { deviceId: selectedAudioDeviceId } : {};
- const stream = await getMicStream({
- audio: {
- deviceId: {
- exact: selectedAudioDeviceId,
- ideal: selectedAudioDeviceId,
- },
- },
- });
+ const stream = await getMicStream(options);
const track = stream.getAudioTracks()[0];
- if (!track) {
- return;
- }
+ if (!track) return;
setAudio({ stream, paused: true });
@@ -83,9 +65,7 @@ const useMediaTracks = () => {
const track = stream.getVideoTracks()[0];
- if (!track) {
- return;
- }
+ if (!track) return;
setScreen({ stream, paused: false });
diff --git a/apps/web/src/utils/stream.ts b/apps/web/src/utils/stream.ts
index 9bcb4440..948f743e 100644
--- a/apps/web/src/utils/stream.ts
+++ b/apps/web/src/utils/stream.ts
@@ -19,7 +19,7 @@ const DEFAULT_SCREEN_CONSTRAINTS: MediaTrackConstraints = {
frameRate: { max: 30, ideal: 15 },
};
-const getCameraStream = async (options: MediaStreamConstraints = {}) => {
+const getCameraStream = async (options: MediaTrackConstraints = {}) => {
return navigator.mediaDevices.getUserMedia({
video: {
...DEFAULT_VIDEO_CONSTRAINTS,
@@ -28,7 +28,7 @@ const getCameraStream = async (options: MediaStreamConstraints = {}) => {
});
};
-const getMicStream = async (options: MediaStreamConstraints = {}) => {
+const getMicStream = async (options: MediaTrackConstraints = {}) => {
return navigator.mediaDevices.getUserMedia({
audio: {
...DEFAULT_AUDIO_CONSTRAINTS,
@@ -37,7 +37,7 @@ const getMicStream = async (options: MediaStreamConstraints = {}) => {
});
};
-const getScreenStream = async (options: MediaStreamConstraints = {}) => {
+const getScreenStream = async (options: MediaTrackConstraints = {}) => {
return navigator.mediaDevices.getDisplayMedia({
video: {
...DEFAULT_SCREEN_CONSTRAINTS,
diff --git a/packages/types/src/dashboard/getDashboardList.ts b/packages/types/src/dashboard/getDashboardList.ts
index 23363e3c..0c1349db 100644
--- a/packages/types/src/dashboard/getDashboardList.ts
+++ b/packages/types/src/dashboard/getDashboardList.ts
@@ -62,8 +62,13 @@ export const DashboardApplicantsResponseSchema = z.array(
export type DashboardApplicantsResponse = z.infer;
-export const DashboardAiSummaryResponseSchema = z.object({
- summary: z.array(z.string()),
-});
+export const DashboardAiSummaryResponseSchema = z
+ .object({
+ id: z.number(),
+ summaryText: z.string().nullable(),
+ audioUrl: z.string(),
+ createdAt: z.string().datetime(),
+ })
+ .nullable();
export type DashboardAiSummaryResponse = z.infer;