Alexandre Lision | 0e14301 | 2014-01-22 11:02:46 -0500 | [diff] [blame^] | 1 | # $Id: call.py 4704 2014-01-16 05:30:46Z ming $ |
| 2 | # |
| 3 | # pjsua Python GUI Demo |
| 4 | # |
| 5 | # Copyright (C)2013 Teluu Inc. (http://www.teluu.com) |
| 6 | # |
| 7 | # This program is free software; you can redistribute it and/or modify |
| 8 | # it under the terms of the GNU General Public License as published by |
| 9 | # the Free Software Foundation; either version 2 of the License, or |
| 10 | # (at your option) any later version. |
| 11 | # |
| 12 | # This program is distributed in the hope that it will be useful, |
| 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | # GNU General Public License for more details. |
| 16 | # |
| 17 | # You should have received a copy of the GNU General Public License |
| 18 | # along with this program; if not, write to the Free Software |
| 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 20 | # |
| 21 | import sys |
| 22 | if sys.version_info[0] >= 3: # Python 3 |
| 23 | import tkinter as tk |
| 24 | from tkinter import ttk |
| 25 | from tkinter import messagebox as msgbox |
| 26 | else: |
| 27 | import Tkinter as tk |
| 28 | import tkMessageBox as msgbox |
| 29 | import ttk |
| 30 | |
| 31 | import random |
| 32 | import pjsua2 as pj |
| 33 | import application |
| 34 | import endpoint as ep |
| 35 | |
| 36 | # Call class |
| 37 | class Call(pj.Call): |
| 38 | """ |
| 39 | High level Python Call object, derived from pjsua2's Call object. |
| 40 | """ |
| 41 | def __init__(self, acc, peer_uri='', chat=None, call_id = pj.PJSUA_INVALID_ID): |
| 42 | pj.Call.__init__(self, acc, call_id) |
| 43 | self.acc = acc |
| 44 | self.peerUri = peer_uri |
| 45 | self.chat = chat |
| 46 | self.connected = False |
| 47 | self.onhold = False |
| 48 | |
| 49 | def onCallState(self, prm): |
| 50 | ci = self.getInfo() |
| 51 | self.connected = ci.state == pj.PJSIP_INV_STATE_CONFIRMED |
| 52 | if self.chat: |
| 53 | self.chat.updateCallState(self, ci) |
| 54 | |
| 55 | def onCallMediaState(self, prm): |
| 56 | ci = self.getInfo() |
| 57 | for mi in ci.media: |
| 58 | if mi.type == pj.PJMEDIA_TYPE_AUDIO and \ |
| 59 | (mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE or \ |
| 60 | mi.status == pj.PJSUA_CALL_MEDIA_REMOTE_HOLD): |
| 61 | m = self.getMedia(mi.index) |
| 62 | am = pj.AudioMedia.typecastFromMedia(m) |
| 63 | # connect ports |
| 64 | ep.Endpoint.instance.audDevManager().getCaptureDevMedia().startTransmit(am) |
| 65 | am.startTransmit(ep.Endpoint.instance.audDevManager().getPlaybackDevMedia()) |
| 66 | |
| 67 | if mi.status == pj.PJSUA_CALL_MEDIA_REMOTE_HOLD and not self.onhold: |
| 68 | self.chat.addMessage(None, "'%s' sets call onhold" % (self.peerUri)) |
| 69 | self.onhold = True |
| 70 | elif mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE and self.onhold: |
| 71 | self.chat.addMessage(None, "'%s' sets call active" % (self.peerUri)) |
| 72 | self.onhold = False |
| 73 | |
| 74 | def onInstantMessage(self, prm): |
| 75 | # chat instance should have been initalized |
| 76 | if not self.chat: return |
| 77 | |
| 78 | self.chat.addMessage(self.peerUri, prm.msgBody) |
| 79 | self.chat.showWindow() |
| 80 | |
| 81 | def onInstantMessageStatus(self, prm): |
| 82 | if prm.code/100 == 2: return |
| 83 | # chat instance should have been initalized |
| 84 | if not self.chat: return |
| 85 | |
| 86 | self.chat.addMessage(None, "Failed sending message to '%s' (%d): %s" % (self.peerUri, prm.code, prm.reason)) |
| 87 | |
| 88 | def onTypingIndication(self, prm): |
| 89 | # chat instance should have been initalized |
| 90 | if not self.chat: return |
| 91 | |
| 92 | self.chat.setTypingIndication(self.peerUri, prm.isTyping) |
| 93 | |
| 94 | def onDtmfDigit(self, prm): |
| 95 | #msgbox.showinfo("pygui", 'Got DTMF:' + prm.digit) |
| 96 | pass |
| 97 | |
| 98 | def onCallMediaTransportState(self, prm): |
| 99 | #msgbox.showinfo("pygui", "Media transport state") |
| 100 | pass |
| 101 | |
| 102 | |
| 103 | if __name__ == '__main__': |
| 104 | application.main() |