Extract AMR, AMR-WB, and EVS audio from RTP pcaps and convert it to playable WAV files.
pcap-parser reads pcap/pcapng captures containing SIP signaling and RTP media, identifies audio flows by SSRC and payload type, and writes each flow in the RFC 4867 storage format. It can also decode to WAV with ffmpeg, export one pcap per flow, and mix all flows into a single multichannel WAV aligned by packet capture time — just like Wireshark's RTP player.
Author: Mansoor Khan
Version: 1.1.0
License: MIT
- Features
- Requirements
- Installation
- Quick Start
- Usage Examples
- Command-Line Options
- Output File Naming
- How It Works
- WAV Output Notes
- Troubleshooting
- Supported Codecs and Frame Sizes
- Changelog
- Contributing
- License
- Extracts AMR-NB, AMR-WB, and EVS RTP payloads.
- Supports RFC 4867 bandwidth-efficient framing and Iu framing.
- Handles pcaps with mixed SIP + RTP traffic.
- Parses SDP from SIP messages to auto-detect codec / payload-type mapping.
- Single-flow mode (
-o): extracts the busiest matching RTP flow to one file. - Multi-flow mode (default): extracts every matching RTP flow into a unique timestamped folder.
- Per-flow filenames include SSRC, codec, source IP:port → destination IP:port.
- Optional WAV conversion (
--wav) usingffmpeg. - Configurable WAV sample rate (
-ar/--sample-rate, default 16 kHz). - Clean WAV headers (no metadata chunks) and a soft peak limiter to avoid hard digital clipping.
- Per-flow audio-level check; silent or near-silent flows are flagged.
- Preserves silent / DTX periods by inserting silence frames for RTP timestamp gaps and replacing SID frames with decodable silence so
ffmpegdoes not drop them. - Optional per-flow RTP pcap export (
--pcaps) for Wireshark analysis. - Optional multichannel mix (
--mix) combining all flow WAVs into one file with one channel per flow, aligned by pcap capture time (Wireshark RTP-player style). Use--no-align-timeto start all channels at 0. - Optional per-endpoint direction mixes (
--direction-mix): for every RTP socket (IP:port) the script creates incoming, outgoing and stereo WAVs (left = incoming, right = outgoing). - Automatic per-folder README report in multi-flow mode with SIP call summary, A/B party direction labels, per-endpoint mixes, Mermaid + ASCII diagrams, and a listening guide.
- Python 3.7+
- Python packages:
scapybitarray
ffmpeg(optional but strongly recommended for WAV output)
- Clone the repository:
git clone https://github.com/goolanceman/pcap-parser.git
cd pcap-parser- Install Python dependencies:
pip install scapy bitarray- Install
ffmpeg:
# macOS
brew install ffmpeg
# Ubuntu / Debian
sudo apt-get install ffmpeg
# Windows (via chocolatey)
choco install ffmpegpython3 pcap_parser.py -i capture.pcapThis runs in multi-flow mode: every matching RTP flow is extracted into a folder named capture_extracted_YYYYMMDD_HHMMSS.
python3 pcap_parser.py -i capture.pcap --wavpython3 pcap_parser.py -i capture.pcap -c amr-wb --wavpython3 pcap_parser.py -i capture.pcap -c amr-wb -o out.3ga --wavpython3 pcap_parser.py -i capture.pcap -c amr --wav -ar 8000python3 pcap_parser.py -i capture.pcap --pcapspython3 pcap_parser.py -i capture.pcap -c amr --mixThe mixed file is aligned by pcap capture time by default. To start every channel at time 0:
python3 pcap_parser.py -i capture.pcap -c amr --mix --no-align-timepython3 pcap_parser.py -i capture.pcap --wav --direction-mixThis creates, for every RTP socket seen in the capture:
ipport_<ip>_<port>_incoming.wav— all RTP streams received on that socketipport_<ip>_<port>_outgoing.wav— all RTP streams sent from that socketipport_<ip>_<port>_stereo.wav— stereo: left = incoming, right = outgoing
python3 pcap_parser.py -i capture.pcap -c amr --wav --pcaps --mix --direction-mix -ar 16000This produces:
- Per-flow
.amrraw codec files - Per-flow
.amr.wavaudio files - Per-flow
.pcapfiles for Wireshark mixed_all_flows.wavwith one channel per flowipport_<ip>_<port>_{incoming,outgoing,stereo}.wavfor every RTP socketREADME.mdwith SIP/RTP analysis and diagrams
| Option | Description |
|---|---|
-i <pcap> |
Input pcap/pcapng file (required) |
-c <codec> |
Codec: amr, amr-wb, evs, or guess (default: guess) |
-f <framing> |
Framing: ietf or iu (default: ietf) |
-o <file> |
Single output file (extracts busiest flow only) |
-d <dir> |
Output directory for multi-flow mode |
--wav |
Convert each output to WAV using ffmpeg |
-ar <rate> / --sample-rate <rate> |
WAV sample rate in Hz (default: 16000) |
--pcaps |
Write one .pcap per RTP flow |
--mix |
Create one multichannel WAV mixing all flow WAVs |
--no-align-time |
With --mix, start all channels at time 0 instead of aligning by pcap capture time |
--direction-mix |
Create per-IP:port incoming/outgoing/stereo WAV mixes |
-h |
Show help |
In multi-flow mode, each file is named like:
ssrc0x2174370c_amr_198.51.100.10:13414_to_192.0.2.20:22466.amr
ssrc0x2174370c_amr_198.51.100.10:13414_to_192.0.2.20:22466.amr.wav
ssrc0x2174370c_amr_198.51.100.10:13414_to_192.0.2.20:22466.pcap
The name contains:
ssrc0x...— RTP SSRC identifieramr/amr-wb/evs— detected codec<src_ip>:<src_port>_to_<dst_ip>:<dst_port>— packet direction.amr/.awb/.evs— raw codec file.wav— WAV version (if--wavwas used).pcap— per-flow RTP pcap (if--pcapswas used)
When --direction-mix is used you also get:
ipport_<ip>_<port>_incoming.wavipport_<ip>_<port>_outgoing.wavipport_<ip>_<port>_stereo.wav
- Reads the pcap with
scapy. - Parses every UDP payload:
- SIP/SDP payloads are scanned to build a payload-type → codec map.
- RTP payloads are parsed (version 2 only), handling CSRC lists, RTP extensions, and padding.
- Groups RTP packets by
(SSRC, payload type). - Filters flows by codec (explicit or guessed) and ignores tiny / spurious flows.
- Deduplicates packets by RTP sequence number and sorts them.
- Preserves silent / DTX intervals by inserting silence frames for RTP timestamp gaps and replacing SID frames with silence (some
ffmpegbuilds drop SID / NO_DATA frames). - Writes each flow in RFC 4867 storage format.
- If
--wavis set, runsffmpegto convert to WAV at the requested sample rate. - If
--pcapsis set, writes the original packets for each flow to a separate.pcapfile. - If
--mixis set, combines all flow WAVs into a single multichannel WAV aligned by pcap capture time, unless--no-align-timeis used. - If
--direction-mixis set, creates incoming / outgoing / stereo mixes for every RTP socket (IP:port). - Reports the RMS / peak level for each WAV and flags flows that are silent or extremely quiet.
- Writes a per-folder
README.mdwith SIP call summary, A/B direction labels, per-endpoint mixes, diagrams, and listening instructions.
WAV files are output at the sample rate chosen with -ar / --sample-rate (default 16 kHz), as 16-bit, mono PCM.
- 16 kHz is the default because it is the native rate of AMR-WB and is widely supported.
- AMR is natively 8 kHz. Use
-ar 8000for the original decoded sample rate. - AMR-WB is natively 16 kHz.
- EVS can be decoded at various rates; 16 kHz is the default.
A soft peak limiter is applied during conversion to prevent the hard digital clipping that some AMR-NB decodes produce.
The pcap contains no UDP traffic that looks like RTP version 2. Verify with Wireshark or tshark that RTP is present.
Specify the codec explicitly:
python3 pcap_parser.py -i capture.pcap -c amr-wbMake sure you are opening the .wav file, not the raw .amr / .awb / .evs file.
If a track is silent, check the extraction summary. Flows marked [SILENT] or below about -60 dBFS contain no usable audio in that direction. Try the opposite direction from the same call.
Flows with fewer than 10 unique RTP packets are ignored as spurious. Edit MIN_FRAMES in pcap_parser.py if you need shorter flows.
Install ffmpeg and ensure it is in your PATH. WAV conversion is skipped if ffmpeg is missing.
| Mode | Speech bits | Typical RTP payload bytes |
|---|---|---|
| 0 | 95 | 14 |
| 1 | 103 | 15 |
| 2 | 118 | 16 |
| 3 | 134 | 18 |
| 4 | 148 | 20 |
| 5 | 159 | 22 |
| 6 | 204 | 27 |
| 7 | 244 | 32 |
| SID | 39 | 7 |
| Mode | Speech bits | Typical RTP payload bytes |
|---|---|---|
| 0 | 132 | 18 |
| 1 | 177 | 24 |
| 2 | 253 | 33 |
| 3 | 285 | 37 |
| 4 | 317 | 41 |
| 5 | 365 | 47 |
| 6 | 397 | 51 |
| 7 | 461 | 59 |
| 8 | 477 | 61 |
| SID | 40 | 7 |
Compact payload format only (3GPP TS 26.445 Annex A.2). Supported payload sizes (bytes):
6, 7, 17, 18, 20, 23, 24, 32, 33, 36, 40, 41, 46, 50, 58, 60, 61, 80, 120, 160, 240, 320
See CHANGELOG.md.
Contributions, bug reports, and feature requests are welcome. Please open an issue or pull request on GitHub.
MIT License — see LICENSE for details.