summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2014-02-21 07:53:31 +0000
committerNanang Izzuddin <nanang@teluu.com>2014-02-21 07:53:31 +0000
commit37cba321ed3f61e6399f388cbf7327d21e90bdc3 (patch)
tree916c2a37c8abd86a3e25a7896ca889ae033e2216
parent0f680b988a08ea439438f4483d1d97a78145fb48 (diff)
Re #1708: Fixed missing conference port connection setups for audio conferencing.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4757 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip-apps/src/pygui/call.py2
-rw-r--r--pjsip-apps/src/pygui/chat.py83
-rw-r--r--pjsip-apps/src/pygui/chatgui.py2
3 files changed, 72 insertions, 15 deletions
diff --git a/pjsip-apps/src/pygui/call.py b/pjsip-apps/src/pygui/call.py
index 35bf698c..fb2bb602 100644
--- a/pjsip-apps/src/pygui/call.py
+++ b/pjsip-apps/src/pygui/call.py
@@ -70,6 +70,8 @@ class Call(pj.Call):
elif mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE and self.onhold:
self.chat.addMessage(None, "'%s' sets call active" % (self.peerUri))
self.onhold = False
+ if self.chat:
+ self.chat.updateCallMediaState(self, ci)
def onInstantMessage(self, prm):
# chat instance should have been initalized
diff --git a/pjsip-apps/src/pygui/chat.py b/pjsip-apps/src/pygui/chat.py
index 760af1c7..1a90401f 100644
--- a/pjsip-apps/src/pygui/chat.py
+++ b/pjsip-apps/src/pygui/chat.py
@@ -140,15 +140,15 @@ class Chat(gui.ChatObserver):
continue
# send via call, if any, or buddy
- sender = None
+ target = None
if self._callList[idx] and self._callList[idx].connected:
- sender = self._callList[idx]
+ target = self._callList[idx]
else:
- sender = self._buddyList[idx]
- assert(sender)
+ target = self._buddyList[idx]
+ assert(target)
try:
- sender.sendTypingIndication(type_ind_param)
+ target.sendTypingIndication(type_ind_param)
except:
pass
@@ -162,15 +162,15 @@ class Chat(gui.ChatObserver):
continue
# send via call, if any, or buddy
- sender = None
+ target = None
if self._callList[idx] and self._callList[idx].connected:
- sender = self._callList[idx]
+ target = self._callList[idx]
else:
- sender = self._buddyList[idx]
- assert(sender)
+ target = self._buddyList[idx]
+ assert(target)
try:
- sender.sendInstantMessage(send_im_param)
+ target.sendInstantMessage(send_im_param)
except:
# error will be handled via Account::onInstantMessageStatus()
pass
@@ -302,10 +302,26 @@ class Chat(gui.ChatObserver):
self._gui.audioUpdateState(thecall.peerUri, gui.AudioState.INITIALIZING)
elif info.state == pj.PJSIP_INV_STATE_CONFIRMED:
self._gui.audioUpdateState(thecall.peerUri, gui.AudioState.CONNECTED)
- med_idx = self._getActiveMediaIdx(thecall)
- si = thecall.getStreamInfo(med_idx)
- stats_str = "Audio codec: %s/%s\n..." % (si.codecName, si.codecClockRate)
- self._gui.audioSetStatsText(thecall.peerUri, stats_str)
+ if not self.isPrivate():
+ # inform peer about conference participants
+ conf_welcome_str = '\n---\n'
+ conf_welcome_str += 'Welcome to the conference, participants:\n'
+ conf_welcome_str += '%s (host)\n' % (self._acc.cfg.idUri)
+ for p in self._participantList:
+ conf_welcome_str += '%s\n' % (str(p))
+ conf_welcome_str += '---\n'
+ send_im_param = pj.SendInstantMessageParam()
+ send_im_param.content = conf_welcome_str
+ try:
+ thecall.sendInstantMessage(send_im_param)
+ except:
+ pass
+
+ # inform others, including self
+ msg = "[Conf manager] %s has joined" % (thecall.peerUri)
+ self.addMessage(None, msg)
+ self._sendInstantMessage(msg, thecall.peerUri)
+
elif info.state == pj.PJSIP_INV_STATE_DISCONNECTED:
if info.lastStatusCode/100 != 2:
self._gui.audioUpdateState(thecall.peerUri, gui.AudioState.FAILED)
@@ -324,6 +340,45 @@ class Chat(gui.ChatObserver):
# kick the disconnected participant, but the last (avoid zombie chat)
if not self.isPrivate():
self.kickParticipant(ParseSipUri(thecall.peerUri))
+
+ # inform others, including self
+ msg = "[Conf manager] %s has left" % (thecall.peerUri)
+ self.addMessage(None, msg)
+ self._sendInstantMessage(msg, thecall.peerUri)
+
+ def updateCallMediaState(self, thecall, info = None):
+ # info is optional here, just to avoid calling getInfo() twice (in the caller and here)
+ if not info: info = thecall.getInfo()
+
+ med_idx = self._getActiveMediaIdx(thecall)
+ if (med_idx < 0):
+ self._gui.audioSetStatsText(thecall.peerUri, 'No active media')
+ return
+
+ si = thecall.getStreamInfo(med_idx)
+ dir_str = ''
+ if si.dir == 0:
+ dir_str = 'inactive'
+ else:
+ if si.dir & pj.PJMEDIA_DIR_ENCODING:
+ dir_str += 'send '
+ if si.dir & pj.PJMEDIA_DIR_DECODING:
+ dir_str += 'receive '
+ stats_str = "Direction : %s\n" % (dir_str)
+ stats_str += "Audio codec : %s (%sHz)" % (si.codecName, si.codecClockRate)
+ self._gui.audioSetStatsText(thecall.peerUri, stats_str)
+ m = pj.AudioMedia.typecastFromMedia(thecall.getMedia(med_idx))
+
+ # make conference
+ for c in self._callList:
+ if c == thecall:
+ continue
+ med_idx = self._getActiveMediaIdx(c)
+ if med_idx < 0:
+ continue
+ mm = pj.AudioMedia.typecastFromMedia(c.getMedia(med_idx))
+ m.startTransmit(mm)
+ mm.startTransmit(m)
# ** callbacks from GUI (ChatObserver implementation) **
diff --git a/pjsip-apps/src/pygui/chatgui.py b/pjsip-apps/src/pygui/chatgui.py
index bb58e286..01c149bf 100644
--- a/pjsip-apps/src/pygui/chatgui.py
+++ b/pjsip-apps/src/pygui/chatgui.py
@@ -257,7 +257,7 @@ class AudioFrame(ttk.Labelframe):
self.btnTxMute.pack(side=tk.LEFT)
# stat
- self.stat = tk.Text(self._callFrame, width=10, height=2, bg='lightgray', relief=tk.FLAT, font=("Arial", "9"))
+ self.stat = tk.Text(self._callFrame, width=10, height=2, bg='lightgray', relief=tk.FLAT, font=("Courier", "9"))
self.stat.insert(tk.END, 'stat here')
self.stat.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=1)