diff --git a/src/main/java/com/bivashy/backend/composer/controller/TrackController.java b/src/main/java/com/bivashy/backend/composer/controller/TrackController.java index c249ebb..582416f 100644 --- a/src/main/java/com/bivashy/backend/composer/controller/TrackController.java +++ b/src/main/java/com/bivashy/backend/composer/controller/TrackController.java @@ -14,10 +14,10 @@ import org.springframework.web.bind.annotation.RestController; import com.bivashy.backend.composer.auth.CustomUserDetails; import com.bivashy.backend.composer.dto.track.AddLocalTrackRequest; -import com.bivashy.backend.composer.dto.track.AddYoutubeTrackRequest; import com.bivashy.backend.composer.dto.track.PlaylistTrackResponse; import com.bivashy.backend.composer.dto.track.TrackBulkReorderRequest; import com.bivashy.backend.composer.dto.track.TrackResponse; +import com.bivashy.backend.composer.dto.track.YoutubeTrackRequest; import com.bivashy.backend.composer.dto.track.service.AddLocalTrackParamsBuilder; import com.bivashy.backend.composer.exception.ImportTrackException; import com.bivashy.backend.composer.service.TrackService; @@ -47,7 +47,7 @@ public class TrackController { public ResponseEntity> addYoutubeTrack( @AuthenticationPrincipal CustomUserDetails user, @PathVariable long playlistId, - @RequestBody AddYoutubeTrackRequest request) throws ImportTrackException { + @RequestBody YoutubeTrackRequest request) throws ImportTrackException { List response = trackService.addYoutubeTrack(user, playlistId, request); return ResponseEntity.ok(response); } diff --git a/src/main/java/com/bivashy/backend/composer/dto/track/AddYoutubeTrackRequest.java b/src/main/java/com/bivashy/backend/composer/dto/track/AddYoutubeTrackRequest.java deleted file mode 100644 index bf68275..0000000 --- a/src/main/java/com/bivashy/backend/composer/dto/track/AddYoutubeTrackRequest.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.bivashy.backend.composer.dto.track; - -public record AddYoutubeTrackRequest(String youtubeUrl) { -} diff --git a/src/main/java/com/bivashy/backend/composer/dto/track/YoutubeTrackRequest.java b/src/main/java/com/bivashy/backend/composer/dto/track/YoutubeTrackRequest.java new file mode 100644 index 0000000..0ae8ad5 --- /dev/null +++ b/src/main/java/com/bivashy/backend/composer/dto/track/YoutubeTrackRequest.java @@ -0,0 +1,4 @@ +package com.bivashy.backend.composer.dto.track; + +public record YoutubeTrackRequest(String youtubeUrl) { +} diff --git a/src/main/java/com/bivashy/backend/composer/service/AudioBlobStorageService.java b/src/main/java/com/bivashy/backend/composer/service/AudioBlobStorageService.java index d9faaed..3b65e82 100644 --- a/src/main/java/com/bivashy/backend/composer/service/AudioBlobStorageService.java +++ b/src/main/java/com/bivashy/backend/composer/service/AudioBlobStorageService.java @@ -17,7 +17,7 @@ public interface AudioBlobStorageService { String store(byte[] data, Map metadata); - String store(String key, byte[] data); + String store(String key, byte[] data, Map metadata); byte[] readRaw(String path) throws IOException; diff --git a/src/main/java/com/bivashy/backend/composer/service/AudioS3StorageService.java b/src/main/java/com/bivashy/backend/composer/service/AudioS3StorageService.java index ee1a70b..5454518 100644 --- a/src/main/java/com/bivashy/backend/composer/service/AudioS3StorageService.java +++ b/src/main/java/com/bivashy/backend/composer/service/AudioS3StorageService.java @@ -78,7 +78,7 @@ public class AudioS3StorageService implements AudioBlobStorageService { } @Override - public String store(String key, byte[] data) { + public String store(String key, byte[] data, Map metadata) { try { ResponseInputStream response = s3Client.getObject(GetObjectRequest.builder() .bucket(bucket) @@ -89,7 +89,7 @@ public class AudioS3StorageService implements AudioBlobStorageService { .bucket(bucket) .key(key) .contentType(response.response().contentType()) - .metadata(response.response().metadata()) + .metadata(metadata) .build(), RequestBody.fromBytes(data)); return key; @@ -98,6 +98,7 @@ public class AudioS3StorageService implements AudioBlobStorageService { s3Client.putObject(PutObjectRequest.builder() .bucket(bucket) .key(key) + .metadata(metadata) .build(), RequestBody.fromBytes(data)); return key; } diff --git a/src/main/java/com/bivashy/backend/composer/service/TrackService.java b/src/main/java/com/bivashy/backend/composer/service/TrackService.java index 40831ea..855474b 100644 --- a/src/main/java/com/bivashy/backend/composer/service/TrackService.java +++ b/src/main/java/com/bivashy/backend/composer/service/TrackService.java @@ -1,12 +1,12 @@ package com.bivashy.backend.composer.service; -import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.stream.Stream; @@ -20,10 +20,10 @@ import org.springframework.web.server.ResponseStatusException; import com.bivashy.backend.composer.auth.CustomUserDetails; import com.bivashy.backend.composer.dto.importing.SingleTrackProgress; -import com.bivashy.backend.composer.dto.track.AddYoutubeTrackRequest; import com.bivashy.backend.composer.dto.track.PlaylistTrackResponse; import com.bivashy.backend.composer.dto.track.TrackBulkReorderRequest; import com.bivashy.backend.composer.dto.track.TrackResponse; +import com.bivashy.backend.composer.dto.track.YoutubeTrackRequest; import com.bivashy.backend.composer.dto.track.service.AddLocalTrackParams; import com.bivashy.backend.composer.dto.track.service.AddLocalTrackParamsBuilder; import com.bivashy.backend.composer.exception.ImportTrackException; @@ -128,7 +128,7 @@ public class TrackService { @Transactional public List addYoutubeTrack(CustomUserDetails user, long playlistId, - AddYoutubeTrackRequest request) throws ImportTrackException { + YoutubeTrackRequest request) throws ImportTrackException { List videoInfos = Collections.emptyList(); try { videoInfos = YtDlp.getVideoInfo(request.youtubeUrl()); @@ -226,7 +226,7 @@ public class TrackService { var body = Files.readAllBytes(path); if (isMetadataFile) { - s3StorageService.store(downloadedMetadataKey, body); + s3StorageService.store(downloadedMetadataKey, body, Map.of()); continue; } String fileName = fileNameWithoutExtension(path.getFileName().toString()); @@ -239,7 +239,6 @@ public class TrackService { logger.info("downloaded file {} and info {}, key {}", fileName, videoInfo.getTitle(), audioKey); - audioKey = s3StorageService.store(audioKey, body); Optional metadata = Optional.empty(); try (var inputStream = Files.newInputStream(path)) { @@ -251,8 +250,8 @@ public class TrackService { TrackSource playlistEntrySource; try { - playlistEntrySource = trackSourceService.createLocalTrackSource( - body, ffprobeJson, OBJECT_MAPPER.writeValueAsString(videoInfo), SourceTypes.PLAYLIST); + playlistEntrySource = trackSourceService.createTrackSourceWithKey(audioKey, body, ffprobeJson, + OBJECT_MAPPER.writeValueAsString(videoInfo), SourceTypes.PLAYLIST); } catch (IOException e) { throw new ImportTrackException("cannot read blob body", e); } @@ -266,7 +265,7 @@ public class TrackService { // TODO: Recognize music if the duration is less than five minutes // (configurable), and if not, it is a playlist and should be marked as is trackMetadataService.createTrackMetadata( - track, title, fileName, trackSource.getSourceUrl(), artist, null, durationSeconds); + track, title, fileName, audioKey, artist, null, durationSeconds); trackPlaylistService.insertTrackAtEnd(playlistId, track.getId()); diff --git a/src/main/java/com/bivashy/backend/composer/service/TrackSourceService.java b/src/main/java/com/bivashy/backend/composer/service/TrackSourceService.java index ad56bee..eeebfff 100644 --- a/src/main/java/com/bivashy/backend/composer/service/TrackSourceService.java +++ b/src/main/java/com/bivashy/backend/composer/service/TrackSourceService.java @@ -43,6 +43,19 @@ public class TrackSourceService { return trackSourceRepository.save(new TrackSource(audioPath, type, LocalDateTime.now())); } + public TrackSource createTrackSourceWithKey(String key, byte[] audioBytes, String ffprobeJson, + String ytdlpMetadata, String sourceType) { + Map metadata = new HashMap<>(Map.of(YTDLP_METADATA_KEY, ffprobeJson)); + if (ytdlpMetadata != null) { + // TODO: Add tag or smth? + } + String audioPath = s3Service.store(key, audioBytes, metadata); + + SourceType type = sourceTypeRepository.findByName(sourceType) + .orElseThrow(() -> new IllegalStateException("Source type not found: " + sourceType)); + return trackSourceRepository.save(new TrackSource(audioPath, type, LocalDateTime.now())); + } + public TrackSource createYoutubeTrackSource(String sourceType) { String folderPath = s3Service.storeFolder(); SourceType type = sourceTypeRepository.findByName(sourceType)