Spring에서 .mov파일을 .mp4파일로 변환하기

dongs·2023년 2월 17일
0

게시판에서 동영상 업로드를 가능케 했는데
썸네일도 나오지 않고 재생이 되지 않는 영상이 수두룩 했습니다.

확인해보니 video type이 type/QuickTime이고 확장자는 MOV라고 출력되었습니다.

아이폰으로 촬영한 동영상은 .mov로 저장되는데
사파리를 제외한 브라우저에서는 지원하지 않는 확장자인 것 같았습니다
(맥에서도 확인했지만 크롬기반 브라우저에서는 나오지 않고 사파리에서만 나왔다)

라떼는 용량도 맞추고 인코딩 곰인코더로 일일히변환해서 사이트에 업로드 하고했는데
떽;; 얼른 작업하자

외부셋팅

  1. http://ffmpeg.org/download.html 접속 후 본인 브라우저에 맞게 다운로드를 합니다
    (저는 윈도우라 윈도우로....!)

  2. window img에 hover 후 https://www.gyan.dev/ffmpeg/builds/ 클릭해줍니다

  3. 아래로 스크롤 하여 release builds에 essentials or full을 다운받는데, 큰 용량 차이가 나지 않는 것 같아서 목록 중 3번째인 ffmpeg-release-full.7z를 다운 받은 후 적당한 곳에 압축 해제를 해주었습니다(버전 확인! 저는 5.1.2!)

  4. 제가 저장한 실행파일의 위치는 C:\dev\ffmpeg-5.1.2-full_build\bin\ffmpeg.exe 입니다

스프링

  1. https://mvnrepository.com/artifact/org.bytedeco/ffmpeg/5.1.2-1.5.8
    저는 maven사용 중이라 mvnrepository에서 아까 다운 받은 버전과 일치하는 걸 찾아줍니다
    그 후 spring - pom.xml에 붙여넣기 합니다

  2. 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파일의 저장경로를 셋팅해주고
세번째는 복사할 파일(경로+파일명), 마지막은 인코딩된 파일이 저장될 곳(경로+파일명)을 의미한다

실제코드에서 업로드를 위해서 리턴타입이나 기타 코드를 제외한 인코딩만을 위한 코드를 올려봅니다. 코드 의미같은 건 아직 모르고 쓰는 것도 있기에 업로드 후 하나씩 공부해보려 합니다.

조금이라도 도움이 되면 좋겠습니다. 꾸벅

profile
제발개발

0개의 댓글

Powered by GraphCDN, the GraphQL CDN