Live Captioning for Livestreams - Android
Live captioning enhances your livestreams by converting hosts' speech into text in real-time, boosting accessibility and engagement. Using the startTranscription()
and stopTranscription()
methods, you can enable or disable captions on the fly, and display captions dynamically in your UI for all viewers.
Video SDK offers flexible configuration and event-driven updates to help you integrate captions seamlessly into your broadcast layout.
startTranscription()
​
The startTranscription()
method, accesible from the Meeting
class, is used to initiate live captions in a live stream.
stopTranscription()
​
The stopTranscription()
method, accesible from the Meeting
class, is used to stop the live captions in a live stream.
Example​
- Kotlin
- Java
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import live.videosdk.rtc.android.Meeting
import live.videosdk.rtc.android.VideoSDK
import live.videosdk.rtc.android.meeting.SummaryConfig
import live.videosdk.rtc.android.meeting.TranscriptionConfig
class LiveStreamActivity : AppCompatActivity() {
private lateinit var liveStream: Meeting
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_stream)
// Initialize the meeting (replace with actual meeting ID and token)
liveStream = VideoSDK.initMeeting(... )
val startCaptionsButton: Button = findViewById(R.id.btn_start_captions)
val stopCaptionsButton: Button = findViewById(R.id.btn_stop_captions)
startCaptionsButton.setOnClickListener {
startRealtimeTranscription()
}
stopCaptionsButton.setOnClickListener {
stopRealtimeTranscription()
}
}
private fun startRealtimeTranscription() {
val webhookUrl = "https://www.example.com"
val summaryConfig = SummaryConfig(
true,
"Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
)
val transcriptionConfig = TranscriptionConfig(
webhookUrl,
summaryConfig
)
liveStream.startTranscription(transcriptionConfig)
}
private fun stopRealtimeTranscription() {
liveStream.stopTranscription()
}
}
public class LiveStreamActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_stream);
// Initialize the meeting
Meeting liveStream = VideoSDK.initMeeting( ...);
Button startCaptionsButton = findViewById(R.id.btn_start_captions);
Button stopCaptionsButton = findViewById(R.id.btn_stop_captions);
startCaptionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startRealtimeTranscription();
}
});
stopCaptionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopRealtimeTranscription();
}
});
}
private void startRealtimeTranscription() {
String webhookUrl = "https://www.example.com";
SummaryConfig summaryConfig = new SummaryConfig(
true,
"Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
);
TranscriptionConfig transcriptionConfig = new TranscriptionConfig(
webhookUrl,
summaryConfig
);
liveStream.startTranscription(transcriptionConfig);
}
private void stopRealtimeTranscription() {
liveStream.stopTranscription();
}
}
Events associated with live captioning​
- All participants-including all the hosts and audience members will receive a callback on the
onTranscriptionStateChanged
event with the current state of the captioning. - All participants-including all the hosts and audience members will receive a callback on the
onTranscriptionText
event with the latest captions whenever a host speaks.
- Kotlin
- Java
private val meetingEventListener: MeetingEventListener = object : MeetingEventListener() {
override fun onTranscriptionStateChanged(data: JSONObject) {
try {
val status = data.getString("status")
val id = data.getString("id")
when (status) {
TranscriptionState.TRANSCRIPTION_STARTING.name -> Log.d("onTranscriptionStateChanged", "Realtime Transcription is starting, ID: $id")
TranscriptionState.TRANSCRIPTION_STARTED.name -> Log.d("onTranscriptionStateChanged", "Realtime Transcription is started, ID: $id")
TranscriptionState.TRANSCRIPTION_STOPPING.name -> Log.d("onTranscriptionStateChanged", "Realtime Transcription is stopping, ID: $id")
TranscriptionState.TRANSCRIPTION_STOPPED.name -> Log.d("onTranscriptionStateChanged", "Realtime Transcription is stopped, ID: $id")
else -> Log.d("onTranscriptionStateChanged", "Unknown transcription state: $status, ID: $id")
}
} catch (e: JSONException) {
Log.e("onTranscriptionStateChanged", "Error parsing transcription state", e)
}
}
override fun onTranscriptionText(data: TranscriptionText) {
val participantId: String = data.participantId
val participantName: String = data.participantName
val text: String = data.text
val timestamp: Int = data.timestamp
val type: String = data.type
Log.d("onTranscriptionText", "$participantName: $text $timestamp")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
//...
// add listener to meeting
liveStream!!.addEventListener(meetingEventListener)
}
private final MeetingEventListener meetingEventListener = new MeetingEventListener() {
@Override
public void onTranscriptionStateChanged(JSONObject data) {
try {
String status = data.getString("status");
String id = data.getString("id");
if (TranscriptionState.TRANSCRIPTION_STARTING.name().equals(status)) {
Log.d("onTranscriptionStateChanged", "Realtime Transcription is starting, ID: " + id);
}
else if (TranscriptionState.TRANSCRIPTION_STARTED.name().equals(status)) {
Log.d("onTranscriptionStateChanged", "Realtime Transcription is started, ID: " + id);
}
else if (TranscriptionState.TRANSCRIPTION_STOPPING.name().equals(status)) {
Log.d("onTranscriptionStateChanged", "Realtime Transcription is stopping, ID: " + id);
}
else if (TranscriptionState.TRANSCRIPTION_STOPPED.name().equals(status)) {
Log.d("onTranscriptionStateChanged", "Realtime Transcription is stopped, ID: " + id);
}
else {
Log.d("onTranscriptionStateChanged", "Unknown transcription state: " + status + ", ID: " + id);
}
} catch (JSONException e) {
Log.e("onTranscriptionStateChanged", "Error parsing transcription state", e.getMessage());
}
}
@Override
public void onTranscriptionText(TranscriptionText data) {
String participantId = data.getParticipantId();
String participantName = data.getParticipantName();
String text = data.getText();
int timestamp = data.getTimestamp();
String type = data.getType();
Log.d("onTranscriptionText", participantName + ": " + text + " " + timestamp);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
// add listener to meeting
liveStream.addEventListener(meetingEventListener);
}
API Reference​
The API references for all the methods utilized in this guide are provided below.
Got a Question? Ask us on discord