Здравствуйте,
Чтобы две стороны могли разговаривать, а третья - подслушивать, необходима трехсторонняя конференция. То есть, будет как минимум три задачи: принявшая звонок, осуществляющая звонок на указанный номер, осуществляющая звонок на номер записывающего устройства.
Еще коментарии ниже.
Никитин Андрей wrote:
> День добрый!
> > Подскажите, как реализовать запись разговора при трансфере. > > Код. >
[]
> > В таком виде, CGP начинает запись до соединения, если вставить строчку > tmp=recordTalk(60, "?????????????"); > после peerLeg = callerLeg(parameters,false); , то соединение разрывается.
У задачи только один медиа канал. Либо его используют для передачи медиа удаленному клиенту, либо используют для записи. Разбить медиа поток на два нельзя. Но можно построить миксер - с тремя задачами.
В аттачменте - пример програмки, которую можно использовать для экспериментов. Первый параметр - куда звоним, второй - кого подключаем дополнительно. Если вторыми параметрами указаны слова file или mail, а первый параметр роутится в локальный аккаунт, то програмка просто записывает медиа и, в зависимости от второго параметра, либо пишет в файл персонального сайта аккаунта, либо отправляет по почте этому аккаунту.
Пример: при звонке на 101 нас соединят с 102 и 103 одновременно (на 103 может быть айБим в режиме атоматического приема звонков и автоматической же записи):
S: <101> = ed{102,103}#pbx
Пример: при звонке на 101 нас соединят 102, а запись разговора сохранится в персональном сайте аккаунта 103 (то есть, будут запущены две копии програмки ed):
S: <recorder> = ed{103,file}#pbx
S: <101> = ed{102,recorder}#pbx
Не судите строго - програмка используется исключительно для тестирования CGPro, но может быть использована для иллюстрации применения миксера.
> С уважением Никитин Андрей
--
Best regards,
Dmitry Akindinov -- Stalker Labs.
ed.sppr:
========================================================================
function caller(uri) forward;
function submitVoiceMail(recordedMessage,fromAddress,toAddress) forward;
entry Main is
phoneNumber = Vars().startParameter;
if IsArray(phoneNumber) then
recorderNum = phoneNumber[1];
if recorderNum != "mail" and then recorderNum != "file" then
recorderNum = "sip:" + recorderNum + "@" + MyDomain() +
";services=no";
phoneNumber = "sip:" + phoneNumber[0] + "@" + MyDomain() +
";services=no";
else
phoneNumber = phoneNumber[0];
end if;
else
RejectCall("555-Bad params");
end if;
syslog("Recording to " + recorderNum);
if recorderNum == "mail" or else recorderNum == "file" then
if AcceptCall() == null then
data = Record(300);
if recorderNum == "mail" then
void(submitVoiceMail(data,"mailer-daemon@"+MyDomain(),phoneNumber));
else
if FindSubstring(phoneNumber, "@") < 0 then phoneNumber =
phoneNumber + "@" + MyDomain(); end if;
phoneNumber = RouteLocalURI(EmailToSIPURI(phoneNumber));
if phoneNumber == null then phoneNumber = MyEmail(); end if;
sysLog("Filing to " + objectToString(phoneNumber));
if phoneNumber != null then
void(WriteSiteFile("~" + phoneNumber + "/recording.wav", data));
end if;
end if;
end if;
stop;
end if;
callee = caller(phoneNumber);
if not IsTask(callee) then
syslog("Callee failed: " + callee);
RejectCall("486-"+callee);
stop;
end if;
errCode = null;
while errCode == null and then not IsConnected() loop
syslog("--- half connected");
input = ReadInput(180);
if input.sender == callee and then input.what == "provision" then
errCode = ProvisionCall(null, null);
elif input.sender == callee and then input.what == "connected" then
errCode = AcceptCall();
elif input.sender == callee and then (input.what == "error" or else
input.what == "stop") then
RejectCall("487-" + ObjectToString(input.parameter));
stop;
end if;
exitif not IsDictionary(input) or else errCode != null or else
isDisconnectEvent(input);
end loop;
if errCode == null and then IsConnected() then
errCode = SendEvent(callee, "connected", null);
if errCode == null then
input = ReadInput(10);
if IsStartBridgeEvent(input) then
errCode = AttachMixer(input);
else
errCode = "unexpected event: " + ObjectToString(input);
end if;
end if;
else
errCode = "not connected";
end if;
if errCode != null then
void(SendEvent(callee, "stop", ObjectToString(errCode)));
syslog("--- Something failed: " + ObjectToString(errCode));
stop;
end if;
recorder = caller(recorderNum);
if not IsTask(recorder) then
syslog("Recorder failed: " + callee);
PlayFile("Failure");
end if;
while IsConnected() loop
input = ReadInput(180);
syslog("--- Event: " + ObjectToString(input));
if IsStartBridgeEvent(input) and then input.sender == recorder then
errCode = AttachMixer(input);
if errCode != null then
syslog("--- Failed to attach the recorder");
PlayFile("Failure");
end if;
elif IsDictionary(input) then
if input.what == "stop" and then input.sender == callee then
Disconnect();
elif input.what == "connected" and then input.sender == recorder then
void(SendEvent(recorder,"connected", null));
end if;
end if;
end loop;
end entry;
entry callerTask forward;
function caller(uri) is
theTask = spawn callerTask;
if theTask == null then return "failed to spawn"; end if;
params = NewDictionary();
params.("") = uri;
params.From = RemoteURI();
params.impersonate= "*";
params.referMode = "peer";
params.("Call-ID")= PendingRequestData("Call-ID")+".ed";
errCode = SendEvent(theTask, "start", ObjectToString(params));
if errCode != null then return errCode; end if;
return theTask;
end function;
entry callerTask is
startEvent = ReadInput(10);
if not IsDictionary(startEvent) or else startEvent.what != "start" then
syslog("=== Caller got unexpected event: " +
ObjectToString(startEvent));
stop;
end if;
params = TextToObject(startEvent.parameter);
if not IsDictionary(params) then
syslog("=== Caller got unexpected param: " + ObjectToString(params));
stop;
end if;
if params.impersonate != null then
void(Impersonate(params.impersonate)); end if;
if params.referMode != null then SetReferMode(params.referMode);
end if;
SetForeignCredentials(params.authUsername,params.authPassword);
SetBridgeBreakMode("disconnect");
errCode = StartCall(params);
if errCode != null then
syslog("=== StartCall failed with: " + ObjectToString(errCode));
void(SendEvent(startEvent.sender,"error",ObjectToString(errCode)));
stop;
end if;
loop
syslog("=== half connected");
input = ReadInput(10);
if IsCallProvisionEvent(input) then
void(SendEvent(startEvent.sender,"provision",null));
elif IsDictionary(input) and then input.what == "stop" then
syslog("=== stopping on the parent's request");
stop;
elif IsCallCompletedEvent(input) then
errCode = input.parameter;
syslog("=== call completed: " + ObjectToString(errCode));
if errCode != null then
errCode = ObjectToString(errCode);
syslog("=== Call failed with: " + errCode);
void(SendEvent(startEvent.sender,"error", errCode));
stop;
end if;
end if;
exitif IsCallCompletedEvent(input);
end loop;
if IsConnected() then
syslog("=== connected");
void(SendEvent(startEvent.sender,"connected",ObjectToString(errCode)));
while IsConnected() loop
input = ReadInput(1800);
if IsDictionary(input) and then input.what == "connected" then
errCode = StartBridge(startEvent.sender);
end if;
end loop;
end if;
void(SendEvent(startEvent.sender, "stop", "terminating"));
syslog("=== quitting");
end entry;
function submitVoiceMail(recordedMessage,fromAddress,toAddress) is
when = LocalTime();
voiceContent = NewDictionary();
voiceContent.("Content-Type") = "audio";
voiceContent.("Content-Subtype") = "32KADPCM";
voiceContent.("Content-Disposition") = "inline";
voiceContent.("filename") = "recording-" +
String(Year(when)) + "-" + Month(when) + "-" +
SubString("0"+String(MonthDay(when) ),-1,2) + "_" +
SubString("0"+String(TimeOfDay(when)/3600),-1,2) + "-" +
SubString("0"+String(TimeOfDay(when)/60%60),-1,2) + ".wav";
voiceContent.body = recordedMessage;
multiparts = newArray();
multiparts[0] = voiceContent;
content = NewDictionary();
content.("Content-Subtype") = "voice-message";
content.body = multiparts;
headers = newDictionary();
headers.("Content-Class") = "audio";
headers.("Message-Context") = "voice-message";
headers.protocol = "SIP";
headers.sourceType = "PBX";
headers.emptyReturnPath = "YES";
headers.("X-Priority") = "1";
return SendEmail(fromAddress,"Recorded Call",toAddress,headers,content);
end function;
Получено Tue Jun 19 05:35:52 2007
Этот архив был сгенерирован hypermail 2.1.8 : Tue 19 Jun 2007 - 10:13:40 MSD