라이브룸 V2V 번역 자막 기능을 추가한다

라이브룸에서 진행자 언어와 기기 언어가 다를 때 자막 토글을 제공한다.
룸 정보 응답에 V2V 워커 토큰과 진행자 언어 코드를 포함한다.
Agora V2V 에이전트 참여와 종료 API 연동을 추가한다.
This commit is contained in:
2026-02-09 00:13:21 +09:00
parent 1dcf16ba2a
commit 8c7602bb1a
12 changed files with 593 additions and 2 deletions

View File

@@ -3,6 +3,8 @@ package kr.co.vividnext.sodalive.di
import android.content.Context
import com.google.gson.GsonBuilder
import kr.co.vividnext.sodalive.BuildConfig
import kr.co.vividnext.sodalive.agora.v2v.V2vApi
import kr.co.vividnext.sodalive.agora.v2v.V2vRepository
import kr.co.vividnext.sodalive.audio_content.AudioContentApi
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
import kr.co.vividnext.sodalive.audio_content.AudioContentViewModel
@@ -176,6 +178,7 @@ import okhttp3.logging.HttpLoggingInterceptor
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.context.startKoin
import org.koin.core.qualifier.named
import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
@@ -184,6 +187,7 @@ import java.util.concurrent.TimeUnit
class AppDI(private val context: Context, isDebugMode: Boolean) {
private val baseUrl = BuildConfig.BASE_URL
private val agoraBaseUrl = "https://api.agora.io/api/speech-to-speech-translation/v2/"
private val otherModule = module {
single { GsonBuilder().create() }
@@ -211,6 +215,23 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
.build()
}
single<OkHttpClient>(named("agoraHttpClient")) {
val logging = HttpLoggingInterceptor()
if (isDebugMode) {
logging.setLevel(HttpLoggingInterceptor.Level.BODY)
} else {
logging.setLevel(HttpLoggingInterceptor.Level.NONE)
}
OkHttpClient().newBuilder()
.addInterceptor(logging)
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build()
}
single { AcceptLanguageInterceptor(get()) }
single {
@@ -222,6 +243,15 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
.build()
}
single<Retrofit>(named("agoraRetrofit")) {
Retrofit.Builder()
.baseUrl(agoraBaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.client(get<OkHttpClient>(named("agoraHttpClient")))
.build()
}
single { ApiBuilder().build(get(), AlarmListApi::class.java) }
single { ApiBuilder().build(get(), CanApi::class.java) }
single { ApiBuilder().build(get(), CanTempApi::class.java) }
@@ -255,6 +285,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
single { ApiBuilder().build(get(), TalkApi::class.java) }
single { ApiBuilder().build(get(), CharacterCommentApi::class.java) }
single { ApiBuilder().build(get(), OriginalWorkApi::class.java) }
single { ApiBuilder().build(get<Retrofit>(named("agoraRetrofit")), V2vApi::class.java) }
}
private val viewModelModule = module {
@@ -273,7 +304,16 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
viewModel { LiveRoomCreateViewModel(get()) }
viewModel { LiveTagViewModel(get()) }
viewModel { LiveRoomEditViewModel(get()) }
viewModel { LiveRoomViewModel(get(), get(), get(), get(), get()) }
viewModel {
LiveRoomViewModel(
repository = get(),
userRepository = get(),
reportRepository = get(),
rouletteRepository = get(),
userEventRepository = get(),
v2vRepository = get()
)
}
viewModel { LiveRoomDonationMessageViewModel(get()) }
viewModel { ExplorerViewModel(get()) }
viewModel { UserProfileViewModel(get(), get(), get()) }
@@ -353,6 +393,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
factory { TermsRepository(get()) }
factory { SeriesRepository(get()) }
factory { LiveRepository(get(), get(), get()) }
factory { V2vRepository(get()) }
factory { EventRepository(get()) }
factory { LiveRecommendRepository(get()) }
factory { AuthRepository(get()) }