A few years ago I wrote a small program to transform a pcap into a wav file - the codec in use was SILK.
These days I'm dealing with Opus, and I have to say things are greatly simplified, in particular if you consider opus-tools, a set of utilities to handle opus files and traces.
One of those tools, opusrtp, can do live captures and write the interpreted payload into a .opus file.
Still, what I needed was to achieve the same result but from a pcap already existing, i.e. "offline".
So I come up with a small - quite shamlessly copy&pasted - patch to opusrtc, which is now in this fork.
Once you have a pcap with an RTP stream with opus (say in input.pcap) you can retrieve the .opus equivalent (in rtpdump.opus) with:
./opusrtp --extract input.pcap
Then you can generate an audible wav file with:
./opusdec --rate 8000 rtpdump.opus output.wav
Happy decoding.
Thanks Giacomo
ReplyDeleteI found this tool very useful!
In order to get it to work for me I had to make a couple of fixes. I was using a Linux cooked capture pcap file so I did not have the standard length ethernet packet header in the PCAP file. I worked around this by setting
#define ETH_HEADER_LEN 20
#define ETH_FILE_HEADER_LEN 20
in opusrtp.c
OPUS has a dynamically allocated payload type so the payload type can be between 96-127. Your code had a hard-coded value for the Opus payload type so I had to change this to get the decoding to work for me. To workaround this I just set
#define OPUS_PAYLOAD_TYPE 117
#define OPUS_FILE_PAYLOAD_TYPE 117
Thanks for your comment, and I'm glad you found that work useful.
ReplyDeleteThere are indeed a couple of hardcoded values, which possibly can be either managed as input arguments for the binary, or extracted somehow from the original pcap in a more dynamic fashion.
Hi Giacomo,
ReplyDeletethank you for your post, I'm using it. I just add an input argument to set the payload type. I use the binary in a bash script in conjunction with tshark. Tshark allows me to inspect the pcap file, extracting rtp infos from sdp messages if SIP signaling is present in pcap, and filtering opus packets before pass to opusrtp.
Thanks a lot!
Good to hear it. Happy decoding ;)
ReplyDeleteAny improvement you may want to suggest, please feel free to raise a Pull Request.
Thanks Giacomo for sharing this
ReplyDeleteI m facing problems in running opusrtp
When i ran the below command as you suggested
./opusrtp --extract input.pcap
I got the below error
Timestamp: 1466490413:383288
eth 0x0800 00:07:7d:67:e1:bf -> 54:ee:75:65:3b:6a
unhandled ip version 0
error parsing ip header
Got 127 byte packet (127 bytes captured)
Though i am using ip version 4, it is displaying as version 0
Thank you
DeleteHi praveen,
ReplyDeleteplease take into account that I've just hardcoded the payload type:
#define OPUS_FILE_PAYLOAD_TYPE 96
and header lenght:
#define ETH_FILE_HEADER_LEN 16
You should in particular check the payload type. It would be great to make it dynamic or pass it as command argument.
Hello!
ReplyDeleteThank you for your code.
Please help me to understand where is the problem?
root@ip-10-23-254-74:/home/ubuntu# ./opusrtp --extract opus.pcap
.....
Got 120 byte packet (120 bytes captured)
skipping packet: unrecognized linktype 12
Got 146 byte packet (146 bytes captured)
skipping packet: unrecognized linktype 12
...
BR
Denys
I think this could be due to multiple streams in the packet capture, filter only one stream and then run with opusrto and hope it works , let me know if it works
DeleteThanks
Praveen
Hi Denys, please upload your opus.pcap somewhere and let me know when I can download it. So I can take a look.
ReplyDeleteCheers,
Giacomo
Hey!
ReplyDeleteI have uploaded file to Google:
https://drive.google.com/file/d/0B33gE9ddn6_4a0ltTVpRdG82S0U/view?usp=sharing
This trace was from rtpengine:
https://github.com/sipwise/rtpengine
But as I see now eth header is empty, maybe that is the reason.
Thank you for the help!
BR,
Denys
Hi Giacomo,
ReplyDeleteI'm not yet able to test the script. I'm having some issues compiling the code ( https://github.com/gcp/opus-tools ) on Ubuntu Linux.
I was wondering if you could provide me a quick step to follow to do the compilation, I usually get away with make install, but it's not working this time.
Thanks
Hi Giacomo,
ReplyDeleteI'm not yet able to test the script. I'm having issues while trying to compile the script (https://github.com/gcp/opus-tools )
I usually get away with "make install" but it's not working this time. I was wondering if you could provide a quick info I can follow to compile the script.
Thanks
Hi, thanks for your comment. I've never used that repo; instead I was referring to https://github.com/xiph/opus-tools
ReplyDeleteIn general though, I'd expect you to:
./autogen.sh
./configure --with-opus-includes=/usr/local/include/opus --without-flac
make
You don't even need 'make install' as long as you identify the location of opusrtp and opusdec binaries. Also please note that you need opus-dev installed.
Good luck.
Hi Giacomo,
ReplyDeleteWhen I run the command:
./opusrtp --extract input.pcap
pcap support disabled, sorry.
Could you help me?
BR,
MartÃn.
I also encountered this problem, then I found the line 199 in configure.ac, which indicates "AC_DEFINE([HAVE_PCAP], 1, [Define if building with libpcap support])", so I installed the "libpcap" and solved the problem. I hope this solution will help anyone who encountered the same problem.
DeleteThanks Giacomo,
ReplyDeletewhen I proceed as you suggested I get a rtpdump.opus of only 111bytes. Obviously opusrtp is skipping the packets.
Wireshark suggests : payload type G.711 PCMU
Anything needs to be adapted in the source code?
Thx for help
Got 105 byte packet (105 bytes captured)
eth 0x0800 01:00:5e:05:06:08 -> b8:27:eb:74:bb:8c
ipv4 protocol 17 192.168.2.254 -> 234.5.6.8 header 20 bytes
udp 71 bytes 54840 -> 8000 crc 0xcfc4
rtp 0x0cf157d0 0 43406 2062153920 v2 ... CC 0 51 bytes
skipping non-opus packet
Hi, to keep it simple I've hardcoded the payload type as 120, see:
Deletehttps://github.com/giavac/opus-tools/blob/master/src/opusrtp.c#L59
#define OPUS_PAYLOAD_TYPE 120
Check what's used in the actual negotiation (maybe it's 96 instead?). If it's different, change it, re-compile and try again.
Ah yes, thank you.
DeleteI just read it in the original blog:
https://www.giacomovacca.com/2017/01/analysing-opus-media-from-network-traces.html