我正在尝试在由pjsip管理的2个星号扩展名之间进行电话会议。 我想打电话给123和124,然后让他们通话。
我已经设置了两个不同的传输方式和两个帐户,这不是强制性的,但这是我正在尝试的方式。无论如何,将一个帐户用于两个通话都很好。
问题是以下代码:
import pjsua
import threading
from time import sleep
def log_cb(level, str, len):
print str,
class MyAccountCallback(pjsua.AccountCallback):
sem = None
def __init__(self, account=None):
pjsua.AccountCallback.__init__(self, account)
def wait(self):
self.sem = threading.Semaphore(0)
self.sem.acquire()
def on_reg_state(self):
if self.sem:
if self.account.info().reg_status >= 200:
self.sem.release()
def cb_func(pid) :
print '%s playback is done' % pid
current_call.hangup()
# Callback to receive events from Call
class MyCallCallback(pjsua.CallCallback):
def __init__(self, call=None, dostuff=True):
pjsua.CallCallback.__init__(self, call)
self.dostuff=dostuff
# Notification when call state has changed
def on_state(self):
if not self.dostuff:
return
global current_call
global in_call
print "Call with", self.call.info().remote_uri,
print "is", self.call.info().state_text,
print "last code =", self.call.info().last_code,
print "(" + self.call.info().last_reason + ")"
#if self.call.info().media_state == pjsua.MediaState.ACTIVE:
# # Connect the call to sound device
# call_slot = self.call.info().conf_slot
# lib.conf_connect(call_slot, 0)
# lib.conf_connect(0, call_slot)
# print "Hello world, I can talk!"
if self.call.info().state == pjsua.CallState.DISCONNECTED:
current_call = None
print 'Current call is', current_call
in_call = False
elif self.call.info().state == pjsua.CallState.CONFIRMED:
print "Call Answred"
another_call = make_call(acc2, dst_uri2, dostuff=False)
conf_slot = self.call.info().conf_slot
conf_slot_2 = another_call.info().conf_slot
i = 0
while i < 10:
print '#####################################'
print '#####################################'
print 'conf_slot ' + str(conf_slot)
print 'conf_slot_2 ' + str(conf_slot_2)
print '#####################################'
print '#####################################'
if another_call.info().state == pjsua.CallState.CONFIRMED:
i = pjsua.Lib.instance()
i.conf_connect(conf_slot, conf_slot_2)
i.conf_connect(conf_slot_2, conf_slot)
else:
print '#####################################'
print 'FIRST CALL STATE %s' % self.call.info().__dict__
print '\n\n'
print 'ANOTHER CALL STATE %s' % another_call.info().__dict__
print '#####################################'
sleep(2)
i += 2
sleep(25)
self.call.hangup()
another_call.hangup()
in_call = False
# Notification when call's media state has changed.
def on_media_state(self):
if self.call.info().media_state == pjsua.MediaState.ACTIVE:
print "Media is now active"
else:
print "Media is inactive"
# Function to make call
def make_call(ac, uri, dostuff=True):
try:
print "Making call to", uri
return ac.make_call(uri, cb=MyCallCallback(dostuff=dostuff))
except pjsua.Error, e:
print "Exception: " + str(e)
return None
lib = pjsua.Lib()
try:
cfg = pjsua.MediaConfig()
lib.init(log_cfg = pjsua.LogConfig(level=4, callback=log_cb), media_cfg=cfg)
t1 = lib.create_transport(pjsua.TransportType.UDP, pjsua.TransportConfig(5081))
t2 = lib.create_transport(pjsua.TransportType.UDP, pjsua.TransportConfig(5082))
lib.set_null_snd_dev()
lib.start()
lib.handle_events()
acc_cfg = pjsua.AccountConfig()
acc_cfg.id = "sip:11111"
acc_cfg.reg_uri = "sip:localhost"
#acc_cfg.proxy = [ "sip:PROXY.YOURSIPSERVER.COM;lr" ]
acc_cfg.auth_cred = [ pjsua.AuthCred("*", "11111", "secret")]
acc_cb = MyAccountCallback()
acc = lib.create_account(acc_cfg, cb=acc_cb)
acc.set_transport(pjsua.Transport(lib, 1))
acc_cb.wait()
print "\n"
print "Registration complete, status=", acc.info().reg_status, \
"(" + acc.info().reg_reason + ")"
##########
# ACCO 2
##########
acc2_cfg = pjsua.AccountConfig()
acc2_cfg.id = "sip:11112"
acc2_cfg.reg_uri = "sip:localhost"
acc2_cfg.transport_id = t2._id
# a2cc_cfg.proxy = [ "sip:PROXY.YOURSIPSERVER.COM;lr" ]
acc2_cfg.auth_cred = [pjsua.AuthCred("*", "11112", "secret")]
acc2_cb = MyAccountCallback()
acc2 = lib.create_account(acc2_cfg, cb=acc2_cb)
acc2.set_transport(t2)
acc2_cb.wait()
###########
#YOURDESTINATION is landline or mobile number you want to call
dst_uri = "sip:123@localhost"
dst_uri2 = "sip:124@localhost"
in_call = True
lck = lib.auto_lock()
current_call = make_call(acc, dst_uri)
print 'Current call is', current_call
del lck
#wait for the call to end before shuting down
while in_call:
print('In call')
sleep(3)
pass
#sys.stdin.readline()
lib.destroy()
lib = None
except pjsua.Error, e:
print "Exception: " + str(e)
lib.destroy()
产生以下结果:
#####################################
In call
#####################################
#####################################
conf_slot 1
conf_slot_2 -1
#####################################
#####################################
#####################################
FIRST CALL STATE {'total_time': 6, 'account': <pjsua.Account instance at 0x7f9482f90ea8>, 'conf_slot': 1, 'sip_call_id': 'de7fe2e7-21c5-4763-a02b-a7a08ab20d02', 'uri': 'sip:11111', 'media_state': 1, 'last_reason': 'OK', 'remote_contact': '<sip:123@127.0.0.1:5060>', 'state': 5, 'contact': '<sip:127.0.0.1:5081;ob>', 'role': 0, 'state_text': 'CONFIRMED', 'media_dir': 3, 'remote_uri': 'sip:123@localhost', 'call_time': 6, 'last_code': 200}
ANOTHER CALL STATE {'total_time': 6, 'account': <pjsua.Account instance at 0x7f9482fa0200>, 'conf_slot': -1, 'sip_call_id': '094b998a-2b0c-42eb-b5ac-0a44251a6566', 'uri': 'sip:11112', 'media_state': 0, 'last_reason': '', 'remote_contact': '', 'state': 1, 'contact': '<sip:127.0.0.1:5082;ob>', 'role': 0, 'state_text': 'CALLING', 'media_dir': 0, 'remote_uri': 'sip:124@localhost', 'call_time': 0, 'last_code': 0}
#####################################
第二个呼叫没有开始。事实并非如此,我认为conf_slot仍为-1,因此不可能桥接:
i.conf_connect(conf_slot, conf_slot_2)
i.conf_connect(conf_slot_2, conf_slot)
任何提示将不胜感激。
答案 0 :(得分:1)
您的第二通电话似乎没有建立。您混合了很多代码。我建议您尝试使用外部SIP客户端(例如,同理心(https://en.wikipedia.org/wiki/Empathy_(software) + SIP插件))首先使呼叫正常工作
在进行工作以通过会议网桥接听来电时,请尝试使用2个线程来管理2个不同的端点。如果pjsip回调很忙(直到长时间任务结束才使用),其他回调将不会触发,因此无法使其正常工作。
尝试隔离创建自定义类和来自不同线程的呼叫的呼叫/帐户代码。