{"id":25422263,"url":"https://github.com/livekit/server-sdk-go","last_synced_at":"2025-05-15T03:03:08.958Z","repository":{"id":37746221,"uuid":"347283805","full_name":"livekit/server-sdk-go","owner":"livekit","description":"Client and server SDK for Golang","archived":false,"fork":false,"pushed_at":"2025-05-14T07:51:05.000Z","size":20609,"stargazers_count":249,"open_issues_count":36,"forks_count":117,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-05-14T08:40:10.318Z","etag":null,"topics":["go","livekit"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/livekit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-03-13T05:39:45.000Z","updated_at":"2025-05-14T07:50:52.000Z","dependencies_parsed_at":"2023-02-18T04:45:57.903Z","dependency_job_id":"29a901c1-368a-4c79-8bb4-5e208938f578","html_url":"https://github.com/livekit/server-sdk-go","commit_stats":null,"previous_names":["livekit/livekit-sdk-go"],"tags_count":98,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livekit%2Fserver-sdk-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livekit%2Fserver-sdk-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livekit%2Fserver-sdk-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livekit%2Fserver-sdk-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/livekit","download_url":"https://codeload.github.com/livekit/server-sdk-go/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254264737,"owners_count":22041791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","livekit"],"created_at":"2025-02-16T21:24:10.799Z","updated_at":"2025-05-15T03:03:08.950Z","avatar_url":"https://github.com/livekit.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--BEGIN_BANNER_IMAGE--\u003e\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"/.github/banner_dark.png\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"/.github/banner_light.png\"\u003e\n  \u003cimg style=\"width:100%;\" alt=\"The LiveKit icon, the name of the repository and some sample code in the background.\" src=\"https://raw.githubusercontent.com/livekit/server-sdk-go/main/.github/banner_light.png\"\u003e\n\u003c/picture\u003e\n\n\u003c!--END_BANNER_IMAGE--\u003e\n\n# LiveKit Go SDK\n\n\u003c!--BEGIN_DESCRIPTION--\u003e\nUse this SDK to interact with \u003ca href=\"https://livekit.io/\"\u003eLiveKit\u003c/a\u003e server APIs and create access tokens from your Go backend.\n\u003c!--END_DESCRIPTION--\u003e\n\n[!NOTE]\n\nVersion 2 of the \u003cplatform\u003e SDK contains a small set of breaking changes. Read the [migration guide](https://docs.livekit.io/guides/migrate-from-v1/) for a detailed overview of what has changed.\n\n## Installation\n\n```shell\ngo get github.com/livekit/server-sdk-go/v2\n```\n\nNote: since v1.0 release, this package requires Go 1.18+ in order to build.\n\n## Token creation\n\n```go\nimport (\n\t\"time\"\n\n\tlksdk \"github.com/livekit/server-sdk-go/v2\"\n\t\"github.com/livekit/protocol/auth\"\n)\n\nfunc getJoinToken(apiKey, apiSecret, room, identity string) (string, error) {\n\tat := auth.NewAccessToken(apiKey, apiSecret)\n\tgrant := \u0026auth.VideoGrant{\n\t\tRoomJoin: true,\n\t\tRoom:     room,\n\t}\n\tat.SetVideoGrant(grant).\n\t\tSetIdentity(identity).\n\t\tSetValidFor(time.Hour)\n\n\treturn at.ToJWT()\n}\n```\n\n## RoomService API\n\nRoomService gives you complete control over rooms and participants within them. It includes selective track subscriptions as well as moderation capabilities.\n\n```go\nimport (\n\tlksdk \"github.com/livekit/server-sdk-go/v2\"\n\tlivekit \"github.com/livekit/protocol/livekit\"\n)\n\nfunc main() {\n\thostURL := \"host-url\"  // ex: https://project-123456.livekit.cloud\n\tapiKey := \"api-key\"\n\tapiSecret := \"api-secret\"\n\n\troomName := \"myroom\"\n\tidentity := \"participantIdentity\"\n\n    roomClient := lksdk.NewRoomServiceClient(hostURL, apiKey, apiSecret)\n\n    // create a new room\n    room, _ := roomClient.CreateRoom(context.Background(), \u0026livekit.CreateRoomRequest{\n\t\tName: roomName,\n\t})\n\n    // list rooms\n    res, _ := roomClient.ListRooms(context.Background(), \u0026livekit.ListRoomsRequest{})\n\n    // terminate a room and cause participants to leave\n    roomClient.DeleteRoom(context.Background(), \u0026livekit.DeleteRoomRequest{\n\t\tRoom: roomId,\n\t})\n\n    // list participants in a room\n    res, _ := roomClient.ListParticipants(context.Background(), \u0026livekit.ListParticipantsRequest{\n\t\tRoom: roomName,\n\t})\n\n    // disconnect a participant from room\n    roomClient.RemoveParticipant(context.Background(), \u0026livekit.RoomParticipantIdentity{\n\t\tRoom:     roomName,\n\t\tIdentity: identity,\n\t})\n\n    // mute/unmute participant's tracks\n    roomClient.MutePublishedTrack(context.Background(), \u0026livekit.MuteRoomTrackRequest{\n\t\tRoom:     roomName,\n\t\tIdentity: identity,\n\t\tTrackSid: \"track_sid\",\n\t\tMuted:    true,\n\t})\n}\n```\n\n## Interacting as a participant\n\nThe Real-time SDK gives you access programmatic access as a client enabling you to publish and record audio/video/data to the room.\n\n```go\nimport (\n  lksdk \"github.com/livekit/server-sdk-go/v2\"\n)\n\nfunc main() {\n  hostURL := \"host-url\"  // ex: https://project-123456.livekit.cloud\n  apiKey := \"api-key\"\n  apiSecret := \"api-secret\"\n  roomName := \"myroom\"\n  identity := \"botuser\"\n  roomCB := \u0026lksdk.RoomCallback{\n\tParticipantCallback: lksdk.ParticipantCallback{\n\t  OnTrackSubscribed: trackSubscribed,\n  \t},\n  }\n  room, err := lksdk.ConnectToRoom(hostURL, lksdk.ConnectInfo{\n  \tAPIKey:              apiKey,\n  \tAPISecret:           apiSecret,\n  \tRoomName:            roomName,\n  \tParticipantIdentity: identity,\n  }, roomCB)\n  if err != nil {\n  \tpanic(err)\n  }\n\n  ...\n  room.Disconnect()\n}\n\nfunc trackSubscribed(track *webrtc.TrackRemote, publication *lksdk.RemoteTrackPublication, rp *lksdk.RemoteParticipant) {\n\n}\n```\n\nFor more advanced usage, see the [examples](https://github.com/livekit/server-sdk-go/tree/main/examples) directory.\n\n## Publishing tracks to Room\n\nWith the Go SDK, you can publish existing files encoded in H.264, VP8, and Opus to the room.\n\nFirst, you will need to encode media into the right format.\n\n### VP8 / Opus\n\n```bash\nffmpeg -i \u003cinput.mp4\u003e \\\n  -c:v libvpx -keyint_min 120 -qmax 50 -maxrate 2M -b:v 1M \u003coutput.ivf\u003e \\\n  -c:a libopus -page_duration 20000 -vn \u003coutput.ogg\u003e\n```\n\nThe above encodes VP8 at average 1Mbps / max 2Mbps with a minimum keyframe interval of 120.\n\n### H.264 / Opus\n\n```bash\nffmpeg -i \u003cinput.mp4\u003e \\\n  -c:v libx264 -bsf:v h264_mp4toannexb -b:v 2M -profile baseline -pix_fmt yuv420p \\\n    -x264-params keyint=120 -max_delay 0 -bf 0 \u003coutput.h264\u003e \\\n  -c:a libopus -page_duration 20000 -vn \u003coutput.ogg\u003e\n```\n\nThe above encodes H264 with CBS of 2Mbps with a minimum keyframe interval of 120.\n\n### Publish from file\n\n```go\nfile := \"video.ivf\"\nvideoWidth := 1920\nvideoHeight := 1080\ntrack, err := lksdk.NewLocalFileTrack(file,\n\t// control FPS to ensure synchronization\n\tlksdk.ReaderTrackWithFrameDuration(33 * time.Millisecond),\n\tlksdk.ReaderTrackWithOnWriteComplete(func() { fmt.Println(\"track finished\") }),\n)\nif err != nil {\n    return err\n}\nif _, err = room.LocalParticipant.PublishTrack(track, \u0026lksdk.TrackPublicationOptions{\n\tName: file,\n\tVideoWidth: videoWidth,\n\tVideoHeight: videoHeight,\n}); err != nil {\n    return err\n}\n```\n\n### Publish from io.ReadCloser implementation\n\n```go\n// - `in` implements io.ReadCloser, such as buffer or file\n// - `mime` has to be one of webrtc.MimeType...\ntrack, err := lksdk.NewLocalReaderTrack(in, mime,\n\tlksdk.ReaderTrackWithFrameDuration(33 * time.Millisecond),\n\tlksdk.ReaderTrackWithOnWriteComplete(func() { fmt.Println(\"track finished\") }),\n)\nif err != nil {\n\treturn err\n}\nif _, err = room.LocalParticipant.PublishTrack(track, \u0026lksdk.TrackPublicationOptions{}); err != nil {\n    return err\n}\n```\n\nFor a full working example, refer to [filesender](https://github.com/livekit/server-sdk-go/blob/main/examples/filesender/main.go). This\nexample sends all audio/video files in the current directory.\n\n### Publishing audio from PCM16 Samples\n\nIn order to publish audio from PCM16 Samples, you can use the NewPCMLocalTrack API as follows:\n\n```go\nimport (\n\t...\n\tlkmedia \"github.com/livekit/server-sdk-go/v2/pkg/media\"\n)\n\n...\n\npublishTrack, err := lkmedia.NewPCMLocalTrack(sourceSampleRate, sourceChannels, logger.GetLogger())\nif err != nil {\n\treturn err\n}\n\nif _, err = room.LocalParticipant.PublishTrack(publishTrack, \u0026lksdk.TrackPublicationOptions{\n\tName: \"test\",\n}); err != nil {\n\treturn err\n}\n```\n\nYou can then write PCM16 samples to the `publishTrack` like:\n\n```go\nerr = publishTrack.WriteSample(sample)\nif err != nil {\n\tlogger.Errorw(\"error writing sample\", err)\n}\n```\n\nThe SDK will encode the sample to Opus and write it to the track. If the sourceSampleRate is not 48000, resampling is also handled internally.\n\nThe API also provides an option to write silence to the track when no data is available, this is disabled by default but you can enable it using:\n\n```go\npublishTrack, err := lkmedia.NewPCMLocalTrack(sourceSampleRate, sourceChannels, logger.GetLogger(), lkmedia.WithWriteSilenceOnNoData(true))\n```\n\nTo close the track, you can call `Close()` on the `publishTrack`, this will stop accepting samples, write the existing buffer and then close the track. If you wish to clear the buffer manually, use the `ClearQeuue()` on the track. There's also a `WaitForPlayout()` API if you want to wait for existing buffer to be written before writing something to the track.\n\n**Note**: Stereo audio is currently not supported, it may result in unpleasant audio.\n\n### Publish from other sources\n\nIn order to publish from non-file sources, you will have to implement your own `SampleProvider`, that could provide frames of data with a `NextSample` method.\n\nThe SDK takes care of sending the samples to the room.\n\n### Using a pacer\n\nWith video publishing, keyframes can be an order of magnitude larger than delta frames.\nThis size difference can cause a significant increase in bitrate when a keyframe is transmitted, leading to a surge in packet flow.\nSuch spikes might result in packet loss at the forwarding layer. To maintain a consistent packet flow,\nyou can enable the use of a [pacer](https://chromium.googlesource.com/external/webrtc/+/master/modules/pacing/g3doc/index.md).\n\n```go\nimport \"github.com/livekit/mediatransportutil/pkg/pacer\"\n\n// Control total output bitrate to 10Mbps with 1s max latency\npf := pacer.NewPacerFactory(\n\tpacer.LeakyBucketPacer,\n\tpacer.WithBitrate(10000000),\n\tpacer.WithMaxLatency(time.Second),\n)\n\nroom, err := lksdk.ConnectToRoom(hostURL, lksdk.ConnectInfo{\n    APIKey:              apiKey,\n    APISecret:           apiSecret,\n    RoomName:            roomName,\n    ParticipantIdentity: identity,\n}, \u0026lksdk.RoomCallback{\n    ParticipantCallback: lksdk.ParticipantCallback{\n        OnTrackSubscribed: onTrackSubscribed,\n    },\n}, lksdk.WithPacer(pf))\n```\n\n## Receiving tracks from Room\n\nWith the Go SDK, you can accept media from the room.\n\nFor a full working example, refer to [filesaver](https://github.com/livekit/server-sdk-go/blob/main/examples/filesaver/main.go). This\nexample saves the audio/video in the LiveKit room to the local disk.\n\n### Decoding an Opus track to PCM16\n\nTo get PCM audio out of a remote Opus audio track, you can use the following API:\n\n```go\nimport (\n\t...\n\tmedia \"github.com/livekit/media-sdk\"\n\tlkmedia \"github.com/livekit/server-sdk-go/v2/pkg/media\"\n)\n\ntype PCM16Writer struct {\n\tclosed atomic.Bool\n}\n\nfunc (w *PCM16Writer) WriteSample(sample media.PCM16Sample) error {\n\tif !w.closed.Load() {\n\t\t// Use the sample however you want\n\t}\n}\n\nfunc (w *PCM16Writer) Close() error {\n\tw.closed.Store(true)\n\t// close the writer\n}\n\n...\n\nwriter := \u0026PCM16Writer{}\npcmTrack, err := lkmedia.NewPCMRemoteTrack(remoteTrack, writer)\nif err != nil {\n\treturn err\n}\n```\n\nThe SDK will then read the provided remote track, decode the audio and write the PCM16 samples to the provided writer. By defeault, it pushes out 48kHz mono audio. The output sample rate and channels can also be configured by passsing as an option:\n\n```go\npcmTrack, err := lkmedia.NewPCMRemoteTrack(remoteTrack, writer, lkmedia.WithTargetSampleRate(24000), lkmedia.WithTargetChannels(2))\n```\n\nResampling to the target sample rate is handled internally, and so is upmixing/downmixing to the target channel count.\n\nThe API also provides an option to handle jitter, this is enabled by default but you can disable it using:\n\n```go\npcmTrack, err := lkmedia.NewPCMRemoteTrack(remoteTrack, writer, lkmedia.WithHandleJitter(false))\n```\n\n## Receiving webhooks\n\nThe Go SDK helps you to verify and decode webhook callbacks to ensure their authenticity.\nSee [webhooks guide](https://docs.livekit.io/guides/webhooks) for configuration.\n\n```go\nimport (\n\t\"github.com/livekit/protocol/auth\"\n\t\"github.com/livekit/protocol/livekit\"\n\t\"github.com/livekit/protocol/webhook\"\n)\n\nvar authProvider = auth.NewSimpleKeyProvider(\n\tapiKey, apiSecret,\n)\n\nfunc ServeHTTP(w http.ResponseWriter, r *http.Request) {\n  // event is a livekit.WebhookEvent{} object\n\tevent, err := webhook.ReceiveWebhookEvent(r, authProvider)\n\tif err != nil {\n\t\t// could not validate, handle error\n\t\treturn\n\t}\n\n\t// consume WebhookEvent\n}\n```\n\n\u003c!--BEGIN_REPO_NAV--\u003e\n\u003cbr/\u003e\u003ctable\u003e\n\u003cthead\u003e\u003ctr\u003e\u003cth colspan=\"2\"\u003eLiveKit Ecosystem\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003eLiveKit SDKs\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/client-sdk-js\"\u003eBrowser\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-swift\"\u003eiOS/macOS/visionOS\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-android\"\u003eAndroid\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-flutter\"\u003eFlutter\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-react-native\"\u003eReact Native\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/rust-sdks\"\u003eRust\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/node-sdks\"\u003eNode.js\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/python-sdks\"\u003ePython\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-unity\"\u003eUnity\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-unity-web\"\u003eUnity (WebGL)\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eServer APIs\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/node-sdks\"\u003eNode.js\u003c/a\u003e · \u003cb\u003eGolang\u003c/b\u003e · \u003ca href=\"https://github.com/livekit/server-sdk-ruby\"\u003eRuby\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/server-sdk-kotlin\"\u003eJava/Kotlin\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/python-sdks\"\u003ePython\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/rust-sdks\"\u003eRust\u003c/a\u003e · \u003ca href=\"https://github.com/agence104/livekit-server-sdk-php\"\u003ePHP (community)\u003c/a\u003e · \u003ca href=\"https://github.com/pabloFuente/livekit-server-sdk-dotnet\"\u003e.NET (community)\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eUI Components\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/components-js\"\u003eReact\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/components-android\"\u003eAndroid Compose\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/components-swift\"\u003eSwiftUI\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eAgents Frameworks\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/agents\"\u003ePython\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/agents-js\"\u003eNode.js\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/agent-playground\"\u003ePlayground\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eServices\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/livekit\"\u003eLiveKit server\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/egress\"\u003eEgress\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/ingress\"\u003eIngress\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/sip\"\u003eSIP\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eResources\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://docs.livekit.io\"\u003eDocs\u003c/a\u003e · \u003ca href=\"https://github.com/livekit-examples\"\u003eExample apps\u003c/a\u003e · \u003ca href=\"https://livekit.io/cloud\"\u003eCloud\u003c/a\u003e · \u003ca href=\"https://docs.livekit.io/home/self-hosting/deployment\"\u003eSelf-hosting\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/livekit-cli\"\u003eCLI\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c!--END_REPO_NAV--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flivekit%2Fserver-sdk-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flivekit%2Fserver-sdk-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flivekit%2Fserver-sdk-go/lists"}