Live Translation for Livestreams - Android
Live translation shows the hosts' speech as text, translated into each viewer's own language, while the livestream runs. Hosts and audience members use the same methods and events: the startTranslation(), stopTranslation() and changeTranslationLanguage() methods of the Room class, and the translation events of RoomEventListener.
The translation language is always a language code, such as "hi" for Hindi. Only the codes listed in Supported Languages return translated text.
How live translation works
- Each participant chooses the language they receive translated text in, with
translationLanguageincreateRoom(). Hosts also set the language they speak, withspeakingLanguage. - A host starts translation with
startTranslation(). One translation runs for the whole livestream. - Every participant, host or audience member, receives
onTranslationTextin their own language only. - While translation is running, a viewer can switch languages with
changeTranslationLanguage(), which affects only that viewer. stopTranslation()stops translation for everyone.
Step 1: Choose the languages
On the host's device, set the language the host speaks:
val liveStream = VideoSDK.createRoom(
roomId = liveStreamId,
token = token,
participantName = "Host",
mode = Mode.SEND_AND_RECV,
speakingLanguage = "en",
)
On a viewer's device, set the language the viewer wants to read:
val liveStream = VideoSDK.createRoom(
roomId = liveStreamId,
token = token,
participantName = "Viewer",
micEnabled = false,
camEnabled = false,
mode = Mode.RECV_ONLY,
translationLanguage = "hi",
)
A participant without a translationLanguage receives no translated text until they call changeTranslationLanguage().
Step 2: Start translation
Once the livestream is joined, the host starts translation:
lifecycleScope.launch {
try {
liveStream.startTranslation()
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Start translation failed: ${e.code} ${e.name}")
}
}
onTranslationStateChanged reports TranslationState.TRANSLATION_STARTING, then TranslationState.TRANSLATION_STARTED. A viewer who joins while translation is already running receives TRANSLATION_STARTED too, before its own onRoomJoined. Add your RoomEventListener before you call join(), or you miss it.
Step 3: Show the translated text
On every device, listen for onTranslationText. getType() is TranslationType.PARTIAL while the service is still revising a line, and TranslationType.FULL once the line is final. A new PARTIAL line replaces the previous one, so keep a line only when it is FULL.
private val liveStreamEventListener = object : RoomEventListener() {
override fun onTranslationStateChanged(state: TranslationState) {
Log.d("Translation", "Translation state: $state")
}
override fun onTranslationText(data: TranslationText) {
if (data.getType() == TranslationType.FULL) {
showCaption("${data.getParticipantName()}: ${data.getText()}")
}
}
}
Step 4: Let viewers change the language
While translation is running, a viewer can switch to another language. Only that viewer's language changes. Before translation has started, the server refuses the change and changeTranslationLanguage() throws VideoSDKException with 4044 (CHANGE_TRANSLATION_LANGUAGE_FAILED).
lifecycleScope.launch {
try {
liveStream.changeTranslationLanguage("fr")
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Language change failed: ${e.code} ${e.name}")
}
}
The new language applies once onTranslationLanguageChanged reports it for that viewer. Until then, onTranslationText keeps delivering the old language.
Step 5: Stop translation
A host stops translation for everyone:
lifecycleScope.launch {
try {
liveStream.stopTranslation()
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Stop translation failed: ${e.code} ${e.name}")
}
}
startTranslation(),stopTranslation()andchangeTranslationLanguage()aresuspendfunctions. Call them from a coroutine, such aslifecycleScope.launch, and catchVideoSDKException, which they throw when the request fails.changeTranslationLanguage()throws4044(CHANGE_TRANSLATION_LANGUAGE_FAILED) when the server refuses the change.- Called before the room is joined, or while it is reconnecting, they do nothing and report
3035(ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED) or3065(ERROR_ROOM_RECONNECTING) ononErrorinstead of throwing.
For how speakingLanguage and translationLanguage work together, see Speaking Language and Translation Language. To show the hosts' speech in the language they spoke, see Live Captioning.
API Reference
The API references for all the methods and events utilized in this guide are provided below.
Got a Question? Ask us on discord

