Voice and video calls
gotd implements Telegram's tgcalls over WebRTC in
the calls package,
supporting both 1:1 calls and group voice chats. This is an advanced feature
that builds on the rest of the library — authenticate and handle updates first.
The examples transcode MP3 to Opus with ffmpeg and feed the resulting RTP packets
into the call. You need ffmpeg available, and you bring your own audio source. The
helper examples.StreamMP3(ctx, writePacket, path) encapsulates the transcoding.
1:1 calls
Create a call client, register it on your dispatcher so it sees signaling updates, then place a call to a user:
import "github.com/gotd/td/telegram/calls"
callClient := calls.NewClient(api, calls.Options{Logger: logzap.New(log)})
callClient.Register(dispatcher)
conn, err := callClient.Request(ctx, user) // user is a tg.InputUserClass
if err != nil {
return err
}
defer callClient.Discard(ctx, calls.DiscardHangup)
connected := make(chan struct{})
conn.OnConnected(func() { close(connected) })
<-connected
// Stream audio into the call's RTP track.
if err := examples.StreamMP3(ctx, conn.AudioTrack().WriteRTP, audioPath); err != nil {
return err
}
conn.AudioTrack() is a webrtc.TrackLocalStaticRTP you write packets to. This is the
call example.
Group voice chats
Join a supergroup or channel's voice chat with a GroupCall:
gc := calls.NewGroupCall(client.API(), calls.Options{Logger: logzap.New(log)})
gc.Register(dispatcher)
gc.OnParticipants(func(p []tg.GroupCallParticipant) {
log.Info("participants", zap.Int("count", len(p)))
})
joinAs := &tg.InputPeerUser{UserID: self.ID, AccessHash: self.AccessHash}
if err := gc.Join(ctx, call, joinAs); err != nil { // call is a *tg.InputGroupCall
return err
}
defer gc.Leave(ctx)
if err := examples.StreamMP3(ctx, gc.WriteAudio, audioPath); err != nil {
return err
}
gc.WriteAudio(pkt *rtp.Packet) feeds audio into the group call. This is the
groupcall example.
Caveats
- Calls require a user session (QR or code login), not a bot.
- You must obtain the
*tg.InputGroupCallfor a chat before joining (resolve the chat, then read its full info). - Video is supported by the underlying protocol, but the examples stream audio only.
- This is one of the more involved parts of the library — read the example sources in full before building on them.