call.py 3.6 KB

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