Examples¶
Here we will go over a few basic phone setups.
Setup¶
PyVoIP uses callback functions to initiate phone calls. In the example below, our callback function is named answer. The callback takes one argument, which is a VoIPCall class.
We are also importing VoIPPhone and InvalidStateError. VoIPPhone is the main class for our softphone. An InvalidStateError is thrown when you try to perform an impossible command. For example, denying the call when the phone is already answered, answering when it’s already answered, etc.
The following will create a phone that answers and automatically hangs up:
from pyVoIP.VoIP import VoIPPhone, InvalidStateError
def answer(call):
try:
call.answer()
call.hangup()
except InvalidStateError:
pass
if __name__=='__main__':
phone=VoIPPhone(<SIP Server IP>, <SIP Server Port>, <SIP Server Username>, <SIP Server Password>, callCallback=answer, myIP=<Your computer's local IP>)
phone.start()
input('Press enter to disable the phone')
phone.stop()
Announcement Board¶
Let’s say you want to make a phone that when you call it, it plays an announcement message, then hangs up. We can accomplish this with the builtin libraries wave, audioop, time and by importing CallState.
from pyVoIP.VoIP import VoIPPhone, InvalidStateError, CallState
import audioop
import time
import wave
def answer(call):
try:
f=wave.open('announcment.wav', 'rb')
frames = f.getnframes()
data = f.readframes(frames)
f.close()
call.answer()
call.writeAudio(data) #This writes the audio data to the transmit buffer, this must be bytes.
stop = time.time()+(frames/8000) #The number of frames/8000 is the length of the audio in seconds.
while time.time() <= stop and call.state == CallState.ANSWERED:
time.sleep(1)
call.hangup()
except InvalidStateError:
pass
except:
call.hangup()
if __name__=='__main__':
phone=VoIPPhone(<SIP Server IP>, <SIP Server Port>, <SIP Server Username>, <SIP Server Password>, callCallback=answer, myIP=<Your computers local IP>)
phone.start()
input('Press enter to disable the phone')
phone.stop()
Something important to note is our wait function. We are currently using:
stop = time.time()+(frames/8000) #The number of frames/8000 is the length of the audio in seconds.
while time.time() <= stop and call.state == CallState.ANSWERED:
time.sleep(1)
This could be replaced with time.sleep(frames/8000)
. However, doing so will not cause the thread to automatically close if the user hangs up, or if VoIPPhone().stop()
is called; using the while loop method will fix this issue. The time.sleep(1)
inside the while loop is also important. Supplementing time.sleep(1)
for pass
will cause your CPU to ramp up while running the loop, making the RTP (audio being sent out) lag. This can make the voice audibly slow or choppy.
Note: Audio must be in 8 bit, 8000Hz, and Mono/1 channel. You can accomplish this in a free program called Audacity. To make an audio recording Mono, go to Tracks > Mix > Mix Stereo Down to Mono. To make an audio recording 8000 Hz, go to Tracks > Resample… and select 8000, then ensure that your ‘Project Rate’ in the bottom left is also set to 8000. To make an audio recording 8 bit, go to File > Export > Export as WAV, then change ‘Save as type:’ to ‘Other uncompressed files’, then set ‘Header:’ to ‘WAV (Microsoft)’, then set the ‘Encoding:’ to ‘Unsigned 8-bit PCM’