Realtime Transcription - Android
Realtime transcription turns the speech in a room into text while the room runs. This guide shows how to use the startTranscription() and stopTranscription() methods of the Room class.
You can also set up webhooks for realtime transcription.
Integrating Realtime Transcription Feature

The image above shows:
-
Start Transcription: The SDK Client initiates real-time transcription using the
startTranscriptionmethod. -
Resource Acquisition: The VideoSDK server prepares transcription for the room.
- If the request is denied,
startTranscription()throws aVideoSDKException. - If the request is successful, the server sends an
onTranscriptionStateChangedevent with the stateTranscriptionState.TRANSCRIPTION_STARTEDto the client, indicating that transcription has begun.
- If the request is denied,
-
Transcription Data: As transcription progresses, the client receives an
onTranscriptionTextevent with aTranscriptionText: the text, the speaker's ID and name, a timestamp and a type.getType()returns aTranscriptionType?:REALTIMEwhile the service may still revise a line,FULL_SENTENCEonce it has settled, ornullfor a type this SDK version does not know. Add a line to a transcript only when it isFULL_SENTENCE.getTimestamp()returns the service's timestamp for the line as aLong, or0when the service sent none.
-
Stop Transcription: The client stops transcription with
stopTranscription().- The server then sends an
onTranscriptionStateChangedevent with the stateTranscriptionState.TRANSCRIPTION_STOPPEDto confirm that transcription has ended.
- The server then sends an
Step 1: Configure Realtime Transcription
- In this step, we set up the configuration for realtime transcription.
TranscriptionConfigtakes three optional arguments:webhookURL, the URL where the webhooks will be received;summary, aSummaryConfigfor the AI summary; andmodelConfig, aJSONObjectof model settings. Each defaults tonull.
// Webhook URL where, webhooks are received
val webhookUrl = "YOUR_WEBHOOK_URL"
// Realtime Transcription Configuration
val summaryConfig = SummaryConfig(
true,
"Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
)
val transcription = TranscriptionConfig(
webhookURL = webhookUrl,
summary = summaryConfig
)
Step 2: Listen for the transcription events
- Add these callbacks to your
RoomEventListener. - Every participant receives the text of every speaker. The same text can arrive more than once as the service refines it.
private val roomEventListener: RoomEventListener = object : RoomEventListener() {
override fun onTranscriptionStateChanged(state: TranscriptionState) {
when (state) {
TranscriptionState.TRANSCRIPTION_STARTING -> Log.d("onTranscriptionStateChanged", "Realtime Transcription is starting")
TranscriptionState.TRANSCRIPTION_STARTED -> Log.d("onTranscriptionStateChanged", "Realtime Transcription is started")
TranscriptionState.TRANSCRIPTION_STOPPING -> Log.d("onTranscriptionStateChanged", "Realtime Transcription is stopping")
TranscriptionState.TRANSCRIPTION_STOPPED -> Log.d("onTranscriptionStateChanged", "Realtime Transcription is stopped")
}
}
override fun onTranscriptionText(data: TranscriptionText) {
// keep only settled lines: `REALTIME` lines are previews that a later line replaces
if (data.getType() != TranscriptionType.FULL_SENTENCE) return
val participantName: String = data.getParticipantName()
val text: String = data.getText()
val timestamp: Long = data.getTimestamp()
Log.d("onTranscriptionText", "$participantName: $text $timestamp")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
//...
// add listener to room
room!!.addEventListener(roomEventListener)
}
Step 3: Start realtime transcription
- Initiate the realtime transcription using the
startTranscription()method.
fun startRealtimeTranscription() {
// Webhook URL where, webhooks are received
val webhookUrl = "YOUR_WEBHOOK_URL"
// Realtime Transcription Configuration
val summaryConfig = SummaryConfig(
true,
"Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
)
val transcription = TranscriptionConfig(
webhookURL = webhookUrl,
summary = summaryConfig
)
lifecycleScope.launch {
try {
room!!.startTranscription(transcription)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Start transcription failed: ${e.code} ${e.name}")
}
}
}
startTranscription()andstopTranscription()aresuspendfunctions. Call them from a coroutine, such aslifecycleScope.launch(fromandroidx.lifecycle:lifecycle-runtime-ktx), and catchVideoSDKException, which they throw when the request fails.- They return before transcription has started or stopped. Wait for
onTranscriptionStateChangedto reportTRANSCRIPTION_STARTEDorTRANSCRIPTION_STOPPED. - 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.
Step 4: Stop realtime transcription
- Terminate the realtime transcription using the
stopTranscription()method.
fun stopRealtimeTranscription() {
lifecycleScope.launch {
try {
room!!.stopTranscription()
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Stop transcription failed: ${e.code} ${e.name}")
}
}
}
You can access a summary of your realtime transcription using the Fetch Realtime Transcription API.
Example
- The following code snippet allows you to start and stop realtime transcription with just a click. When you click the "Start Realtime Transcription" button, it begins realtime transcription. Clicking the "Stop Realtime Transcription" button ends the realtime transcription.
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import live.videosdk.rtc.android.Room
import live.videosdk.rtc.android.lib.VideoSDKException
import live.videosdk.rtc.android.lib.transcription.SummaryConfig
import live.videosdk.rtc.android.lib.transcription.TranscriptionConfig
import live.videosdk.rtc.android.lib.transcription.TranscriptionState
import live.videosdk.rtc.android.lib.transcription.TranscriptionText
import live.videosdk.rtc.android.lib.transcription.TranscriptionType
import live.videosdk.rtc.android.listeners.RoomEventListener
class RoomActivity : AppCompatActivity() {
private lateinit var room: Room
// add roomEventListener to handle transcription events
private val roomEventListener = object : RoomEventListener() {
override fun onTranscriptionStateChanged(state: TranscriptionState) {
Log.d("RoomActivity", "Transcription state: $state")
}
override fun onTranscriptionText(data: TranscriptionText) {
if (data.getType() != TranscriptionType.FULL_SENTENCE) return
val participantName = data.getParticipantName()
val text = data.getText()
val timestamp = data.getTimestamp()
Log.d("RoomActivity", "$participantName: $text $timestamp")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_room)
// create the room
//...
val startButton: Button = findViewById(R.id.startTranscriptionButton)
val stopButton: Button = findViewById(R.id.stopTranscriptionButton)
startButton.setOnClickListener { startRealtimeTranscription() }
stopButton.setOnClickListener { stopRealtimeTranscription() }
// add listener to room
room.addEventListener(roomEventListener)
}
private fun startRealtimeTranscription() {
// Configuration for realtime transcription
val summaryConfig = SummaryConfig(
true,
"Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
)
val transcriptionConfig = TranscriptionConfig(
summary = summaryConfig
)
// Call to start transcription with the specified configuration
lifecycleScope.launch {
try {
room.startTranscription(transcriptionConfig)
} catch (e: VideoSDKException) {
Log.e("RoomActivity", "Start transcription failed: ${e.code} ${e.name}")
}
}
}
private fun stopRealtimeTranscription() {
// Call to stop transcription
lifecycleScope.launch {
try {
room.stopTranscription()
} catch (e: VideoSDKException) {
Log.e("RoomActivity", "Stop transcription failed: ${e.code} ${e.name}")
}
}
}
}
Realtime Translation
To show the speech in the room translated into each participant's own language, see Realtime Translation.
API Reference
The API references for all the methods utilized in this guide are provided below.
Got a Question? Ask us on discord

