PJSUA2 - 将通话音频录制到 wav 文件
PJSUA2 - Recording call audio to wav file
我正在尝试使用 PJSUA2 将来电直接录制到 wav 文件,但听不到 wav 文件中的任何音频。
代码如下:
void SipCall::onCallMediaState(pj::OnCallMediaStateParam& /*prm*/)
{
pj::CallInfo call_info = getInfo();
pj::AudioMedia* audio_media = 0;
for (unsigned int i = 0; i < call_info.media.size(); ++i) {
if (call_info.media[i].type == PJMEDIA_TYPE_AUDIO) {
audio_media = static_cast<pj::AudioMedia*>(getMedia(i));
break;
}
}
if (audio_media != 0) {
try {
pj::AudioMediaRecorder recorder;
recorder.createRecorder("file.wav");
audio_media->startTransmit(recorder);
pj_thread_sleep(5000);
audio_media->stopTransmit(recorder);
}
catch (pj::Error& err) {
qWarning("[SipAccount::onIncomingCall] : Failed to record call to %s. Error = %s", "file.wav", err.info().data());
}
}
}
PJSUA2 的文档很差所以有人知道我做错了什么吗?
出现问题,因为 AudioMediaRecorder 对象刚创建就超出范围。如果您使它成为 class 的成员,则以下将起作用。
void SipCall::onCallMediaState(pj::OnCallMediaStateParam& /*prm*/)
{
pj::CallInfo call_info = getInfo();
pj::AudioMedia* audio_media = 0;
for (unsigned int i = 0; i < call_info.media.size(); ++i) {
if (call_info.media[i].type == PJMEDIA_TYPE_AUDIO) {
audio_media = static_cast<pj::AudioMedia*>(getMedia(i));
break;
}
}
if (audio_media != 0) {
try {
recorder.createRecorder("file.wav");
audio_media->startTransmit(recorder);
}
catch (pj::Error& err) {
qWarning("[SipAccount::onIncomingCall] : Failed to record call to %s. Error = %s", "file.wav", err.info().data());
}
}
}
在下面的 onCallState() 方法中进行任何必要的清理:
void SipCall::onCallState(pj::OnCallStateParam& prm)
{
int i = prm.e.type;
i = 0;
pj::CallInfo call_info = getInfo();
switch (call_info.state) {
case PJSIP_INV_STATE_DISCONNECTED:
// Add clean up code here
delete this;
break;
case PJSIP_INV_STATE_CONFIRMED:
break;
default:
break;
}
}
我在通过 JNI 调用 PJ 时遇到了同样的问题。就我而言,我忘记关闭录音机。如果你仔细看 documentation,它说你不能播放 wav 文件,除非你关闭录音机。所以停止传输后,不要忘记删除录音机。
您做错的是在 onCallMediaState
的线程中等待。为了进一步处理调用,该线程必须继续 运行。因此,您创建记录器,等待(没有任何反应,所以您什么也不记录),关闭记录器,通话继续。所以什么都没有记录。它与范围无关,因为在你的情况下,当超出范围时,记录器已经完成了他的工作记录。
你需要做的主要是确实不要在onCallMediaState
的线程中等待,让调用继续,并在调用被销毁时销毁记录器。为此,您需要从 SipCall::onCallMediaState
中获取记录器声明,当然或者正如您所说,记录器在完成工作之前会被销毁。
我正在尝试使用 PJSUA2 将来电直接录制到 wav 文件,但听不到 wav 文件中的任何音频。
代码如下:
void SipCall::onCallMediaState(pj::OnCallMediaStateParam& /*prm*/)
{
pj::CallInfo call_info = getInfo();
pj::AudioMedia* audio_media = 0;
for (unsigned int i = 0; i < call_info.media.size(); ++i) {
if (call_info.media[i].type == PJMEDIA_TYPE_AUDIO) {
audio_media = static_cast<pj::AudioMedia*>(getMedia(i));
break;
}
}
if (audio_media != 0) {
try {
pj::AudioMediaRecorder recorder;
recorder.createRecorder("file.wav");
audio_media->startTransmit(recorder);
pj_thread_sleep(5000);
audio_media->stopTransmit(recorder);
}
catch (pj::Error& err) {
qWarning("[SipAccount::onIncomingCall] : Failed to record call to %s. Error = %s", "file.wav", err.info().data());
}
}
}
PJSUA2 的文档很差所以有人知道我做错了什么吗?
出现问题,因为 AudioMediaRecorder 对象刚创建就超出范围。如果您使它成为 class 的成员,则以下将起作用。
void SipCall::onCallMediaState(pj::OnCallMediaStateParam& /*prm*/)
{
pj::CallInfo call_info = getInfo();
pj::AudioMedia* audio_media = 0;
for (unsigned int i = 0; i < call_info.media.size(); ++i) {
if (call_info.media[i].type == PJMEDIA_TYPE_AUDIO) {
audio_media = static_cast<pj::AudioMedia*>(getMedia(i));
break;
}
}
if (audio_media != 0) {
try {
recorder.createRecorder("file.wav");
audio_media->startTransmit(recorder);
}
catch (pj::Error& err) {
qWarning("[SipAccount::onIncomingCall] : Failed to record call to %s. Error = %s", "file.wav", err.info().data());
}
}
}
在下面的 onCallState() 方法中进行任何必要的清理:
void SipCall::onCallState(pj::OnCallStateParam& prm)
{
int i = prm.e.type;
i = 0;
pj::CallInfo call_info = getInfo();
switch (call_info.state) {
case PJSIP_INV_STATE_DISCONNECTED:
// Add clean up code here
delete this;
break;
case PJSIP_INV_STATE_CONFIRMED:
break;
default:
break;
}
}
我在通过 JNI 调用 PJ 时遇到了同样的问题。就我而言,我忘记关闭录音机。如果你仔细看 documentation,它说你不能播放 wav 文件,除非你关闭录音机。所以停止传输后,不要忘记删除录音机。
您做错的是在 onCallMediaState
的线程中等待。为了进一步处理调用,该线程必须继续 运行。因此,您创建记录器,等待(没有任何反应,所以您什么也不记录),关闭记录器,通话继续。所以什么都没有记录。它与范围无关,因为在你的情况下,当超出范围时,记录器已经完成了他的工作记录。
你需要做的主要是确实不要在onCallMediaState
的线程中等待,让调用继续,并在调用被销毁时销毁记录器。为此,您需要从 SipCall::onCallMediaState
中获取记录器声明,当然或者正如您所说,记录器在完成工作之前会被销毁。