我实现了一个简单的调用者和侦听器脚本,其工作方式如下:
pj.AudioMediaPlayer
实例传输到 playback_media
)capture_media
路由到 playback_media
capture_media
路由到 pj.AudioMediaRecorder
,将循环的声音输出到 wav 文件中备注:
playback_media
获得为 pj.Endpoint.instance().audDevManager().getPlaybackDevmedia()
capture_media
获得为 pj.Endpoint.instance().audDevManager().getCaptureDevmedia()
整个设置的想法,用语言来说就是:呼叫者播放音频文件,听者将音频循环回呼叫者,呼叫者最终将循环的音频存储到音频文件中。我想要的只是一个简单的音频循环,不对原始声音进行任何增强或更改。
问题是来电者录制的音频质量很糟糕:音量整体降低,前几秒的音量甚至比其余部分更低,整个录音过程中有轻微的回声,似乎淡入淡出没有原因(回声消除?),衰减很快,导致大部分录音的音量都很低,几乎听不见,只有大约 4 个可听见的声音出现,但质量很差。
我发现官方 pjsip/pjsua2 文档对于除了最简单的示例之外的任何内容都毫无用处。我尝试禁用 VAD 并使脚本成为单线程和多线程,最后我尝试更改
EpConfig
的 MediaConfig.quality
变量,但这没有任何帮助。
问题是:我该如何确保原始音频按原样传输、环回和存储,而不改变录制音频的质量或特性?这是一个简单、简短的调用,仅循环一个 wav 文件,仅此而已。
我尝试通过 Python
EpConfig
界面更改一些可用的基本选项。
我尝试切换播放和捕获媒体设备。
我通过不使用默认媒体设备解决了音频质量问题。
相反,我将两端的
playback_device
和capture_device
替换为audio_device
,获得为
# Inside the onCallState() method of caller and listener
# which derive from pj.Call class...
ci = self.getInfo()
if ci.state == pj.PJSIP_INV_STATE_CONFIRMED:
for i in range(0, ci.media.size()):
if ci.media[i].type == pj.PJMEDIA_TYPE_AUDIO:
# Here we fetch the call's own audio media device...
# We use this object to directly manipulate the call's media,
# avoiding whatever nonsense the default media devices were doing, apparently...
self.audio_media = self.getAudioMedia(i)
# We insert the caller/listener device transmit code here...
现在,呼叫者可以
self.audio_media.startTransmit(self.recorder)
self.player.startTransmit(self.audio_media)
其中
self.recorder
是写入最终输出音频文件的 pj.AudioMediaRecorder
,self.player
是播放参考音频文件的 pj.AudioMediaPlayer
(该音频被发送给收听者,收听者将其循环回调用者)。
然后,听者可以
self.audio_media.startTransmit(self.audio_media)
将音频循环回给呼叫者。
无论“质量”设置或 VAD 如何,最终输出音频都不是完全完美的,但对于我的目的来说已经足够好了。录音开始时只有一点小故障,其余音量正常:
pjsip 系统似乎试图通过改变播放速度来减少呼叫延迟,并且过滤器会对传输的音频进行一些更改(+存在一些噪音),但同样,这些不会过多降低质量,并且我可以接受现在的运作方式。