def checkCallTime(self) -> None: """Check all current calls and enforce call time restrictions""" if ( self.__phone.current_call is None and len(self.__phone._ringing_calls) == 0 ): return with self.__phone._call_lock: call = self.__phone.current_call if call is not None: ci = call.getInfo() calltime = self.__config["calltime"] if ( 0 < calltime <= ci.connectDuration.sec and ci.state == pj.PJSIP_INV_STATE_CONFIRMED ): LOGGER.info( "Hanging up call to %s after %d seconds", repr(ci.remoteUri), self.__config["calltime"], ) fire_event("OnCallTimeExceeded") prm = pj.CallOpParam() call.hangup(prm) self.__phone.current_call = None else: synthetic_disconnect = False prm = pj.CallOpParam() for call in self.__phone._ringing_calls: try: ci = call.getInfo() if ci.totalDuration.sec >= self.__config["ringtime"]: LOGGER.info( "Giving up call to %s after %d seconds", repr(ci.remoteUri), self.__config["ringtime"], ) call.hangup(prm) self.__phone._ringing_calls.remove(call) synthetic_disconnect = True except pj.Error as err: if err.reason.endswith("(PJSIP_ESESSIONTERMINATED)"): LOGGER.warning( "Found an already terminated call, removing it" ) else: LOGGER.exception( "Can't get info for a call: %s", err.reason ) self.__phone._ringing_calls.remove(call) if ( synthetic_disconnect and len(self.__phone._ringing_calls) == 0 ): # Last ringing call was cancelled fire_event("OnCallUnanswered")
def hangup(self): self._logger.debug('entered hangup') self._logger.debug('before hangup, sip_call = %s',self._sip_call) prm=pjsua2.CallOpParam() if self._sip_call is not None: self._sip_call.hangup(prm) self._logger.debug('after sip_call.hangup(),sip_call = %s',self._sip_call)
def __init__(self,gtk_builder,account,prm,frame,parent_call_disconnected_handler): self._logger=logging.getLogger(__name__) super().__init__(gtk_builder,frame,parent_call_disconnected_handler) self._gtk_builder=gtk_builder self._call_id=prm.callId self._sip_call=gtkapplication.api.sip.sip_call.SipCall(account,self._call_id,on_call_state_change_handler=self.on_call_state_change_handler) call_prm=pjsua2.CallOpParam() call_prm.statusCode=180 self._sip_call.answer(call_prm) call_info=self._sip_call.getInfo() self._logger.debug("incoming call from '%s' to %s",call_info.remoteUri,account.uri) contact_manager=gtkapplication.api.contacts.contact_manager.ContactManager() (contact,active_contact_point_index)=contact_manager.find_contact_by_sip_uri(call_info.remoteUri,True) self._contact=contact self._active_contact_point_index=active_contact_point_index self._logger.info("contact = %s, active_contact_point_index = %s",contact,active_contact_point_index) contact_point=contact.contact_points[active_contact_point_index] assert contact_point.point_type in ["x-sip","tel"] if contact_point.point_type=="tel": caller_id="Incoming call from {0} ({1})".format(contact.name,contact_point.uri_string_national) elif contact_point.point_type=="x-sip": caller_id="Free Buddy call from {0}".format(contact.name) self._logger.info("caller_id = %s, point_type = %s",caller_id,contact_point.point_type) self._caller_id_label.set_text(caller_id) self._dialog_button_clicked=False gtkapplication.api.sip.sip_call_state.sip_calls[call_info.id]=self._sip_call
def onIncomingCall(self, iprm: pj.OnIncomingCallParam) -> None: sp = DoorPi().sipphone call = CallCallback(self, iprm.callId) callInfo = call.getInfo() oprm = pj.CallOpParam(False) event = None fire_event("BeforeCallIncoming", remote_uri=callInfo.remoteUri) try: if not sp.is_admin(callInfo.remoteUri): logger.info("Rejecting call from unregistered number %s", callInfo.remoteUri) oprm.statusCode = pj.PJSIP_SC_FORBIDDEN event = "OnCallReject" return with sp._Pjsua2__call_lock: if sp.current_call is not None and sp.current_call.isActive(): logger.info("Busy-rejecting call from %s", callInfo.remoteUri) oprm.statusCode = pj.PJSIP_SC_BUSY_HERE event = "OnCallBusy" return else: logger.info("Accepting incoming call from %s", callInfo.remoteUri) oprm.statusCode = pj.PJSIP_SC_OK event = "OnCallIncoming" sp.current_call = call return finally: call.answer(oprm) fire_event(event, remote_uri=callInfo.remoteUri)
def incoming_call(self, prm): call = Call(self.acc, call_id=prm.callId) call_prm = pj.CallOpParam() # Ringing State call_prm.statusCode = pj.PJSIP_SC_RINGING call.answer(call_prm) # Set uri call.uri = call.getInfo().remoteUri iid = call.uri.split(':')[1].split('@')[0] if msg.askquestion('Incoming Call', 'Accept call from ' + iid + ' ?', default=msg.YES): # If not exist current buddy, then create if iid not in self.buddy_list: # Initialize buddy bud = Buddy(self, iid) # Initialize configuration of buddy bud_cfg = pj.BuddyConfig() bud_cfg.uri = 'sip:' + iid + '@' + self.domain # Create buddy bud.cfg = bud_cfg bud.create(self.acc, bud.cfg) bud.subscribePresence(True) # Push into buddy_list self.buddy_list[iid] = bud self.update_buddy(bud) # If not exist current chat dialog, then create if iid not in self.chat_list: self.chat_list[iid] = Chat(self.acc, self.buddy_list[iid], self) # Inform the corresponding chat self.chat_list[iid].receive_call(call) else: call.hangup(call_prm)
def checkHangupAll(self) -> None: """Check if hanging up all calls was requested""" if not self.hangup: return with self.__phone._call_lock: prm = pj.CallOpParam() self.__phone._waiting_calls = [] for call in self.__phone._ringing_calls: try: call.hangup(prm) except pj.Error as err: if err.reason.endswith("(PJSIP_ESESSIONTERMINATED)"): continue LOGGER.exception( "Error hanging up a call: %s (ignored)", err.reason ) self.__phone._ringing_calls = [] if self.__phone.current_call is not None: self.__phone.current_call.hangup(prm) else: # Synthesize a disconnect event fire_event("OnCallDisconnect", remote_uri="sip:null@null") self.hangup = False
def startCall(self): self._gui.enableAudio() call_param = pj.CallOpParam() call_param.opt.audioCount = 1 call_param.opt.videoCount = 0 fails = [] for idx, p in enumerate(self._participantList): # just skip if call is instantiated if self._callList[idx]: continue uri_str = str(p) c = call.Call(self._acc, uri_str, self) self._callList[idx] = c self._gui.audioUpdateState(uri_str, gui.AudioState.INITIALIZING) try: c.makeCall(uri_str, call_param) except: self._callList[idx] = None self._gui.audioUpdateState(uri_str, gui.AudioState.FAILED) fails.append(p) for p in fails: # kick participants with call failure, but spare the last (avoid zombie chat) if not self.isPrivate(): self.kickParticipant(p)
def receive_call(self, call): # Update call and set chat self.call = call self.call.chat = self # Receive call call_prm = pj.CallOpParam() call_prm.statusCode = pj.PJSIP_SC_OK self.call.answer(call_prm)
def onUnhold(self, peer_uri_str): c = self._getCallFromUriStr(peer_uri_str, "onUnhold()") if not c: return call_param = pj.CallOpParam() call_param.opt.audioCount = 1 call_param.opt.videoCount = 0 call_param.opt.flag |= pj.PJSUA_CALL_UNHOLD c.reinvite(call_param)
def onCallState(self, prm: pj.OnCallStateParam) -> None: ci = self.getInfo() sp: glue.Pjsua2 = doorpi.INSTANCE.sipphone # type: ignore if ci.state == pj.PJSIP_INV_STATE_CALLING: LOGGER.debug("Call to %r is now calling", ci.remoteUri) elif ci.state == pj.PJSIP_INV_STATE_INCOMING: LOGGER.debug("Call from %r is coming in", ci.remoteUri) elif ci.state == pj.PJSIP_INV_STATE_EARLY: LOGGER.debug("Call to %r is in early state", ci.remoteUri) elif ci.state == pj.PJSIP_INV_STATE_CONNECTING: LOGGER.debug("Call to %r is now connecting", ci.remoteUri) elif ci.state == pj.PJSIP_INV_STATE_CONFIRMED: LOGGER.info("Call to %r was accepted", ci.remoteUri) self.__fire_disconnect = True with sp._call_lock: prm = pj.CallOpParam() if sp.current_call is not None: # (note: this should not be possible) sp.current_call.hangup(prm) sp.current_call = None sp.current_call = self for ring in sp._ringing_calls: if self != ring: ring.hangup(prm) sp._ringing_calls = [] sp._waiting_calls = [] fire_event("OnCallConnect", remote_uri=ci.remoteUri) elif ci.state == pj.PJSIP_INV_STATE_DISCONNECTED: LOGGER.info( "Call to %r disconnected after %d seconds (%d total)", ci.remoteUri, ci.connectDuration.sec, ci.totalDuration.sec, ) with sp._call_lock: if sp.current_call == self: sp.current_call = None elif self in sp._ringing_calls: sp._ringing_calls.remove(self) if self.__fire_disconnect: LOGGER.trace("Firing disconnect event for call to %r", ci.remoteUri) fire_event("OnCallDisconnect", remote_uri=ci.remoteUri) elif len(sp._ringing_calls) == 0: LOGGER.info("No call was answered") fire_event("OnCallUnanswered") else: LOGGER.trace( "Skipping disconnect event for call to %r", ci.remoteUri, ) else: LOGGER.warning("Call to %r: unknown state %d", ci.remoteUri, ci.state)
def on_hangup_button_clicked(self,button): self._logger.debug('entered on_hangup_button_clicked') if self._sip_call is None: self._logger.debug('in hangup _sip_call() is None') else: self._logger.debug("hanging up call") prm=pjsua2.CallOpParam() self._sip_call.hangup(prm) self._logger.debug("after hangup()")
def onCallState(self, prm: pj.OnCallStateParam) -> None: ci = self.getInfo() sp = DoorPi().sipphone eh = DoorPi().event_handler conf = DoorPi().config if ci.state == pj.PJSIP_INV_STATE_CALLING: logger.debug("Call to %s is now calling", repr(ci.remoteUri)) elif ci.state == pj.PJSIP_INV_STATE_INCOMING: logger.debug("Call from %s is incoming", repr(ci.remoteUri)) elif ci.state == pj.PJSIP_INV_STATE_EARLY: logger.debug("Call to %s is in early state", repr(ci.remoteUri)) elif ci.state == pj.PJSIP_INV_STATE_CONNECTING: logger.debug("Call to %s is now connecting", repr(ci.remoteUri)) elif ci.state == pj.PJSIP_INV_STATE_CONFIRMED: logger.info("Call to %s was accepted", repr(ci.remoteUri)) self.__fire_disconnect = True with sp._Pjsua2__call_lock: prm = pj.CallOpParam() if sp.current_call is not None: # (note: this should not be possible) sp.current_call.hangup(prm) sp.current_call = None sp.current_call = self for ring in sp._Pjsua2__ringing_calls: if self != ring: ring.hangup(prm) sp._Pjsua2__ringing_calls = [] sp._Pjsua2__waiting_calls = [] fire_event("OnCallConnect", remote_uri=ci.remoteUri) elif ci.state == pj.PJSIP_INV_STATE_DISCONNECTED: logger.info("Call to %s disconnected after %d seconds (%d total)", repr(ci.remoteUri), ci.connectDuration.sec, ci.totalDuration.sec) with sp._Pjsua2__call_lock: if sp.current_call == self: sp.current_call = None elif self in sp._Pjsua2__ringing_calls: sp._Pjsua2__ringing_calls.remove(self) if self.__fire_disconnect: logger.trace("Firing disconnect event for call to %s", repr(ci.remoteUri)) fire_event("OnCallDisconnect", remote_uri=ci.remoteUri) elif len(sp._Pjsua2__ringing_calls) == 0: logger.trace( "Last ringing call disconnected, synthesizing disconnect" ) fire_event("OnCallDisconnect", remote_uri="sip:null@null") else: logger.trace("Skipping disconnect event for call to %s", repr(ci.remoteUri)) else: logger.warning("Call to %s: unknown state %d", repr(ci.remoteUri), ci.state)
def _make_call(self): if self.state == AudioState.DISCONNECT: # Initialize Call self.call = Call(self.acc, self.bud.cfg.uri, self) # Create paramter call_prm = pj.CallOpParam() # Enable audio call_prm.opt.audioCount = 1 # Enable video call_prm.opt.videoCount = 1 # Make call self.call.makeCall(self.bud.cfg.uri, call_prm)
def on_answer_button_clicked(self,button): self._logger.debug('entered on_answer_button_clicked') self._dialog_button_clicked=True if self._sip_call is None: self._logger.warning('attempt to answer, but sip_call is None') else: gtkapplication.api.audio.ringer.stop_ringer() self._logger.debug('attempting to answer call from %s',self._contact.name) call_prm=pjsua2.CallOpParam() call_prm.statusCode=200 self._logger.debug("About to answer call with ID %d",self._call_id) self._sip_call.answer(call_prm) self._logger.debug('call answered from %s',self._contact.name) button.hide()
def _set_hold(self): if self.call: call_prm = pj.CallOpParam() if self.state == AudioState.CONNECT: self.call.setHold(call_prm) self.is_hold() elif self.state == AudioState.HOLD: # Important!!! Can't remove!!! call_prm.opt.audioCount = 1 call_prm.opt.flag = pj.PJSUA_CALL_UNHOLD self.call.reinvite(call_prm) self.is_unhold() else: print('Call isn\'t initialized')
def __init__(self,gtk_builder,contact,active_contact_point_index,frame,on_call_disconnected_handler): super().__init__(gtk_builder,frame,on_call_disconnected_handler) self._logger=logging.getLogger(__name__) self._call_id=-999 self._gtk_builder=gtk_builder self._contact=contact self._active_contact_point_index=active_contact_point_index contact_point=contact.contact_points[active_contact_point_index] pjsip_accessor=gtkapplication.api.sip.pjsip_container_accessor.PjSipContainerAccessor() account=None if contact_point.point_type=='tel': self._logger.debug('PSTN call') account=pjsip_accessor.get_account_by_name("twilio") self._logger.debug('account = %s',account) dest_uri=contact_point.uri_string self._logger.debug('dest_uri = %s',dest_uri) idUri=account.cfg.idUri self._logger.debug("idUri = %s",idUri) sip_parser=gtkapplication.api.sip.sipuri.SipUriParser() parsed_uri=sip_parser.parseSipUri(idUri) pstn_sip_domain=parsed_uri.host self._logger.debug('pstn_sip_domain = %s',pstn_sip_domain) dest_uri="sip:{0}@{1}".format(dest_uri,pstn_sip_domain) self._logger.debug("dest_uri after formatting for twilio = %s",dest_uri) self._logger.debug('calling dest_uri = %s',dest_uri) elif contact_point.point_type=="x-sip": self._logger.debug('Buddy call') account=pjsip_accessor.get_account_by_name("sip") self._logger.debug('account = %r',account) dest_uri=contact_point.uri_string buddy=contact.buddy self._logger.debug("buddy = %r",buddy) self._logger.info("free buddy calling from %s to %s",account.uri,buddy.uri) else: raise ValueError("invalid point_type: {0}".format(contact_point.point_type)) self._sip_call=gtkapplication.api.sip.sip_call.SipCall(account,pjsua2.PJSUA_INVALID_ID,on_call_state_change_handler=self.on_call_state_change_handler) contact_point=contact.contact_points[active_contact_point_index] self._logger.debug('point_type = %s',contact_point.point_type) self._call_status_label=self._gtk_builder.get_object("call_status_label") self._caller_id_label=self._gtk_builder.get_object("caller_id_label") self._caller_id_label.set_text("Calling {0}\n{1}".format(contact.name,contact_point.description)) call_param=pjsua2.CallOpParam() call_param.opt.audioCount=1 call_param.opt.videoCount=0 self._sip_call.makeCall(dest_uri,call_param) call_info=self._sip_call.getInfo() self._call_id=call_info.id gtkapplication.api.sip.sip_call_state.sip_calls[call_info.id]=self._sip_call self._logger.debug('call_id = %s',call_info.id)
def checkCallTime(self): """Check all current calls and enforce call time restrictions""" if self.__phone.current_call is None and len( self.__phone._Pjsua2__ringing_calls) == 0: return eh = DoorPi().event_handler with self.__phone._Pjsua2__call_lock: c = self.__phone.current_call if c is not None: ci = c.getInfo() if self.__max_call_time > 0 \ and ci.state == pj.PJSIP_INV_STATE_CONFIRMED \ and ci.connectDuration.sec >= self.__max_call_time: logger.info("Hanging up call to %s after %d seconds", repr(ci.remoteUri), self.__max_call_time) prm = pj.CallOpParam() c.hangup(prm) self.__phone.current_call = None else: synthetic_disconnect = False prm = pj.CallOpParam() for c in self.__phone._Pjsua2__ringing_calls: ci = c.getInfo() if ci.totalDuration.sec >= self.__call_timeout: logger.info( "Call to %s unanswered after %d seconds, giving up", repr(ci.remoteUri), self.__call_timeout) c.hangup(prm) self.__phone._Pjsua2__ringing_calls.remove(c) synthetic_disconnect = True if synthetic_disconnect and len( self.__phone._Pjsua2__ringing_calls) == 0: # All calls went unanswered. Synthesize a disconnect event. fire_event("OnCallDisconnect", remote_uri="sip:null@null")
def createCalls(self) -> None: """Create requested outbound calls""" if len(self.__phone._waiting_calls) == 0: return with self.__phone._call_lock: for uri in self.__phone._waiting_calls: LOGGER.info("Calling %s", uri) fire_event("OnCallOutgoing", remote_uri=uri) call = CallCallback(self.__account) callprm = pj.CallOpParam(True) try: call.makeCall(uri, callprm) except pj.Error as err: LOGGER.error("Error making a call: %s", err.info()) self.__phone._ringing_calls += [call] self.__phone._waiting_calls = []
def onIncomingCall(self, prm): c = call.Call(self, call_id=prm.callId) call_prm = pj.CallOpParam() call_prm.statusCode = 180 c.answer(call_prm) ci = c.getInfo() msg = "Incoming call for account '%s'" % self.cfg.idUri if msgbox.askquestion(msg, "Accept call from '%s'?" % (ci.remoteUri), default=msgbox.YES) == u'yes': call_prm.statusCode = 200 c.answer(call_prm) # find/create chat instance chat = self.findChat(ci.remoteUri) if not chat: chat = self.newChat(ci.remoteUri) chat.showWindow() chat.registerCall(ci.remoteUri, c) chat.updateCallState(c, ci) else: c.hangup(call_prm)
def on_hangup_button_clicked(self,button): self._logger.debug('entered on_hangup_button_clicked') self._dialog_button_clicked=True if self._sip_call is None: self._logger.debug('in reject _sip_call() is None') else: self._logger.debug('sip_call is not None') button_label=button.get_label() self._logger.debug("button_label = %s",button_label) assert button_label in ["Reject","Hang Up"] self._logger.debug("button.get_label = %s",button_label) if button_label=="Reject": self._logger.debug('call rejected from %s. Call ID = %d',self._contact.name,self._call_id) call_prm=pjsua2.CallOpParam() call_prm.statusCode=486 self._sip_call.answer(call_prm) self._logger.debug('after answer with 486') elif button_label=="Hang Up": self._logger.debug("Hang Up action") self.hangup()
def checkHangupAll(self): """Check if hanging up all calls was requested""" if self.hangup < 1: return with self.__phone._Pjsua2__call_lock: prm = pj.CallOpParam() self.__waiting_calls = [] for c in self.__ringing_calls: c.hangup(prm) self.__ringing_calls = [] if self.current_call is not None: self.current_call.hangup(prm) else: # Synthesize a disconnect event fire_event("OnCallDisconnect", remote_uri="sip:null@null") self.ready.release(self.hangup) self.hangup = 0
def onIncomingCall(self, prm): c = call.Call(self, call_id=prm.callId) call_prm = pj.CallOpParam() call_prm.statusCode = 180 c.answer(call_prm) ci = c.getInfo() print("Incoming call for account '%s'" % self.cfg.idUri) r=input("ACCEPT y/n ") if r == "y": call_prm.statusCode = 200 c.answer(call_prm) # find/create chat instance chat = self.findChat(ci.remoteUri) if not chat: chat = self.newChat(ci.remoteUri) chat.showWindow() chat.registerCall(ci.remoteUri, c) chat.updateCallState(c, ci) else: c.hangup(call_prm)
def onIncomingCall(self, iprm: pj.OnIncomingCallParam) -> None: sp: glue.Pjsua2 = doorpi.INSTANCE.sipphone # type: ignore call = CallCallback(self, iprm.callId) callInfo = call.getInfo() oprm = pj.CallOpParam(False) event = None fire_event("BeforeCallIncoming", remote_uri=callInfo.remoteUri) try: if not sp.is_admin(callInfo.remoteUri): LOGGER.info( "Rejecting call from unregistered number %s", callInfo.remoteUri, ) oprm.statusCode = pj.PJSIP_SC_FORBIDDEN event = "OnCallReject" else: with sp._call_lock: if (sp.current_call is not None and sp.current_call.isActive()): LOGGER.info("Busy-rejecting call from %s", callInfo.remoteUri) oprm.statusCode = pj.PJSIP_SC_BUSY_HERE event = "OnCallBusy" else: LOGGER.info( "Accepting incoming call from %s", callInfo.remoteUri, ) oprm.statusCode = pj.PJSIP_SC_OK event = "OnCallIncoming" sp.current_call = call call.answer(oprm) fire_event(event, remote_uri=callInfo.remoteUri) except Exception: LOGGER.exception("Error while handling incoming call") oprm.statusCode = pj.PJSIP_SC_FORBIDDEN call.answer(oprm)
def onHangup(self, peer_uri_str): c = self._getCallFromUriStr(peer_uri_str, "onHangup()") if not c: return call_param = pj.CallOpParam() c.hangup(call_param)
def pjsua2_test(): global ep # Create and initialize the library ep_cfg = pj.EpConfig() ep_cfg.logConfig.level = 5; ep = pj.Endpoint() ep.libCreate() ep.libInit(ep_cfg) ep.audDevManager().setNullDev() for codec in ep.codecEnum2(): priority = 0 if 'PCMA/8000' in codec.codecId: priority = 255 ep.codecSetPriority(codec.codecId, priority) # Create SIP transport. Error handling sample is shown sipTpConfig = pj.TransportConfig(); sipTpConfig.port = 15060; ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, sipTpConfig); # Start the library ep.libStart(); acfg = pj.AccountConfig(); acfg.idUri = "sip:1002@asterisk"; acfg.regConfig.registrarUri = "sip:asterisk"; cred = pj.AuthCredInfo("digest", "*", "1002", 0, "12345"); acfg.sipConfig.authCreds.append( cred ) # Create the account acc = pj.Account() acc.create(acfg) # Here we don't have anything else to do.. while not acc.getInfo().regIsActive: print('========== registering') time.sleep(0.1) if acc.getInfo().regStatus != 200: print('++++++++++++++++++') print('no registration') return call = Call(acc) prm = pj.CallOpParam(True) prm.opt.audioCount = 1 prm.opt.videoCount = 0 call.makeCall("sip:8080@asterisk", prm) while call.getInfo().state != pj.PJSIP_INV_STATE_CONFIRMED: print(call.getInfo().stateText) time.sleep(0.1) f = open('output.lpcm', 'wb') f2 = open('hw.raw', 'rb') hwraw = f2.read() n = 320 [call.putFrame(hwraw[i:i+320]) for i in range(0, len(hwraw), n)] for i in range(10): time.sleep(1) data = call.getFrames() if data: f.write(data) f.close() prm = pj.CallOpParam() call.hangup(prm) # Destroy the library ep.hangupAllCalls() print('unregistering') acc.delete()
def _hang_up(self): if self.call: call_prm = pj.CallOpParam() if self.state != AudioState.DISCONNECT: self.call.hangup(call_prm)
def stopCall(self): for idx, p in enumerate(self._participantList): self._gui.audioUpdateState(str(p), gui.AudioState.DISCONNECTED) c = self._callList[idx] if c: c.hangup(pj.CallOpParam())
def onHold(self, peer_uri_str): c = self._getCallFromUriStr(peer_uri_str, "onHold()") if not c: return call_param = pj.CallOpParam() c.setHold(call_param)
def pjsua2_test(): # Create and initialize the library global ep ep_cfg = pj.EpConfig() ep_cfg.uaConfig.threadCnt = 0 ep_cfg.uaConfig.mainThreadOnly = False ep = pj.Endpoint() ep.libCreate() ep.libInit(ep_cfg) # Create SIP transport. Error handling sample is shown sipTpConfig = pj.TransportConfig() sipTpConfig.port = 12345 tp = ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, sipTpConfig) # Start the library ep.libStart() acfg = pj.AccountConfig() acfg.idUri = "sip:192.168.1.11:12345" # Create the account acc = Account(ep) acc.create(acfg) #Get device list and collect device IDs of two virtual devices created ep.audDevManager().refreshDevs() devList = ep.audDevManager().enumDev() fullRecorderDeviceID = 0 devID = 0 for dev in devList: print(dev.name) if (dev.name == "FullRecorder"): acc.fullRecorderDeviceID = devID if (dev.name == "CallerVoice"): acc.callerVoiceRecorderDeviceID = devID ep.audDevManager().setPlaybackDev(acc.callerVoiceRecorderDeviceID) #acc.amr=ep.audDevManager().getPlaybackDevMedia() acc.amr = pj.AudioMediaRecorder.typecastFromAudioMedia( ep.audDevManager().getPlaybackDevMedia()) acc.amr.createRecorder(file_name="123.wav") ep.mediaAdd(acc.amr) devID = devID + 1 ep.audDevManager().setPlaybackDev(acc.fullRecorderDeviceID) while True: ep.libHandleEvents(10) if (acc.acceptCall == True): acc.acceptCall = False call_prm = pj.CallOpParam() call_prm.statusCode = 200 acc.c.answer(call_prm) if (acc.c.canConnectPlayer == True and acc.c.am != None): acc.c.canConnectPlayer = False player = pj.AudioMediaPlayer() #Play welcome message fn = u'/PJSUA2/example/welcomeFull.wav' player.createPlayer(fn, pj.PJMEDIA_FILE_NO_LOOP) # This will connect the sound device/mic to the call audio media player.startTransmit(acc.c.am) #player.startTransmit( ep.audDevManager().getPlaybackDevMedia()); #ep.audDevManager().setPlaybackDev(self.acc.callerVoiceRecorderDeviceID); #player.startTransmit(acc.amr) """ ep.audDevManager().refreshDevs(); devList=ep.audDevManager().enumDev() devID=0 for dev in devList: print(dev.name) """ ep.libDestroy()