Skip to content

Commit

Permalink
Update rust sdk, add dtmf and attributes support (#239)
Browse files Browse the repository at this point in the history
* Update rust sdk and add dtmf support

* update rust-sdks pointer to main

* add enableQueue for AudioSource constructor

* add attributes support

* Add support for retrieving attributes

* reuse

* add changesets
  • Loading branch information
lukasIO committed Jul 18, 2024
1 parent a23c543 commit 3b40e58
Show file tree
Hide file tree
Showing 19 changed files with 1,187 additions and 322 deletions.
5 changes: 5 additions & 0 deletions .changeset/cold-parents-visit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@livekit/rtc-node': minor
---

Update rust-sdk dependency to latest
5 changes: 5 additions & 0 deletions .changeset/dry-lizards-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@livekit/rtc-node': patch
---

Add publishDtmf method on local participant
5 changes: 5 additions & 0 deletions .changeset/kind-cups-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@livekit/rtc-node': patch
---

Add support for setting and listening to participant attribute changes
5 changes: 5 additions & 0 deletions .changeset/neat-falcons-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@livekit/rtc-node': patch
---

Add enableQueue argument to AudioSource constructor
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ web_modules/
# Yarn Integrity file
.yarn-integrity

# macOS
.DS_Store

# dotenv environment variable files
.env
.env.development.local
Expand Down
2 changes: 1 addition & 1 deletion packages/livekit-rtc/rust-sdks
Submodule rust-sdks updated 75 files
+ .github/banner_dark.png
+ .github/banner_light.png
+4 −4 .github/workflows/builds.yml
+22 −8 .github/workflows/ffi-builds.yml
+1 −1 .github/workflows/tests.yml
+5 −5 .github/workflows/webrtc-builds.yml
+6 −6 Cargo.lock
+4 −3 README.md
+11 −11 download_ffi.py
+2 −3 libwebrtc/Cargo.toml
+13 −1 libwebrtc/src/audio_source.rs
+1 −1 libwebrtc/src/audio_stream.rs
+68 −171 libwebrtc/src/native/audio_source.rs
+1 −1 libwebrtc/src/native/audio_stream.rs
+2 −2 libwebrtc/src/native/peer_connection_factory.rs
+18 −0 libwebrtc/src/native/video_frame.rs
+2 −1 libwebrtc/src/native/video_source.rs
+1 −1 libwebrtc/src/native/video_stream.rs
+21 −0 libwebrtc/src/video_frame.rs
+1 −2 libwebrtc/src/video_stream.rs
+2 −2 livekit-api/Cargo.toml
+22 −0 livekit-api/src/access_token.rs
+18 −9 livekit-api/src/services/egress.rs
+12 −4 livekit-api/src/services/ingress.rs
+13 −5 livekit-api/src/services/mod.rs
+41 −43 livekit-api/src/services/room.rs
+421 −0 livekit-api/src/services/sip.rs
+16 −4 livekit-api/src/signal_client/signal_stream.rs
+3 −3 livekit-ffi/Cargo.toml
+1 −0 livekit-ffi/protocol/audio_frame.proto
+47 −38 livekit-ffi/protocol/ffi.proto
+1 −0 livekit-ffi/protocol/participant.proto
+116 −38 livekit-ffi/protocol/room.proto
+1 −0 livekit-ffi/src/conversion/participant.rs
+5 −1 livekit-ffi/src/conversion/room.rs
+247 −80 livekit-ffi/src/livekit.proto.rs
+1 −0 livekit-ffi/src/server/audio_source.rs
+62 −16 livekit-ffi/src/server/requests.rs
+329 −55 livekit-ffi/src/server/room.rs
+2 −2 livekit-protocol/Cargo.toml
+3 −2 livekit-protocol/generate_proto.sh
+1 −1 livekit-protocol/protocol
+1 −0 livekit-protocol/src/lib.rs
+1,158 −83 livekit-protocol/src/livekit.rs
+19,982 −11,058 livekit-protocol/src/livekit.serde.rs
+50 −0 livekit-protocol/src/promise.rs
+3 −2 livekit-runtime/Cargo.toml
+4 −3 livekit-runtime/src/async_std.rs
+1 −0 livekit-runtime/src/dispatcher.rs
+1 −0 livekit-runtime/src/tokio.rs
+4 −4 livekit/Cargo.toml
+1 −1 livekit/src/prelude.rs
+8 −0 livekit/src/room/e2ee/mod.rs
+1 −1 livekit/src/room/id.rs
+185 −109 livekit/src/room/mod.rs
+4 −1 livekit/src/room/options.rs
+106 −16 livekit/src/room/participant/local_participant.rs
+60 −7 livekit/src/room/participant/mod.rs
+36 −7 livekit/src/room/participant/remote_participant.rs
+8 −0 livekit/src/room/publication/local.rs
+35 −2 livekit/src/room/publication/remote.rs
+6 −2 livekit/src/room/track/local_audio_track.rs
+6 −2 livekit/src/room/track/local_video_track.rs
+6 −5 livekit/src/room/track/mod.rs
+6 −2 livekit/src/room/track/remote_audio_track.rs
+6 −2 livekit/src/room/track/remote_video_track.rs
+29 −9 livekit/src/rtc_engine/mod.rs
+1 −2 livekit/src/rtc_engine/rtc_events.rs
+46 −2 livekit/src/rtc_engine/rtc_session.rs
+34 −2 webrtc-sys/build.rs
+15 −0 webrtc-sys/include/livekit/video_frame_buffer.h
+1 −1 webrtc-sys/src/audio_device.cpp
+48 −0 webrtc-sys/src/objc_video_frame_buffer.mm
+16 −0 webrtc-sys/src/video_frame_buffer.cpp
+8 −0 webrtc-sys/src/video_frame_buffer.rs
3 changes: 2 additions & 1 deletion packages/livekit-rtc/src/audio_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ export class AudioSource {
sampleRate: number;
numChannels: number;

constructor(sampleRate: number, numChannels: number) {
constructor(sampleRate: number, numChannels: number, enableQueue?: boolean) {
this.sampleRate = sampleRate;
this.numChannels = numChannels;

const req = new NewAudioSourceRequest({
type: AudioSourceType.AUDIO_SOURCE_NATIVE,
sampleRate: sampleRate,
numChannels: numChannels,
enableQueue: enableQueue,
});

const res = FfiClient.instance.request<NewAudioSourceResponse>({
Expand Down
92 changes: 64 additions & 28 deletions packages/livekit-rtc/src/participant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,28 @@ import type { OwnedParticipant, ParticipantInfo } from './proto/participant_pb.j
import type {
PublishDataCallback,
PublishDataResponse,
PublishSipDtmfCallback,
PublishSipDtmfResponse,
PublishTrackCallback,
PublishTrackResponse,
SetLocalAttributesCallback,
SetLocalAttributesResponse,
SetLocalMetadataCallback,
SetLocalMetadataResponse,
SetLocalNameCallback,
SetLocalNameResponse,
TrackPublishOptions,
UnpublishTrackCallback,
UnpublishTrackResponse,
UpdateLocalMetadataCallback,
UpdateLocalMetadataResponse,
UpdateLocalNameCallback,
UpdateLocalNameResponse,
} from './proto/room_pb.js';
import {
DataPacketKind,
PublishDataRequest,
PublishSipDtmfRequest,
PublishTrackRequest,
SetLocalAttributesRequest,
SetLocalMetadataRequest,
SetLocalNameRequest,
UnpublishTrackRequest,
UpdateLocalMetadataRequest,
UpdateLocalNameRequest,
} from './proto/room_pb.js';
import type { LocalTrack } from './track.js';
import type { RemoteTrackPublication, TrackPublication } from './track_publication.js';
Expand Down Expand Up @@ -57,6 +62,10 @@ export abstract class Participant {
get metadata(): string {
return this.info.metadata;
}

get attributes(): Record<string, string> {
return this.info.attributes;
}
}

export type DataPublishOptions = {
Expand All @@ -68,9 +77,9 @@ export type DataPublishOptions = {
*/
reliable?: boolean;
/**
* the sids of participants who will receive the message, will be sent to every one if empty
* the identities of participants who will receive the message, will be sent to every one if empty
*/
destination?: string[] | RemoteParticipant[];
destination_identities?: string[];
/** the topic under which the message gets published */
topic?: string;
};
Expand All @@ -83,18 +92,11 @@ export class LocalParticipant extends Participant {
localParticipantHandle: this.ffi_handle.handle,
dataPtr: FfiClient.instance.retrievePtr(data),
dataLen: BigInt(data.byteLength),
kind: options.reliable ? DataPacketKind.KIND_RELIABLE : DataPacketKind.KIND_LOSSY,
reliable: options.reliable,
topic: options.topic,
destinationIdentities: options.destination_identities,
});

if (options.destination) {
const sids = options.destination.map((sid: string | RemoteParticipant) => {
if (typeof sid == 'string') return sid;
return sid.sid;
});
req.destinationSids = sids;
}

const res = FfiClient.instance.request<PublishDataResponse>({
message: { case: 'publishData', value: req },
});
Expand All @@ -108,33 +110,67 @@ export class LocalParticipant extends Participant {
}
}

async publishDtmf(code: number, digit: string) {
const req = new PublishSipDtmfRequest({
code,
digit,
});

const res = FfiClient.instance.request<PublishSipDtmfResponse>({
message: { case: 'publishSipDtmf', value: req },
});

const cb = await FfiClient.instance.waitFor<PublishSipDtmfCallback>((ev) => {
return ev.message.case == 'publishSipDtmf' && ev.message.value.asyncId == res.asyncId;
});

if (cb.error) {
throw new Error(cb.error);
}
}

async updateMetadata(metadata: string) {
const req = new UpdateLocalMetadataRequest({
const req = new SetLocalMetadataRequest({
localParticipantHandle: this.ffi_handle.handle,
metadata: metadata,
});

const res = FfiClient.instance.request<UpdateLocalMetadataResponse>({
message: { case: 'updateLocalMetadata', value: req },
const res = FfiClient.instance.request<SetLocalMetadataResponse>({
message: { case: 'setLocalMetadata', value: req },
});

await FfiClient.instance.waitFor<UpdateLocalMetadataCallback>((ev) => {
return ev.message.case == 'updateLocalMetadata' && ev.message.value.asyncId == res.asyncId;
await FfiClient.instance.waitFor<SetLocalMetadataCallback>((ev) => {
return ev.message.case == 'setLocalMetadata' && ev.message.value.asyncId == res.asyncId;
});
}

async updateName(name: string) {
const req = new UpdateLocalNameRequest({
const req = new SetLocalNameRequest({
localParticipantHandle: this.ffi_handle.handle,
name: name,
});

const res = FfiClient.instance.request<UpdateLocalNameResponse>({
message: { case: 'updateLocalName', value: req },
const res = FfiClient.instance.request<SetLocalNameResponse>({
message: { case: 'setLocalName', value: req },
});

await FfiClient.instance.waitFor<SetLocalNameCallback>((ev) => {
return ev.message.case == 'setLocalName' && ev.message.value.asyncId == res.asyncId;
});
}

async setAttributes(attributes: Record<string, string>) {
const req = new SetLocalAttributesRequest({
localParticipantHandle: this.ffi_handle.handle,
attributes: attributes,
});

const res = FfiClient.instance.request<SetLocalAttributesResponse>({
message: { case: 'setLocalAttributes', value: req },
});

await FfiClient.instance.waitFor<UpdateLocalNameCallback>((ev) => {
return ev.message.case == 'updateLocalName' && ev.message.value.asyncId == res.asyncId;
await FfiClient.instance.waitFor<SetLocalAttributesCallback>((ev) => {
return ev.message.case == 'setLocalAttributes' && ev.message.value.asyncId == res.asyncId;
});
}

Expand Down
8 changes: 7 additions & 1 deletion packages/livekit-rtc/src/proto/audio_frame_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// @generated by protoc-gen-es v1.7.2 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file audio_frame.proto (package livekit.proto, syntax proto3)
/* eslint-disable */
// @ts-nocheck
Expand Down Expand Up @@ -164,6 +164,11 @@ export class NewAudioSourceRequest extends Message<NewAudioSourceRequest> {
*/
numChannels = 0;

/**
* @generated from field: optional bool enable_queue = 5;
*/
enableQueue?: boolean;

constructor(data?: PartialMessage<NewAudioSourceRequest>) {
super();
proto3.util.initPartial(data, this);
Expand All @@ -176,6 +181,7 @@ export class NewAudioSourceRequest extends Message<NewAudioSourceRequest> {
{ no: 2, name: "options", kind: "message", T: AudioSourceOptions, opt: true },
{ no: 3, name: "sample_rate", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
{ no: 4, name: "num_channels", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
{ no: 5, name: "enable_queue", kind: "scalar", T: 8 /* ScalarType.BOOL */, opt: true },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): NewAudioSourceRequest {
Expand Down
2 changes: 1 addition & 1 deletion packages/livekit-rtc/src/proto/e2ee_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// @generated by protoc-gen-es v1.7.2 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file e2ee.proto (package livekit.proto, syntax proto3)
/* eslint-disable */
// @ts-nocheck
Expand Down
Loading

0 comments on commit 3b40e58

Please sign in to comment.