Skip to content

Commit 06a9836

Browse files
lsakeeSangwook123
authored andcommitted
[feat] #62 add domain,data
1 parent 8ec2239 commit 06a9836

File tree

8 files changed

+129
-23
lines changed

8 files changed

+129
-23
lines changed

core/common/src/main/java/com/record/common/util/EncodingUtil.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ fun encodingString(contentValue: String): String {
1919
val bytes = contentValue.toByteArray(Charsets.UTF_8)
2020
val encodedString = android.util.Base64.encodeToString(bytes, android.util.Base64.DEFAULT)
2121
return encodedString
22-
}
22+
}

feature/upload/build.gradle.kts

+3-7
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,10 @@ android {
77
}
88

99
dependencies {
10-
implementation("com.google.accompanist:accompanist-permissions:0.34.0")
11-
implementation("com.google.accompanist:accompanist-insets:0.24.13-rc")
12-
implementation("com.google.accompanist:accompanist-systemuicontroller:0.24.13-rc")
13-
implementation("com.github.AbedElazizShe:LightCompressor:1.3.2")
10+
implementation(libs.bundles.aws)
11+
implementation(libs.bundles.accompanist)
12+
implementation(libs.lightcompressor)
1413
implementation(projects.domain.upload)
1514
implementation(projects.domain.keyword)
1615
implementation(projects.core.common)
17-
implementation("com.amazonaws:aws-android-sdk-mobile-client:2.13.5")
18-
implementation("com.amazonaws:aws-android-sdk-cognito:2.13.5")
19-
implementation("com.amazonaws:aws-android-sdk-s3:2.13.5")
2016
}

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

+43-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
package com.record.upload
22

3+
import android.content.Context
34
import android.util.Log
45
import androidx.lifecycle.viewModelScope
56
import com.record.common.util.encodingString
67
import com.record.designsystem.component.snackbar.SnackBarType
78
import com.record.keyword.repository.KeywordRepository
89
import com.record.ui.base.BaseViewModel
910
import com.record.upload.extension.GalleryVideo
11+
import com.record.upload.extension.uploadFileToS3PresignedUrl
12+
import com.record.upload.extension.uploadFileToS3ThumbnailPresignedUrl
1013
import com.record.upload.model.VideoInfo
1114
import com.record.upload.repository.UploadRepository
1215
import dagger.hilt.android.lifecycle.HiltViewModel
16+
import kotlinx.coroutines.Dispatchers
1317
import kotlinx.coroutines.launch
1418
import java.io.File
19+
import java.net.URL
1520
import javax.inject.Inject
1621

1722
@HiltViewModel
@@ -36,22 +41,50 @@ class UploadViewModel @Inject constructor(
3641
Log.d("failure", "${it.message}")
3742
}
3843
}
44+
fun removeQueryParameters(urlString: String): String {
45+
val url = URL(urlString)
46+
val cleanUrl = URL(url.protocol, url.host, url.port, url.path)
47+
return cleanUrl.toString()
48+
}
49+
3950

40-
fun uploadVideoToS3Bucket(file: File) =
51+
fun uploadVideoToS3Bucket(context: Context, file: File) =
4152
viewModelScope.launch {
42-
uploadRepository.uploadVideoToS3Bucket(
53+
var a = ""
54+
var b = ""
55+
uploadFileToS3PresignedUrl(
4356
uiState.value.bucketUrl,
44-
file,
45-
).onSuccess { videoUrl ->
46-
uploadRepository.uploadThumbnailToS3Bucket(
47-
uiState.value.thumbnailUrl,
48-
file,
49-
).onSuccess { thumbNailUrl ->
50-
uploadRecord(videoUrl, thumbNailUrl)
57+
file
58+
) { success, message ->
59+
println(message)
60+
a = removeQueryParameters(message)
61+
if (success) {
62+
uploadFileToS3ThumbnailPresignedUrl(
63+
context,
64+
uiState.value.thumbnailUrl,
65+
file,
66+
) { success, message ->
67+
println(message)
68+
b = removeQueryParameters(message)
69+
uploadRecord(a, b)
70+
}
5171
}
52-
}.onFailure {
5372
}
5473
}
74+
// fun uploadVideoToS3Bucket(file: File) = viewModelScope.launch(Dispatchers.IO) {
75+
// uploadRepository.uploadVideoToS3Bucket(
76+
// uiState.value.bucketUrl,
77+
// file,
78+
// ).onSuccess { videoUrl ->
79+
// uploadRepository.uploadThumbnailToS3Bucket(
80+
// uiState.value.thumbnailUrl,
81+
// file,
82+
// ).onSuccess { thumbNailUrl ->
83+
// uploadRecord(videoUrl, thumbNailUrl)
84+
// }
85+
// }.onFailure {
86+
// }
87+
// }
5588

5689
fun uploadRecord(videoS3Url: String, thumbnailS3Url: String) {
5790
viewModelScope.launch {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ fun VideoPickerRoute(
130130
state = state,
131131
onClickContentChip = viewModel::setSelectedList,
132132
onClickVideo = viewModel::setVideo,
133-
uploadVideoS3Bucket = viewModel::uploadVideoToS3Bucket,
133+
uploadVideoS3Bucket = { viewModel.uploadVideoToS3Bucket(context,it) },
134134
locationFocusRequester = locationFocusRequester,
135135
contentFocusRequester = locationFocusRequester,
136136
updateLocationTextField = viewModel::updateLocationTextField,

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

+59
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,16 @@ import com.abedelazizshe.lightcompressorlibrary.VideoQuality
1212
import com.abedelazizshe.lightcompressorlibrary.config.Configuration
1313
import com.abedelazizshe.lightcompressorlibrary.config.SaveLocation
1414
import com.abedelazizshe.lightcompressorlibrary.config.SharedStorageConfiguration
15+
import com.record.common.util.getVideoFrameAt1Sec
1516
import kotlinx.coroutines.CoroutineScope
1617
import kotlinx.coroutines.Dispatchers
1718
import kotlinx.coroutines.launch
19+
import okhttp3.MediaType.Companion.toMediaTypeOrNull
20+
import okhttp3.OkHttpClient
21+
import okhttp3.Request
22+
import okhttp3.RequestBody
23+
import java.io.File
24+
import java.io.IOException
1825

1926
fun getAllVideos(
2027
loadSize: Int,
@@ -93,7 +100,59 @@ fun getVideoDuration(context: Context, uri: Uri): Long {
93100
retriever.release()
94101
}
95102
}
103+
fun uploadFileToS3PresignedUrl(presignedUrl: String, file: File, callback: (Boolean, String) -> Unit) {
104+
val client = OkHttpClient()
105+
val mediaType = "application/octet-stream".toMediaTypeOrNull()
106+
val requestBody = RequestBody.create(mediaType, file)
96107

108+
val request = Request.Builder()
109+
.url(presignedUrl)
110+
.put(requestBody)
111+
.build()
112+
client.newCall(request).enqueue(
113+
object : okhttp3.Callback {
114+
override fun onFailure(call: okhttp3.Call, e: IOException) {
115+
callback(false, "Upload failed: ${e.message}")
116+
}
117+
118+
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
119+
if (response.isSuccessful) {
120+
callback(true, "${response.request.url}")
121+
} else {
122+
callback(false, "Upload failed: ${response.message}")
123+
}
124+
}
125+
},
126+
)
127+
}
128+
fun uploadFileToS3ThumbnailPresignedUrl(context: Context, presignedUrl: String, file: File, callback: (Boolean, String) -> Unit) {
129+
val videoPath = file.absolutePath
130+
val outputImagePath = File(context.cacheDir, file.name)
131+
getVideoFrameAt1Sec(videoPath, outputImagePath.absolutePath)
132+
val client = OkHttpClient()
133+
val mediaType = "application/octet-stream".toMediaTypeOrNull()
134+
val requestBody = RequestBody.create(mediaType, outputImagePath)
135+
136+
val request = Request.Builder()
137+
.url(presignedUrl)
138+
.put(requestBody)
139+
.build()
140+
client.newCall(request).enqueue(
141+
object : okhttp3.Callback {
142+
override fun onFailure(call: okhttp3.Call, e: IOException) {
143+
callback(false, "Upload failed: ${e.message}")
144+
}
145+
146+
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
147+
if (response.isSuccessful) {
148+
callback(true, "${response.request.url}")
149+
} else {
150+
callback(false, "Upload failed: ${response.message}")
151+
}
152+
}
153+
},
154+
)
155+
}
97156
fun formatDuration(durationMillis: Long): String {
98157
val minutes = (durationMillis / 1000) / 60
99158
val seconds = (durationMillis / 1000) % 60

gradle/libs.versions.toml

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
[versions]
22
# SDK Versions
3+
accompanistInsets = "0.24.13-rc"
4+
accompanistPermissions = "0.34.0"
5+
awsAndroidSdkMobileClient = "2.13.5"
36
compileSdk = "34"
7+
lightcompressor = "1.3.2"
48
minSdk = "28"
59
targetSdk = "34"
610
jdkVersion = "17"
@@ -129,6 +133,7 @@ kotlinx-collections = { group = "org.jetbrains.kotlinx", name = "kotlinx-collect
129133

130134
# Testing Libraries
131135
junit = { group = "junit", name = "junit", version.ref = "junit" }
136+
lightcompressor = { module = "com.github.AbedElazizShe:LightCompressor", version.ref = "lightcompressor" }
132137
mockito = { group = "org.mockito", name = "mockito-core", version.ref = "mockito" }
133138
robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric"}
134139
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" }
@@ -205,6 +210,14 @@ firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashly
205210
firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics-ktx" }
206211
firebase-remoteConfig = { group = "com.google.firebase", name = "firebase-config-ktx" }
207212
firebase-database = { group = "com.google.firebase", name = "firebase-database-ktx" }
213+
accompanist-insets = { module = "com.google.accompanist:accompanist-insets", version.ref = "accompanistInsets" }
214+
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanistPermissions" }
215+
accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanistPermissions" }
216+
217+
# AWS
218+
aws-android-sdk-cognito = { module = "com.amazonaws:aws-android-sdk-cognito", version.ref = "awsAndroidSdkMobileClient" }
219+
aws-android-sdk-mobile-client = { module = "com.amazonaws:aws-android-sdk-mobile-client", version.ref = "awsAndroidSdkMobileClient" }
220+
aws-android-sdk-s3 = { module = "com.amazonaws:aws-android-sdk-s3", version.ref = "awsAndroidSdkMobileClient" }
208221

209222
# Timber
210223
timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" }
@@ -231,5 +244,6 @@ datastore = ["androidx-datastore-core", "androidx-datastore-preferences"]
231244
compose = ["ui", "ui-graphics", "ui-tooling-preview", "material3-compose", "coil-compose", "coil-video", "ui-foundation", "activity-compose", "lifecycle-compose", "navigation-compose", "hilt-navigation-compose"]
232245
compose-debug = ["ui-tooling", "ui-test-manifest"]
233246
media3 = ["androidx-media3-exoplayer", "androidx-media3-exoplayer-dash", "androidx-media3-ui" ]
234-
247+
accompanist = ["accompanist-insets", "accompanist-permissions", "accompanist-systemuicontroller"]
248+
aws = ["aws-android-sdk-s3", "aws-android-sdk-cognito", "aws-android-sdk-mobile-client"]
235249
orbit = ["orbit-core", "orbit-viewmodel", "orbit-compose"]

remote/video/src/main/java/com/record/video/api/BucketApi.kt

+6
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,10 @@ interface BucketApi {
1515
@Body requestBody: RequestBody,
1616
@Header("Content-Type") contentType: String = "application/octet-stream",
1717
): Response<ResponseBody>
18+
@PUT
19+
suspend fun uploadThumbnailWithS3Video(
20+
@Url url: String,
21+
@Body requestBody: RequestBody,
22+
@Header("Content-Type") contentType: String = "application/octet-stream",
23+
): Response<ResponseBody>
1824
}

remote/video/src/main/java/com/record/video/datasource/RemoteUploadDataSourceImpl.kt

+1-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ class RemoteUploadDataSourceImpl @Inject constructor(
3232
val mediaType = "application/octet-stream".toMediaTypeOrNull()
3333
val requestBody = RequestBody.create(mediaType, videoPath)
3434
val url = URL(bucketApi.uploadVideoWithS3Video(url, requestBody).raw().request.url.toString())
35-
Log.d("testUrl", "$url")
3635
return URL(url.protocol, url.host, url.port, url.path).toString()
3736
}
3837

@@ -42,8 +41,7 @@ class RemoteUploadDataSourceImpl @Inject constructor(
4241
getVideoFrameAt1Sec(videoPath, outputImagePath.absolutePath)
4342
val mediaType = "application/octet-stream".toMediaTypeOrNull()
4443
val requestBody = RequestBody.create(mediaType, outputImagePath)
45-
val url = URL(bucketApi.uploadVideoWithS3Video(url, requestBody).raw().request.url.toString())
46-
Log.d("testUrl2", "$url")
44+
val url = URL(bucketApi.uploadThumbnailWithS3Video(url, requestBody).raw().request.url.toString())
4745
return URL(url.protocol, url.host, url.port, url.path).toString()
4846
}
4947
}

0 commit comments

Comments
 (0)