작성
·
2.2K
0
react - spring 으로 블로그 만들기 프로젝트를 개인적으로 하고있습니다.
image를 blob형태로 가져와서 띄우는 것 까진 잘 되는데, 영상 재생이 원활히 되지 않아서 질문을 남깁니다.
public ResponseEntity<Resource> getVideo(String videoName) throws IOException {
String fileDirectory = "src/main/resources/static/video/";
String fileName = videoName + getExtension(fileDirectory, videoName);
Path videoPath = Paths.get(fileDirectory + fileName);
Resource videoResource = new UrlResource(videoPath.toUri());
System.out.println("videoResource = " + videoResource);
String videoUrl = "http://localhost:4000/videos/" + fileName;
System.out.println("videoUrl = " + videoUrl);
return ResponseEntity.ok()
.contentType(MediaType.valueOf("video/mp4")) // 비디오 타입에 맞게 설정
.body(videoResource);
}
서버측에서 다음과 같이 로컬에 저장된 영상을 프론트로 보내줍니다.(임시)
이후 프론트에서 이를 재생하려고 하는데,
export const getVideoApi = async (token: string | null, videoName: string | number) => {
const url = `http://localhost:4000/api/videos/${videoName}`;
try {
const response = await axios.get(url, {
headers: {
Authorization: `Bearer ${token}`,
},
responseType : "blob",
});
console.log(response.data)
const videoUrl = URL.createObjectURL(response.data);
console.log(videoUrl)
return videoUrl;
} catch (error) {
console.error("Error fetching board data:", error);
return null;
}
};
video를 다음과 같은 api호출로 가져오고, 저장하였습니다.
useEffect(() => {
async function fetchProfileImage() {
try {
if (!boardData) return; // Return early if boardData is not available yet
const token = cookies.token;
const profileUrl = await getImageApi(token, boardData.boardWriterEmail);
setProfileImages({ [boardData.boardNumber]: profileUrl });
const imageUrl = await getImageApi(
token,
boardData.boardNumber.toString()
);
setBoardImages({ [boardData.boardNumber]: imageUrl });
const videoName = boardData.boardNumber.toString();
const videoBlobUrl = await getVideoApi(token, videoName);
setVideoUrl(videoBlobUrl || undefined);
} catch (error) {
console.error("Error fetching profile image:", error);
setVideoUrl(undefined);
}
}
fetchProfileImage();
return () => {
// Clean up Blob URL when the component unmounts
if (videoUrl) {
URL.revokeObjectURL(videoUrl);
}
console.log(videoUrl);
};
}, [boardData,cookies.token]);
그리고 다음과 같이, 게시물에 접속할 때, 게시물의 사진과 영상이 보여질 수 있도록 useEffect()를 사용하였고 여기서 받은 링크를
{boardVideo && (
<div>
<video
width="60%"
controls
style={{
display: "block", // Center align the video
margin: "0 auto", // Center align the video
}}
>
<source src={videoUrl || "default.mp4"} type="video/mp4" />
Your browser does not support the video tag.
</video>
<p>videoUrl: {videoUrl}</p>
</div>
)}
이런식으로 보여주려고 하고있습니다. (p,div 태그는 로그를 찍어보기 위함)
브라우저 개발자 도구에서, 영상이 제대로 프론트로 넘어오는 것 까진 확인이 되는데, 생성한 blobUrl로 영상을 불러오는 것이 잡히지 않았고, 또한 bloburl을 2번 생성하는 것을 확인할 수 있었습니다.
리액트에 관한 지식이 많이 부족하고, 공부하지 않은 터라, useEffect를 사용하는데 미숙해서 그런건지, 왜 2번이나 bloburl을 만드는지도 이해가 가지 않고, 영상이 재생되지 않는 부분도 이해가 가지 않습니다. blob으론 영상을 재생할 수 없는 것이라면, 서버에서 url을 string으로 넘겨주는 방식을 사용해야하는건지도 궁금합니다. 아래와 같이 blob 객체가 2번 보이고, url도 두개가 생성됩니다.
Blob {size: 34970691, type: 'video/mp4'}
fileApis.ts:53 blob:http://localhost:3000/c7bb643e-2d0b-4838-9b8b-dd0863a349d4
fileApis.ts:50 Blob {size: 34970691, type: 'video/mp4'}
fileApis.ts:53 blob:http://localhost:3000/dfe61c3b-8faa-4b01-8a3c-1ef7a743ce6a
제 이해가 많이 부족합니다. 혹시 blob방식을 사용하는 것이 옳지 않은 건지, 스프링과 리액트를 같이 사용할 때 (혹은 타 프레임워크를 사용하더라도,) 서버에 저장되어있는 영상을 프론트에서 재생하는데 좋은 방법이 있다면 알려주시면 감사하겠습니다.
답변 1
1
안녕하세요, 인프런 AI 인턴이에요. 영상을 blob 형태로 가져오고 싶으신 것 같은데요, 현재 서버측에서는 영상을 로컬에 저장하여 프론트로 보내주고 있습니다. 프론트에서 이를 재생하기 위해서는 HTML5 비디오 태그를 이용해야 합니다.
우선, 프론트 코드에서 해당 비디오를 재생하는 부분을 구현해야 합니다. 아래와 같이 비디오 태그를 사용하여 특정 URL에서 비디오를 재생할 수 있습니다.
<video controls>
<source src={videoUrl} type="video/mp4" />
</video>
위의 코드에서 videoUrl
은 서버에서 받아온 영상 URL을 할당하면 됩니다.
또한, 서버에서는 videoUrl
에 해당하는 경로로 접근이 가능하도록 프론트에 CORS(Cross-Origin Resource Sharing) 설정을 해주어야 합니다. 이 설정을 위해서는 서버 측에서 CORS 관련 헤더를 설정해 주어야 합니다.
서버에서는 CORS 관련 설정을 아래와 같이 해주면 됩니다.
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/videos/**")
.allowedOrigins("*")
.allowedMethods("GET");
}
}
위의 코드에서 allowedOrigins
에는 프론트에서 사용하는 도메인을 입력하시면 됩니다.
이렇게 하면 프론트에서 비디오를 재생할 수 있을 것입니다. 혹시 문제가 있거나 더 자세한 설명이 필요하시면 말씀해주세요. 참고로, 위의 내용은 예시에 대한 설명일 뿐 실제 코드 상황에 따라 다를 수 있으니 참고하시길 바랍니다. 어려운 내용이나 추가 질문이 있으신 경우에는 프로젝트 코드나 좀 더 자세한 정보를 알려주시면 도움을 드리겠습니다. 감사합니다.~요.