Rubylight Download 2.2.10

Microphone #

Documentation · Configuration · Features

A streaming device can send its microphone to the PC. Games and chat apps on the PC hear it as Microphone (Steam Streaming Microphone), a recording device Steam provides. Rubylight speaks the format of Apollo's microphone passthrough (Apollo pull request #1428, client side in ClassicOldSong/moonlight-common-c), so a client built for it works with Rubylight unchanged.

On the PC #

For client developers #

The microphone is a separate UDP stream from the client to the host. Nothing goes back to the client; the video and audio streams are unchanged.

Negotiation #

  1. DESCRIBE. A host that takes a microphone adds these lines, and adds 8 (microphone encryption) to x-ss-general.encryptionSupported and x-ss-general.encryptionRequested:

    m=audio 48001 RTP/AVP 96
    a=rtpmap:96 opus/48000/1
    a=fmtp:96 minptime=10;useinbandfec=1
    

    The a=rtpmap:96 opus/48000/1 line is the signal. Without it, do not set the microphone up.

  2. SETUP streamid=mic/0/0 (streamid=mic for a host older than app version 5), after the audio, video and control streams and before ANNOUNCE. The Transport: server_port= header gives the port.

  3. ANNOUNCE with bit 8 set in x-ss-general.encryptionEnabled. Rubylight, like Apollo, never takes a microphone in the clear: without the bit, the microphone is off for that session and the stream card says why. Everything else in the stream goes on.

  4. PLAY. A client that plays each stream separately may send PLAY streamid=mic; a client that sends one PLAY for the session needs nothing more.

Packets #

One datagram per Opus packet, from any local port to the host's microphone port:

Bytes Field Value
0 flags 0
1 type 0x61 (Opus)
2–3 sequence little-endian, +1 per packet, wraps at 65535
4–7 timestamp little-endian, the client's clock in milliseconds (logs only)
8–11 magic 0x12345678, little-endian (78 56 34 12)
12– payload the encrypted Opus packet

The payload is AES-128-CBC with the launch's rikey as the key. The IV is 16 bytes: the big-endian 32-bit sum of the launch's rikeyid and the packet's sequence number, then 12 zero bytes (the same IV scheme as the host's audio packets). Pad the Opus packet with PKCS#7 before encrypting. moonlight-common-c pads twice, first to a whole block and then a full PKCS#7 block from OpenSSL; the host accepts both that and a single layer, such as Java's AES/CBC/PKCS5Padding. Keep a datagram within 1400 bytes.

The host matches a packet to its session by the client's IP address and the key that decrypts it.

Audio #

Android #

Testing #

rust/windows/examples/mic_probe.rs runs the host half on a real PC: it sends tone bursts through the same packet, decryption, decoding and playback code and records them back from Microphone (Steam Streaming Microphone), reporting the delay from a packet's arrival to the recording app and any dropouts. The RTSP exchange and packet routing have an automated test (host/src/stream/reconnect_tests.rs::microphone_packets_reach_only_the_session_that_set_them_up).

View this page on GitHub