Janus supports recordings of WebRTC sessions out of the box, assuming plugins take advantage of the feature. Specifically, recording as a functionality is implemented in the Janus core, specifically using the janus_recorder structure and the related methods. When enabled, media streams are recorded to a custom format (that we introduce below): as such, it's then up to individual plugins to expose ways for users to configure/start/stop recordings, and using the core functionality to actually implementing the recording part. At the time of writing, most plugins do implement it.
As anticipated, the janus_recorder core functionality saves media streams to a custom format that we call the "Meetecho Janus Recordings" format. When saved to file, the custom mjr
extension is used.
Each mjr
file contains a single media stream. This means that if if you want to record, for instance, an audio/video stream, you'll need two separate mjr
files: one just for audio, and the other just for video. Each mjr
file then basically just contains a structured dump of the RTP packets exactly as they arrived: after a short header that describes the data contained in the recording (i.e., type of media, the codec, when it was created, when the first packet was written), each RTP packet is saved together with info on its length. A partial timestamp of when the packet was received is also stored, as this allows for more realistic conversions to pcap
format when needed.
+-----------------------------------------------+ | MJR00002 (8 bytes) | +-----------------------------------------------+ | LEN (2 bytes) | JSON header (variable length) | +-----------------------------------------------+ | MEET (4 bytes) | Recvd Time (4 bytes) | +-----------------------------------------------+ | LEN (2 bytes) | RTP packet (variable length) | +-----------------------------------------------+ | MEET (4 bytes) | Recvd Time (4 bytes) | +-----------------------------------------------+ | LEN (2 bytes) | RTP packet (variable length) | +-----------------------------------------------+ | MEET (4 bytes) | Recvd Time (4 bytes) | +-----------------------------------------------+ | LEN (2 bytes) | RTP packet (variable length) | +-----------------------------------------------+ | ... | +-----------------------------------------------+
This makes the recording process very lightweight, as Janus doesn't need to do anything more that just saving the packets to file: no CPU intensive operation like transcoding or frame manipulation is done by the janus_recorder instances. RTP packets don't even need to be saved in order, as the mjr
files can be post-processed later and, as we'll see, re-ordering of the stored packets is part of the activities that our post-processor performs when doing so.
While we've so far only mentioned RTP packets, and so audio and video, Janus actually also natively supports the recording of datachannels. In that case, the recording will be a structured dump not of RTP packets, but of the individual messages that were received. Just as we said for audio and video, since mjr
files only cover individual streams, data recordings will need their own instance as well.
Once a recording is available in the mjr
format, it obviously needs some transformation before it can be consumed by external tools, e.g., media players or third-party applications for further processing (like muxing audio and video together, or mixing multiple video streams together).
Out of the box, Janus comes with a simple post-processing tool whose only job is re-ordering the available RTP packets, extracting the media frames from the RTP packets (which for video might mean extracting the same frame from multiple packets in sequence), and saving the media frames to a well-known media format. To make this simple, this tool can, for instance, convert an audio mjr
recording to an opus
file, or a video mjr
recording containing VP8 packets to a webm
file instead. Notice that no transcoding is done by this postprocessor either: frames are extracted exactly as they were sent originally, and just saved to a media container in a way that multimedia applications can consume them. If further processing is needed (e.g., muxing, mixing, transcoding, or other), then this is up to third-party applications that can work with existing media files.
For more information on the Janus recordings post-processor, check the documentation for the janus-pp-rec.c executable.