Skip to content

Commit

Permalink
feat: 동영상 업로드 시 인코딩된 동영상 또한 저장
Browse files Browse the repository at this point in the history
  • Loading branch information
SJ70 committed Oct 1, 2024
1 parent 9512416 commit 9cf7e32
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/main/java/com/j9/bestmoments/BestMomentsApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class BestMomentsApplication {

public static void main(String[] args) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/j9/bestmoments/service/FfmpegService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.InputStreamReader;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.io.IOException;

Expand All @@ -14,6 +15,7 @@ public class FfmpegService {
@Value("${ffmpeg.path}")
private String ffmpegPath;

@Async
public void encodeVideo(String inputFilePath, String outputFilePath, String resolution) {
try {
ProcessBuilder processBuilder = new ProcessBuilder(
Expand Down
37 changes: 34 additions & 3 deletions src/main/java/com/j9/bestmoments/service/VideoService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import com.j9.bestmoments.service.storageService.LocalStorageService;
import com.j9.bestmoments.util.FileNameGenerator;
import jakarta.persistence.EntityNotFoundException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
Expand All @@ -24,6 +26,7 @@ public class VideoService {

private final VideoRepository videoRepository;
private final LocalStorageService storageService;
private final FfmpegService ffmpegService;

@Transactional
public Video upload(Member member, VideoCreateDto createDto) {
Expand All @@ -34,18 +37,46 @@ public Video upload(Member member, VideoCreateDto createDto) {
.description(createDto.description())
.build();

String videoName = FileNameGenerator.generateVideoFileName(video, createDto.video());
String videoUrl = storageService.uploadFile(createDto.video(), videoName);
video.setVideoUrl(videoUrl);
// 원본 영상
String originVideoName = FileNameGenerator.generateVideoFileName(video, createDto.video());
String originVideoUrl = storageService.uploadFile(createDto.video(), originVideoName);
video.setVideoUrl(originVideoUrl);

// 썸네일 이미지
String thumbnailName = FileNameGenerator.generateThumbnailImageFileName(video, createDto.thumbnail());
String thumbnailUrl = storageService.uploadFile(createDto.thumbnail(), thumbnailName);
video.setThumbnailUrl(thumbnailUrl);

// 원본 사이즈 인코딩
String resolution = ffmpegService.getVideoResolution(originVideoUrl);
String encodedVideoUrl = uploadEncodedVideo(originVideoUrl, resolution);

// 1/2 사이즈 인코딩
String halfResolution = Arrays.stream(resolution.split("x"))
.mapToInt(Integer::parseInt)
.map(value -> value / 2)
.mapToObj(String::valueOf)
.collect(Collectors.joining("x"));
String halfEncodedVideoUrl = uploadEncodedVideo(originVideoUrl, halfResolution);

// 1/4 사이즈 인코딩
String quarterResolution = Arrays.stream(resolution.split("x"))
.mapToInt(Integer::parseInt)
.map(value -> value / 4)
.mapToObj(String::valueOf)
.collect(Collectors.joining("x"));
String quarterEncodedVideoUrl = uploadEncodedVideo(originVideoUrl, quarterResolution);

videoRepository.save(video);
return video;
}

private String uploadEncodedVideo(String videoUrl, String resolution) {
String encodedVideoUrl = FileNameGenerator.generateEncodedVideoFileName(videoUrl, resolution);
ffmpegService.encodeVideo(videoUrl, encodedVideoUrl, resolution);
return encodedVideoUrl;
}

public Page<Video> findAll(Pageable pageable) {
return videoRepository.findAll(
PageRequest.of(
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/j9/bestmoments/util/FileNameGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ public static String generateVideoFileName(Video video, MultipartFile file) {
return String.format("video/%s/video-origin.%s", videoId, contentType);
}

public static String generateEncodedVideoFileName(String videoFileName, String resolution) {
String[] splitFileName = videoFileName.split("-origin.");
String originVideoFileName = splitFileName[0];
return String.format("%s-%s.mp4", originVideoFileName, resolution);
}

public static String generateThumbnailImageFileName(Video video, MultipartFile file) {
String videoId = video.getId().toString();
String dateString = generateDateString();
Expand Down

0 comments on commit 9cf7e32

Please sign in to comment.