게시판에서 동영상 업로드를 가능케 했는데
썸네일도 나오지 않고 재생이 되지 않는 영상이 수두룩 했습니다.
확인해보니 video type이 type/QuickTime이고 확장자는 MOV라고 출력되었습니다.
아이폰으로 촬영한 동영상은 .mov로 저장되는데
사파리를 제외한 브라우저에서는 지원하지 않는 확장자인 것 같았습니다
(맥에서도 확인했지만 크롬기반 브라우저에서는 나오지 않고 사파리에서만 나왔다)
라떼는 용량도 맞추고 인코딩 곰인코더로 일일히변환해서 사이트에 업로드 하고했는데
떽;; 얼른 작업하자
http://ffmpeg.org/download.html 접속 후 본인 브라우저에 맞게 다운로드를 합니다
(저는 윈도우라 윈도우로....!)
window img에 hover 후 https://www.gyan.dev/ffmpeg/builds/ 클릭해줍니다
아래로 스크롤 하여 release builds에 essentials or full을 다운받는데, 큰 용량 차이가 나지 않는 것 같아서 목록 중 3번째인 ffmpeg-release-full.7z를 다운 받은 후 적당한 곳에 압축 해제를 해주었습니다(버전 확인! 저는 5.1.2!)
제가 저장한 실행파일의 위치는 C:\dev\ffmpeg-5.1.2-full_build\bin\ffmpeg.exe 입니다
https://mvnrepository.com/artifact/org.bytedeco/ffmpeg/5.1.2-1.5.8
저는 maven사용 중이라 mvnrepository에서 아까 다운 받은 버전과 일치하는 걸 찾아줍니다
그 후 spring - pom.xml에 붙여넣기 합니다
public void uploadVideo(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) {
String path = request.getSession().getServletContext().getRealPath("/video");
String originalFileName = multipartFile.getOriginalFilename(); // 오리지날 파일명
String fileType = multipartFile.getContentType().toLowerCase();
if(fileType.equals("video/quicktime")){
convertVideo(multipartFile,path); // mov -> mp4 변환
}
... 기존 업로드 코드
}
public void convertVideo(MultipartFile file, String path){
try{
File tempFile = File.createTempFile("temp", ".mov");
file.transferTo(tempFile);
String savedFileName = UUID.randomUUID() + ".mp4"; // 저장될 파일 명
File targetFile = new File(path, savedFileName);
ProcessBuilder processBuilder = new ProcessBuilder("C:\\dev\\ffmpeg-5.1.2-full_build\\bin\\ffmpeg.exe", "-i", tempFile.getAbsolutePath(), "-c:v", "libx264", "-preset", "veryfast", "-c:a", "aac", "-b:a", "192k", "-strict", "-2", targetFile.getAbsolutePath());
Process process = processBuilder.start();
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().close();
process.waitFor();
Path tempPath = Paths.get(tempFile.getAbsolutePath());
Files.deleteIfExists(tempPath);
}catch(Exception e){}
}
변환 과정 중 멈추는 문제가 발생하여 확인해보니 process.waitFor() 이 결과 값을 리턴하지 않고 행이 걸려서 무한대기 하는 상황이 발생하는 이슈가 있다고 했다. 여려 해결방안 중
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().close();
코드를 추가하니 해결되었다.
new ProcessBuilder()의 첫번째 인자는 ffmpeg.exe파일의 저장경로를 셋팅해주고
세번째는 복사할 파일(경로+파일명), 마지막은 인코딩된 파일이 저장될 곳(경로+파일명)을 의미한다
실제코드에서 업로드를 위해서 리턴타입이나 기타 코드를 제외한 인코딩만을 위한 코드를 올려봅니다. 코드 의미같은 건 아직 모르고 쓰는 것도 있기에 업로드 후 하나씩 공부해보려 합니다.
조금이라도 도움이 되면 좋겠습니다. 꾸벅