From a50154c1eddd1432b23624581b15686749ef3ed2 Mon Sep 17 00:00:00 2001 From: shinyoshiaki Date: Wed, 13 Dec 2023 16:00:42 +0900 Subject: [PATCH] fix serializeAudioLevelIndication --- package-lock.json | 4 +- packages/rtp/package.json | 2 +- packages/rtp/src/helper.ts | 2 +- packages/rtp/src/rtp/headerExtension.ts | 7 ++- packages/rtp/tests/rtp/packet.test.ts | 31 ++++++++++++- packages/webrtc/package.json | 2 +- .../tests/integrate/mediaChannel.test.ts | 44 +++++++++++++++++++ 7 files changed, 84 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d719b3693..e2b4b4ea1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8512,7 +8512,7 @@ }, "packages/rtp": { "name": "werift-rtp", - "version": "0.7.25", + "version": "0.7.26", "license": "MIT", "dependencies": { "@minhducsun2002/leb128": "^1.0.0", @@ -8624,7 +8624,7 @@ }, "packages/webrtc": { "name": "werift", - "version": "0.18.16", + "version": "0.18.17", "license": "MIT", "dependencies": { "@fidm/x509": "^1.2.1", diff --git a/packages/rtp/package.json b/packages/rtp/package.json index 29e7b9041..365db5811 100644 --- a/packages/rtp/package.json +++ b/packages/rtp/package.json @@ -1,6 +1,6 @@ { "name": "werift-rtp", - "version": "0.7.25", + "version": "0.7.26", "description": "RTP,RTCP,SRTP,SRTCP implementation for TypeScript.", "homepage": "https://github.com/shinyoshiaki/werift-webrtc", "repository": { diff --git a/packages/rtp/src/helper.ts b/packages/rtp/src/helper.ts index 090d7636d..031c9446b 100644 --- a/packages/rtp/src/helper.ts +++ b/packages/rtp/src/helper.ts @@ -23,7 +23,7 @@ export const timer = { args[0](); }, //@ts-ignore - ...args.slice(1) + ...args.slice(1), ); return () => clearInterval(id); }, diff --git a/packages/rtp/src/rtp/headerExtension.ts b/packages/rtp/src/rtp/headerExtension.ts index 28e8c579d..3f717e00f 100644 --- a/packages/rtp/src/rtp/headerExtension.ts +++ b/packages/rtp/src/rtp/headerExtension.ts @@ -24,6 +24,9 @@ export function rtpHeaderExtensionsParser( return extensions .map((extension) => { const uri = extIdUriMap[extension.id]; + if (!uri) { + return { uri: "unknown", value: extension.payload }; + } switch (uri) { case RTP_EXTENSION_URI.sdesMid: case RTP_EXTENSION_URI.sdesRTPStreamID: @@ -43,7 +46,7 @@ export function rtpHeaderExtensionsParser( }; } default: - return { uri, value: 0 }; + return { uri, value: extension.payload }; } }) .reduce((acc: { [uri: string]: any }, cur) => { @@ -78,7 +81,7 @@ export function serializeAbsSendTime(ntpTime: bigint) { export function serializeAudioLevelIndication(level: number) { const stream = new BitStream(Buffer.alloc(1)); stream.writeBits(1, 1); - stream.writeBits(level, 7); + stream.writeBits(7, level); return stream.uint8Array; } diff --git a/packages/rtp/tests/rtp/packet.test.ts b/packages/rtp/tests/rtp/packet.test.ts index e7ab63d05..18152caf3 100644 --- a/packages/rtp/tests/rtp/packet.test.ts +++ b/packages/rtp/tests/rtp/packet.test.ts @@ -1,4 +1,4 @@ -import { RtpPacket } from "../../src/rtp/rtp"; +import { ExtensionProfiles, RtpHeader, RtpPacket } from "../../src/rtp/rtp"; import { load } from "../utils"; describe("packet", () => { @@ -125,4 +125,33 @@ describe("packet", () => { const buf = p.serialize(); expect(buf).toEqual(data); }); + + test("serialize_deserialize", () => { + const packet = new RtpPacket( + new RtpHeader({ + csrc: [], + csrcLength: 0, + extension: true, + extensionProfile: ExtensionProfiles.OneByte, + extensions: [ + { id: 1, payload: Buffer.from([48]) }, + { id: 2, payload: Buffer.from([40, 1, 222]) }, + { id: 10, payload: Buffer.from([128]) }, + ], + marker: false, + padding: false, + paddingSize: 0, + payloadType: 109, + sequenceNumber: 15546, + ssrc: 2882400001, + timestamp: 144, + version: 2, + }), + Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + ); + const buf = packet.serialize(); + const parsed = RtpPacket.deSerialize(buf); + const buf2 = parsed.serialize(); + expect(buf2).toEqual(buf); + }); }); diff --git a/packages/webrtc/package.json b/packages/webrtc/package.json index 5b6d48c0b..05e41c627 100644 --- a/packages/webrtc/package.json +++ b/packages/webrtc/package.json @@ -1,6 +1,6 @@ { "name": "werift", - "version": "0.18.16", + "version": "0.18.17", "description": "WebRTC Implementation for TypeScript (Node.js)", "keywords": [ "WebRTC", diff --git a/packages/webrtc/tests/integrate/mediaChannel.test.ts b/packages/webrtc/tests/integrate/mediaChannel.test.ts index d080ea21d..495b833ca 100644 --- a/packages/webrtc/tests/integrate/mediaChannel.test.ts +++ b/packages/webrtc/tests/integrate/mediaChannel.test.ts @@ -1,9 +1,11 @@ import { + deserializeAudioLevelIndication, isMedia, MediaStreamTrack, RTCPeerConnection, RtpHeader, RtpPacket, + serializeAudioLevelIndication, useSdesMid, } from "../../src"; @@ -122,4 +124,46 @@ describe("media", () => { ); await pc1.setRemoteDescription(pc2.localDescription!); }); + + test("test_sendonly_recvonly_audioLevel", async () => + new Promise(async (done) => { + const sendonly = new RTCPeerConnection(); + const track = new MediaStreamTrack({ kind: "audio" }); + sendonly.addTransceiver(track, { direction: "sendonly" }); + sendonly.connectionStateChange + .watch((v) => v === "connected") + .then(() => { + const rtpPacket = new RtpPacket( + new RtpHeader({ + extensions: [ + { id: 10, payload: serializeAudioLevelIndication(25) }, + ], + }), + Buffer.from("test") + ).serialize(); + expect(isMedia(rtpPacket)).toBe(true); + track.writeRtp(rtpPacket); + }); + + const recvonly = new RTCPeerConnection(); + recvonly.onRemoteTransceiverAdded.subscribe((transceiver) => { + transceiver.onTrack.subscribe((track) => { + track.onReceiveRtp.subscribe(async (rtp) => { + expect(rtp.header.extensions[0].id).toBe(10); + expect( + deserializeAudioLevelIndication(rtp.header.extensions[0].payload) + .level + ).toEqual(25); + expect(rtp.payload).toEqual(Buffer.from("test")); + await Promise.all([sendonly.close(), recvonly.close()]); + done(); + }); + }); + }); + + await sendonly.setLocalDescription(await sendonly.createOffer()); + await recvonly.setRemoteDescription(sendonly.localDescription!); + await recvonly.setLocalDescription(await recvonly.createAnswer()); + await sendonly.setRemoteDescription(recvonly.localDescription!); + })); });