Hallo at all,
I'm trying to use LiveKit Client Worker to decode a video track coming from an iOS app, but if I connect two versions of Node.js, everything works fine.
But between iOS and Node.js.
Hoping not to violate any group policies, I'm trying to insert some code snippets. Can you tell me if this is the wrong approach?
nodejs:
this.cryptoWorker.postMessage({
kind: 'init',
data: {
keyProviderOptions: {
sharedKey: false,
ratchetWindowSize: 0,
failureTolerance: 0,
keyringSize: 1,
ratchetSalt: new Uint8Array(0),
discardFrameWhenCryptorNotReady: true
},
loglevel: 'trace',
},
});
const encoder = new TextEncoder();
const raw = encoder.encode(cipherKey.value);
const material = await crypto.subtle.importKey('raw', raw, 'HKDF', false, ['deriveKey']);
_this.cryptoWorker.postMessage({
kind: 'setKey',
data: {
key: raw, keyIndex: 0, isPublisher: publisher, participantIdentity: callsign
}
});
_this.cryptoWorker.postMessage({
kind: 'enable',
data: {
enabled: true, participantIdentity: callsign
}
});
whene I have the track:
this.cryptoWorker.postMessage({
kind: 'updateCodec',
data: {
participantIdentity: this.callsign || '',
trackId: receiver.track.id,
codec: (receiver.track.kind === "audio" ? this.audio_codec : this.video_codec)
}
});
const { readable, writable } = receiver.createEncodedStreams() ;
const kind = 'decode' ;
// debugger;
this.cryptoWorker.postMessage({
kind: kind,
data: {
participantIdentity: this.callsign || '',
trackId: receiver.track.id,
isReuse: false,
readableStream: readable,
writableStream: writable
},
}, [readable, writable]);
in swift:
private var peerConnection: LKRTCPeerConnection?
var audioCryptor: LKRTCFrameCryptor?
var videoCryptor: LKRTCFrameCryptor?
keyProvider = self.setupKeyProvider(
key: data,
partecipantId: self.callsign
)
private func hkdfSHA256(ikm: Data, salt: Data, info: Data = Data(), outLen: Int = 32) -> Data {
let inputKey = SymmetricKey(data: ikm)
let derived = HKDF
SHA256.deriveKey(
inputKeyMaterial: inputKey,
salt: Data(),
info: Data(),
outputByteCount: outLen
)
return derived.withUnsafeBytes { Data($0) }
}
private func setupKeyProvider(key: Data, partecipantId: String) -> LKRTCFrameCryptorKeyProvider {
let salt = Data() // non usato se window=0
let provider = LKRTCFrameCryptorKeyProvider(
ratchetSalt: salt,
ratchetWindowSize: 0,
sharedKeyMode: false,
uncryptedMagicBytes: Data(),
failureTolerance: 0,
keyRingSize: 1,
discardFrameWhenCryptorNotReady: true
)
let derivedKey = hkdfSHA256(ikm: key, salt: salt)
provider.setKey(derivedKey, with: 0, forParticipant: partecipantId)
return provider
}
if isVideoEnabled {
let localVideoTrack = try makeVideoTrack()
guard let sender = peerConnection!.add(localVideoTrack.track, streamIds: ["video0"]) else {
throw MapError.generic(message: "Error create local video track")
}
guard let cryptor = LKRTCFrameCryptor(
factory: factory,
rtpSender: sender,
participantId: callsign,
algorithm: .aesGcm,
keyProvider: keyProvider
) else {
throw MapError.generic(message: "Error create video frame cryptor")
}
videoCryptor = cryptor
videoCryptor?.enabled = true
videoCryptor?.delegate = self
self.localVideoTrack = localVideoTrack
try restartCapture(width: 640, height: 480, frameRate: 30)
}
the keys are identical on both sides
Thank you so much for any help you can give me
Gianmassimo