From b6cac2d133c975e16a66f88afa093f564ae66441 Mon Sep 17 00:00:00 2001 From: DavidVentura Date: Sat, 27 Jan 2024 16:24:35 +0100 Subject: [PATCH] add audio support --- README.md | 4 ++-- handlers.ts | 10 ++++++++-- server.ts | 11 ++++++++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0989a3a..72879cc 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ The hooks used with frida are at `frida-hooks.js`, but it's mostly a playground There's also a pretty crappy Wireshark dissector at `dissector.lua`. You can install it with `make install-wireshark-dissector`. ## Running -To execute the server, run `make run`; JPEG files will be created in a folder named `captures`. +To execute the server, run `make run`; JPEG files and `audio.pcm` will be created in a folder named `captures`. There's no live-stream server built into this project yet. @@ -73,7 +73,7 @@ To start a stream, a single _control packet_ is sent. The received stream is broken up into 1028 byte payloads, along with a sequence number. -Stitching the payloads together yields JPEG frames for video, and (TBD) for audio. +Stitching the payloads together yields JPEG frames for video, and 8KHz A-law PCM for audio. ```mermaid --- diff --git a/handlers.ts b/handlers.ts index 92130e4..9e5c5fb 100644 --- a/handlers.ts +++ b/handlers.ts @@ -1,6 +1,7 @@ import { Commands, CommandsByValue, ControlCommands } from "./datatypes.js"; import { create_P2pRdy, SendStartVideo, SendUsrChk } from "./impl.js"; import { Session } from "./server.js"; +import { u16_swap } from "./utils.js"; let curImage = null; @@ -66,12 +67,17 @@ const deal_with_data = (session: Session, dv: DataView) => { } if (audio) { - // TODO audio pkt + // "stream_head_t->type == 0x06" per pdf + if (dv.add(12).readU8() == 0x06) { + const audio_len = u16_swap(dv.add(8 + 16).readU16()); + const audio_buf = dv.add(32 + 8).readByteArray(audio_len).buffer; // 8 for pkt header, 32 for `stream_head_t` + session.eventEmitter.emit("audio", Buffer.from(audio_buf)); + } } else { const data = dv.add(8).readByteArray(pkt_len - 4); if (is_new_image) { if (curImage != null) { - session.frameEmitter.emit("frame", curImage); + session.eventEmitter.emit("frame", curImage); } curImage = Buffer.from(data.buffer); } else { diff --git a/server.ts b/server.ts index fc2371a..448b562 100644 --- a/server.ts +++ b/server.ts @@ -11,7 +11,7 @@ export type Session = { broadcast: (msg: DataView) => void; outgoingCommandId: number; ticket: number[]; - frameEmitter: EventEmitter; + eventEmitter: EventEmitter; }; export type PacketHandler = (session: Session, dv: DataView) => void; @@ -50,7 +50,7 @@ const makeSession = (cb: msgCb, connCb: connCb, options?: opt): Session => { const session: Session = { outgoingCommandId: 0, ticket: [0, 0, 0, 0], - frameEmitter: new EventEmitter(), + eventEmitter: new EventEmitter(), send: (msg: DataView) => { const raw = msg.readU16(); const cmd = CommandsByValue[raw]; @@ -117,7 +117,8 @@ const s = makeSession( ); let cur_image_index = 0; -s.frameEmitter.on("frame", (frame: Buffer) => { +const audioFd = createWriteStream(`captures/audio.pcm`); +s.eventEmitter.on("frame", (frame: Buffer) => { const fname = `captures/${cur_image_index.toString().padStart(4, "0")}.jpg`; let cur_image = createWriteStream(fname); cur_image_index++; @@ -125,3 +126,7 @@ s.frameEmitter.on("frame", (frame: Buffer) => { cur_image.close(); console.log("got an entire frame", frame.length); }); + +s.eventEmitter.on("audio", (frame: Buffer) => { + audioFd.write(frame); +});