Skip to content

Commit 7ce6224

Browse files
lsakeeSangwook123
authored andcommitted
[feat] #62 upload record
1 parent cdca1d2 commit 7ce6224

File tree

6 files changed

+65
-30
lines changed

6 files changed

+65
-30
lines changed

data/video/src/main/java/com/record/video/model/remote/request/RequestPostVideoDto.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ data class RequestPostVideoDto(
1212
@SerialName("fileUrl")
1313
val fileUrl: FileUrl,
1414
@SerialName("keywords")
15-
val keywords: List<String>,
15+
val keywords: String,
1616
@SerialName("location")
1717
val location: String,
1818
)

data/video/src/main/java/com/record/video/repository/UploadRepositoryImpl.kt

-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ class UploadRepositoryImpl @Inject constructor(
4040
is HttpException -> {
4141
throw ApiError(exception.message())
4242
}
43-
4443
else -> {
4544
throw exception
4645
}

domain/upload/src/main/java/com/record/upload/model/VideoInfo.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.record.upload.model
33
data class VideoInfo(
44
val location: String,
55
val content: String,
6-
val keywords: List<String>,
6+
val keywords: String,
77
val videoUrl: String,
88
val previewUrl: String,
99
)

feature/upload/src/main/java/com/record/upload/UploadViewModel.kt

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
package com.record.upload
22

33
import android.content.Context
4+
import android.util.Base64
45
import android.util.Log
56
import androidx.lifecycle.viewModelScope
67
import com.record.ui.base.BaseViewModel
78
import com.record.upload.extension.GalleryVideo
89
import com.record.upload.extension.uploadFileToS3PresignedUrl
910
import com.record.upload.extension.uploadFileToS3ThumbnailPresignedUrl
11+
import com.record.upload.model.VideoInfo
1012
import com.record.upload.repository.UploadRepository
1113
import dagger.hilt.android.lifecycle.HiltViewModel
1214
import kotlinx.coroutines.launch
1315
import java.io.File
16+
import java.net.URLDecoder
1417
import javax.inject.Inject
1518

1619
@HiltViewModel
@@ -37,18 +40,48 @@ class UploadViewModel @Inject constructor(
3740
}
3841
}
3942

43+
private fun decodeBase64(encodedString: String): String? {
44+
val decodedBytes = Base64.decode(encodedString, Base64.DEFAULT)
45+
val decodedString = String(decodedBytes, Charsets.UTF_8)
46+
return URLDecoder.decode(decodedString, "UTF-8")
47+
}
48+
4049
fun uploadVideoToS3Bucket(context: Context, file: File) =
4150
viewModelScope.launch {
4251
uploadFileToS3PresignedUrl(uiState.value.bucketUrl, file) { success, message ->
4352
println(message)
4453
Log.d("messageFile", "$message ")
4554
}
46-
uploadFileToS3ThumbnailPresignedUrl(context, uiState.value.thumbnailUrl, file) { success, message ->
55+
uploadFileToS3ThumbnailPresignedUrl(
56+
context,
57+
uiState.value.thumbnailUrl,
58+
file,
59+
) { success, message ->
4760
println(message)
4861
Log.d("messageThumbnail", "$message ")
4962
}
63+
uploadRecord()
5064
}
5165

66+
fun uploadRecord() =
67+
viewModelScope.launch {
68+
uploadRepository.uploadRecord(
69+
videoInfo = VideoInfo(
70+
location = "test",
71+
content = "test",
72+
keywords = encodingString("감각적인,강렬한,귀여운").trim(),
73+
videoUrl = "https://recordy-bucket.s3.ap-northeast-2.amazonaws.com/videos/40683dd4-52a3-4bb1-9833-7fb2256285e9.mp4",
74+
previewUrl = "https://recordy-bucket.s3.ap-northeast-2.amazonaws.com/thumbnails/0ed9dfc0-8e41-491f-b4fb-2d7ea9a5d5e3.jpeg",
75+
),
76+
)
77+
}
78+
79+
private fun encodingString(contentValue: String): String {
80+
val bytes = contentValue.toByteArray(Charsets.UTF_8)
81+
val encodedString = Base64.encodeToString(bytes, Base64.DEFAULT)
82+
return encodedString
83+
}
84+
5285
fun setVideo(video: GalleryVideo) = intent {
5386
copy(video = video)
5487
}

feature/upload/src/main/java/com/record/upload/VideoPickerScreen.kt

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ fun VideoPickerRoute(
8282
LaunchedEffectWithLifecycle {
8383
viewModel.getPresignedUrl()
8484
viewModel.sideEffect.collectLatest { }
85+
viewModel.uploadRecord()
8586
}
8687

8788
VideoPickerScreen(

feature/upload/src/main/java/com/record/upload/extension/UploadExtension.kt

+28-26
Original file line numberDiff line numberDiff line change
@@ -175,25 +175,26 @@ fun uploadFileToS3PresignedUrl(presignedUrl: String, file: File, callback: (Bool
175175
.url(presignedUrl)
176176
.put(requestBody)
177177
.build()
178+
client.newCall(request).enqueue(
179+
object : okhttp3.Callback {
180+
override fun onFailure(call: okhttp3.Call, e: IOException) {
181+
callback(false, "Upload failed: ${e.message}")
182+
}
178183

179-
client.newCall(request).enqueue(object : okhttp3.Callback {
180-
override fun onFailure(call: okhttp3.Call, e: IOException) {
181-
callback(false, "Upload failed: ${e.message}")
182-
}
183-
184-
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
185-
if (response.isSuccessful) {
186-
callback(true, "Upload successful")
187-
} else {
188-
callback(false, "Upload failed: ${response.message}")
184+
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
185+
if (response.isSuccessful) {
186+
callback(true, "Upload successful")
187+
} else {
188+
callback(false, "Upload failed: ${response.message}")
189+
}
189190
}
190-
}
191-
},)
191+
},
192+
)
192193
}
193194

194195
fun uploadFileToS3ThumbnailPresignedUrl(context: Context, presignedUrl: String, file: File, callback: (Boolean, String) -> Unit) {
195196
val videoPath = file.absolutePath
196-
val outputImagePath = File(context.cacheDir, "${ file.name }.jpg")
197+
val outputImagePath = File(context.cacheDir, file.name)
197198
getVideoFrameAt1Sec(videoPath, outputImagePath.absolutePath)
198199
val client = OkHttpClient()
199200
val mediaType = "application/octet-stream".toMediaTypeOrNull()
@@ -203,26 +204,27 @@ fun uploadFileToS3ThumbnailPresignedUrl(context: Context, presignedUrl: String,
203204
.url(presignedUrl)
204205
.put(requestBody)
205206
.build()
207+
client.newCall(request).enqueue(
208+
object : okhttp3.Callback {
209+
override fun onFailure(call: okhttp3.Call, e: IOException) {
210+
callback(false, "Upload failed: ${e.message}")
211+
}
206212

207-
client.newCall(request).enqueue(object : okhttp3.Callback {
208-
override fun onFailure(call: okhttp3.Call, e: IOException) {
209-
callback(false, "Upload failed: ${e.message}")
210-
}
211-
212-
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
213-
if (response.isSuccessful) {
214-
callback(true, "Upload successful")
215-
} else {
216-
callback(false, "Upload failed: ${response.message}")
213+
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
214+
if (response.isSuccessful) {
215+
callback(true, "Upload successful")
216+
} else {
217+
callback(false, "Upload failed: ${response.message}")
218+
}
217219
}
218-
}
219-
},)
220+
},
221+
)
220222
}
221223
fun getVideoFrameAt1Sec(videoPath: String, outputImagePath: String) {
222224
val retriever = MediaMetadataRetriever()
223225
try {
224226
retriever.setDataSource(videoPath)
225-
val timeUs = 1 * 1000000 // 1초를 마이크로초로 변환
227+
val timeUs = 1 * 1000000
226228
val bitmap: Bitmap? = retriever.getFrameAtTime(timeUs.toLong(), MediaMetadataRetriever.OPTION_CLOSEST_SYNC)
227229

228230
if (bitmap != null) {

0 commit comments

Comments
 (0)