我需要将.rtp文件(使用RTP代理记录)转换为.wav文件。 如果有人知道如何做,请给我你的解决方案。
提前致谢:)
答案 0 :(得分:1)
或许有点晚了,但我最近遇到了同样的问题,并且如果其他人有这个问题我认为我应该在这里分享我的解决方案。我还使用RTP代理捕获音频流,这些音频流保存为两个.rtp文件,每个频道一个,其中.o。是发起呼叫(呼叫者)和.a的呼叫的输出。是接听电话的人(被叫者)。
解决方案1。 RTP代理有一个内置模块,可以为你进行wav转换,称为" extractaudio"。文档缺乏说明,但您可以从命令行使用它,如下所示:
extractaudio -F wav -B /path/to/rtp /path/of/outfile.wav
这会将一个RTP文件一次转换为WAV文件。该模块使用GSM编码编码创建的WAV文件。如果这是不希望的,您可以将-D pcm_16
作为额外参数传递给它,以将编码切换为线性PCM 16,这是保持音频质量的更好格式。我通过python以子进程的方式以编程方式提取WAV文件,以便进行命令行调用。
解决方案2。 您可以直接提取原始RTP数据,并使用第三方软件(如SoX或FFmpeg将其转换为WAV文件。此解决方案需要SoX,FFmpeg和tshark作为依赖项。如果您自己打开RTP文件并提取UDP数据,则可以不使用tshark,但可以使用tshark轻松完成。
这是我的代码(Python 2.7.9):
import os
import subprocess
import shlex
import binascii
FILENAME = "my_file"
WORKING_DIR = os.path.dirname(os.path.realpath(__file__))
IN_FILE_O = "%s/%s.o.rtp" % (WORKING_DIR, FILENAME)
IN_FILE_A = "%s/%s.a.rtp" % (WORKING_DIR, FILENAME)
conversion_list = {"PCMU" : "sox -t ul -r 8000 -c 1 %s %s",
"GSM" : "sox -t gsm -r 8000 -c 1 %s %s" ,
"PCMA" : "sox -t al -r 8000 -c 1 %s %s",
"G722" : "ffmpeg -f g722 -i %s -acodec pcm_s16le -ar 16000 -ac 1 %s",
"G729": "ffmpeg -f g729 -i %s -acodec pcm_s16le -ar 8000 -ac 1 %s"
}
if __name__ == "__main__":
args_o = "tshark -n -r " + IN_FILE_O + " -T fields -e data"
args_a = "tshark -n -r " + IN_FILE_A + " -T fields -e data"
f_o = WORKING_DIR + "/" + "payload_o.g722"
f_a = WORKING_DIR + "/" + "payload_a.g722"
payload_o = subprocess.Popen(shlex.split(args_o), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()[0]
payload_a = subprocess.Popen(shlex.split(args_a), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()[0]
if os.path.exists(f_o):
os.remove(f_o)
if os.path.exists(f_a):
os.remove(f_a)
with open(f_o, "ab") as new_codec:
payload = payload_o.split("\n")
for line in payload:
line = line.rstrip()
tmp = "%s.o: " % FILENAME
for index, (op, code) in enumerate(zip(line[0::2], line[1::2])):
if index > 11:
new_codec.write(binascii.unhexlify(op + code))
with open(f_a, "ab") as new_codec:
payload = payload_a.split("\n")
for line in payload:
line = line.rstrip()
tmp = "%s.a: " % FILENAME
for index, (op, code) in enumerate(zip(line[0::2], line[1::2])):
if index > 11:
new_codec.write(binascii.unhexlify(op + code))
owav = WORKING_DIR + "/" + "%s.o.wav" % FILENAME
awav = WORKING_DIR + "/" + "%s.a.wav" % FILENAME
if os.path.exists(owav):
os.remove(owav)
if os.path.exists(awav):
os.remove(awav)
print("Creating %s with %s" % (owav, f_o))
print("Creating %s with %s" % (awav, f_a))
subprocess.Popen(shlex.split(conversion_list["G722"] % (f_o, owav)), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()[0]
subprocess.Popen(shlex.split(conversion_list["G722"] % (f_a, awav)), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()[0]
我在我的解决方案中将G722硬编码为输入数据但是它应该适用于任何类型的输入编码,因为你有正确的SoX / FFmpeg命令。我在预定义的词典中添加了一些不同的编码。此解决方案的缺点是您必须知道RTP文件中记录的呼叫的编码。我试图在RTP文件中找到PCAP文件中找到的rtp.p_type
的等效参数,这个参数需要使用编解码器,但没有任何运气。我对RTP文件不太熟悉,但它可能存在于某个地方的数据中。这样做的另一个缺点是所产生的音频文件有时可能比原始音频短。我假设这是由Silence Suppression引起的,在这种情况下,可以通过在时间戳表示静音被删除(未传输)的地方插入静音来修复它。
查看有关RTP文件的信息的一种好方法是通过tshark-command:
tshark -n -r /path/to/file.rtp
希望它会帮助别人!
编辑: 我发现了另一个关于detecting the encoding within a RTP file的问题。