Здравствуйте,
Чтобы две стороны могли разговаривать, а третья - подслушивать, необходима трехсторонняя конференция. То есть, будет как минимум три задачи: принявшая звонок, осуществляющая звонок на указанный номер, осуществляющая звонок на номер записывающего устройства.
Еще коментарии ниже.
Никитин Андрей 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