gpt4 book ai didi

converter - 如何将 .rtp 文件(使用 RTP 代理编解码器 G711 录制)转换为 .wav 文件

转载 作者:行者123 更新时间:2023-12-02 03:31:32 50 4
gpt4 key购买 nike

我需要将一个 .rtp 文件(已使用 RTP 代理录制)转换为 .wav 文件。如果有人知道如何做到这一点,请给我您的解决方案。

提前致谢:)

最佳答案

聚会可能有点晚了,但我最近遇到了同样的问题,我认为如果其他人有这个问题,我应该在这里分享我的解决方案。我还使用 RTP-proxy 来捕获保存为两个 .rtp 文件的音频流,每个 channel 一个,其中 .o。是发起调用者(调用者)和 .a 的输出。是接听电话的人(被叫者)。

解决方案 1。RTP-proxy 有一个内置模块,可以为您进行 wav 转换,称为“extractaudio”。至少可以说缺少文档,但您可以从命令行使用它,如下所示:

extractaudio -F wav -B /path/to/rtp /path/of/outfile.wav

这将一次将一个 RTP 文件转换为 WAV 文件。模块 encode 使用 GSM 编码创建 WAV 文件。如果不需要,您可以将 -D pcm_16 作为额外参数传递给它,以将编码切换为 Linear PCM 16,这是保持音频质量的更好格式。我使用子进程的方式通过 python 以编程方式提取 WAV 文件,以便进行命令行调用。

解决方案 2。您可以直接提取原始 RTP 数据并使用第 3 部分软件(如 SoX)将其转换为 WAV 文件。或 FFmpeg .此解决方案需要 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 命令:

tshark -n -r /path/to/file.rtp 

希望对大家有所帮助!

编辑:我发现了另一个关于 detecting the encoding within a RTP file 的问题.

关于converter - 如何将 .rtp 文件(使用 RTP 代理编解码器 G711 录制)转换为 .wav 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26397727/

50 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com