diff --git a/bulkupload/build.gradle b/bulkupload/build.gradle index 0ce5e4d5..ce0926e2 100644 --- a/bulkupload/build.gradle +++ b/bulkupload/build.gradle @@ -24,6 +24,9 @@ dependencies { implementation 'commons-fileupload:commons-fileupload:1.4' + implementation 'org.jcodec:jcodec:0.2.5' + implementation 'org.jcodec:jcodec-javase:0.2.5' + implementation "me.desair.tus:tus-java-server:1.0.0-2.0" compileOnly 'org.projectlombok:lombok' diff --git a/bulkupload/src/main/java/com/example/bulkupload/controller/TusUploadController.java b/bulkupload/src/main/java/com/example/bulkupload/controller/TusUploadController.java index 5d633481..1376414c 100644 --- a/bulkupload/src/main/java/com/example/bulkupload/controller/TusUploadController.java +++ b/bulkupload/src/main/java/com/example/bulkupload/controller/TusUploadController.java @@ -1,5 +1,6 @@ package com.example.bulkupload.controller; +import com.example.bulkupload.dto.UploadResponse; import com.example.bulkupload.service.FileUploadService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -28,18 +29,18 @@ public class TusUploadController { @CrossOrigin(origins = "*") @RequestMapping(value = {"/upload", "/upload/**"}) - public ResponseEntity uploadWithTus2(HttpServletRequest request, HttpServletResponse response) { - String filename = fileUploadService.process(request, response); - return httpOkStatus(filename); + public ResponseEntity uploadWithTus2(HttpServletRequest request, HttpServletResponse response) { + UploadResponse res = fileUploadService.process(request, response); + return httpOkStatus(res); } - private static ResponseEntity httpOkStatus(String filename) { + private static ResponseEntity httpOkStatus(UploadResponse res) { HttpHeaders headers = new HttpHeaders(); headers.set(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*"); return ResponseEntity.status(HttpStatus.OK) .headers(headers) - .body(filename); + .body(res); } @GetMapping("/video/{date}/{url}") diff --git a/bulkupload/src/main/java/com/example/bulkupload/dto/UploadResponse.java b/bulkupload/src/main/java/com/example/bulkupload/dto/UploadResponse.java new file mode 100644 index 00000000..9d04d0d0 --- /dev/null +++ b/bulkupload/src/main/java/com/example/bulkupload/dto/UploadResponse.java @@ -0,0 +1,12 @@ +package com.example.bulkupload.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class UploadResponse { + + private String videoUrl; + private String thumbnailUrl; +} diff --git a/bulkupload/src/main/java/com/example/bulkupload/service/FileUploadService.java b/bulkupload/src/main/java/com/example/bulkupload/service/FileUploadService.java index 99ea43f4..8ffb5880 100644 --- a/bulkupload/src/main/java/com/example/bulkupload/service/FileUploadService.java +++ b/bulkupload/src/main/java/com/example/bulkupload/service/FileUploadService.java @@ -1,5 +1,6 @@ package com.example.bulkupload.service; +import com.example.bulkupload.dto.UploadResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.desair.tus.server.TusFileUploadService; @@ -27,14 +28,14 @@ public class FileUploadService { @Value("${video.path}") private String savedPath; - public String process(HttpServletRequest request, HttpServletResponse response) { + public UploadResponse process(HttpServletRequest request, HttpServletResponse response) { try { tusFileUploadService.process(request, response); UploadInfo uploadInfo = tusFileUploadService.getUploadInfo(request.getRequestURI()); if (uploadInfo != null && !uploadInfo.isUploadInProgress()) { - String filename = createFile(tusFileUploadService.getUploadedBytes(request.getRequestURI()), uploadInfo.getFileName()); + UploadResponse filename = createFile(tusFileUploadService.getUploadedBytes(request.getRequestURI()), uploadInfo.getFileName()); tusFileUploadService.deleteUpload(request.getRequestURI()); @@ -49,18 +50,26 @@ public class FileUploadService { } } - private String createFile(InputStream is, String filename) throws IOException { + private UploadResponse createFile(InputStream is, String filename) throws IOException { String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 12); String[] split = filename.split("\\."); - String savedFilename = uuid + "." + split[split.length - 1]; - LocalDate today = LocalDate.now(); - File file = new File(savedPath + "/" + today, savedFilename); + + String uploadedPath = savedPath + "/" + today; + String videoName = uuid + "." + split[split.length - 1]; + + File file = new File(uploadedPath, videoName); FileUtils.copyInputStreamToFile(is, file); - return today + "/" + savedFilename; + String thumbnailName = ThumbnailExtractor.getThumbnail(file, uploadedPath, uuid); + + return UploadResponse.builder() + .videoUrl(today + "/" + videoName) + .thumbnailUrl(today + "/" + thumbnailName) + .build(); + } } \ No newline at end of file diff --git a/bulkupload/src/main/java/com/example/bulkupload/service/ThumbnailExtractor.java b/bulkupload/src/main/java/com/example/bulkupload/service/ThumbnailExtractor.java new file mode 100644 index 00000000..d9798509 --- /dev/null +++ b/bulkupload/src/main/java/com/example/bulkupload/service/ThumbnailExtractor.java @@ -0,0 +1,34 @@ +package com.example.bulkupload.service; + +import org.jcodec.api.FrameGrab; +import org.jcodec.api.JCodecException; +import org.jcodec.common.io.NIOUtils; +import org.jcodec.common.model.Picture; +import org.jcodec.scale.AWTUtil; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +public class ThumbnailExtractor { + + private static final String EXTENSION = "png"; + + public static String getThumbnail(File source, String path, String filename) { + try { + FrameGrab frameGrab = FrameGrab.createFrameGrab(NIOUtils.readableChannel(source)); + + frameGrab.seekToSecondPrecise(0); + + Picture picture = frameGrab.getNativeFrame(); + + BufferedImage bi = AWTUtil.toBufferedImage(picture); + ImageIO.write(bi, EXTENSION, new File(path, filename + "." + EXTENSION)); + + return filename + "." + EXTENSION; + } catch (IOException | JCodecException e) { + throw new RuntimeException(e); + } + } +} diff --git a/bulkupload/src/main/resources/templates/index.html b/bulkupload/src/main/resources/templates/index.html index eb7013bd..dd9f385f 100644 --- a/bulkupload/src/main/resources/templates/index.html +++ b/bulkupload/src/main/resources/templates/index.html @@ -115,7 +115,8 @@ }, onSuccess: function () { $('#js-upload-text-progress_' + key).html("파일 저장 완료"); - } + }, + }); toggleBtn.addEventListener('click', (e) => {