Welcome to Shane’s World – Installment II

Leveraging the full power of the Call.Play API

Nov 15, 2019

By Shane Bryldt, Senior Software Engineer

Hello world! My name is Shane Bryldt and I am a Senior Software Engineer here at SignalWire. As a developer, I have made it my mission to explain everything that SignalWire can do, provide examples, and give the community my pro tips on how to leverage some of the more obscure options you can set. In my first Installment, I talked about RELAY and covered the calling.DialPhone API, Calling.NewPhoneCall, Call.DIal, and Call.Hangup. You can read all of that that right here!

The Feature Dive

Today we are going to continue down the road into the RELAY SDK, and talk about some of the exciting API's we have to offer. We will cover the Call.Play API and its helpers, Call.PlayAudio, Call.PlayTTS, Call.PlaySilence, and Call.PlayRingtone. We will also cover Call.Record.

Here are the links to the documentation, please review these for relevant information:

Let's start with the same example code that we used in installment 1 and then I will discuss what the code is doing.

The first thing we should take note of, is that not much has changed in the example since the last installment. In fact, the only thing that we have added is the operation to play something to the call. This shows that the initial example was really a skeleton template for most applications. We see once again that there are helper methods like PlayTTS that wrap calling the more complicated Play method.

*Advanced Note: When using the Play method, there is the ability to pass a list of different media to be played. These will be played in series, one after the other, until all are completed. Consider playing silence when you need a little gap between playing other media. 

There are currently 4 helper methods that can be used to send only 1 media more conveniently. These are PlayAudio, PlayTTS, PlaySilence, and as of SDK 2.3 we now have PlayRingtone. The first allows you to play an audio file from an arbitrary Url which can be in WAV or MP3 format. The second allows you to play Text To Speech. The default parameters are a female voice in en-US but you can change both the language and gender. The third allows for playing silence for some duration in seconds. The last allows for playing different regional ringtones using a predefined set of strings and a duration for it to play. As of SDK release 2.3, all of the Play operations also have an additional optional volume parameter which can be used to alter the volume for the duration of the media being played. This volume parameter ranges from -40dB to +40dB where 0dB represents no change to the volume. Also included in SDK release 2.3, is the ability to activate multiple play operations at once, this would require the use of the non-blocking Async version of the Play operations but is now possible.

Next we will cover the Record API, which can be a little more confusing with extra options that need to be understood to use this API effectively. Let's look at another piece of example code. 

There are a number of parameters involved in setting up a Record operation, but there are sane defaults for most cases. In the example above, we have initiated recording of audio based on the defaults of recording to an MP3 file, in mono, and only what the caller speaks. The defaults impose a 5 second timeout with the InitialTimeout parameter that means it'll wait up to 5 seconds to detect audio and start recording before it'll fail with a no_input error. Additionally, the EndSilenceTimeout is defaulted to 1 second for the duration which the recording will continue to record after silence is heard. The other parameters are rather self explanatory allowing you to control if you want the recording in MP3 or WAV format, whether or not to include a beep in the recording, whether you want the recording in stereo, and what channels of audio you want to capture (speak, listen, or both). The Terminators parameter offers a way to use DTMF input tones to end the recording prematurely.

When a recording is completed, the url, size, and duration are available in the RecordResult thanks to the final events. However, as of SDK release 2.3 the URL is available in the RecordAction when doing a RecordAsync as soon as the response is received, before the recording is completed. However, the URL will point to an incomplete file until the recording has been completed.

*Advanced Note: In the example we used the blocking API for Record, this would cause the call to block until the recording has finished or errored out. A useful pattern is to sometimes use the `RecordAsync` API with both timeouts set to 0 to disable them. This pattern allows you to start a recording in the background and have it automatically end when a call is hung up.

Thank you for reading this article and I hope you find it helpful. The best way to learn about SignalWire is to tinker around with it, so sign up now to receive $5 in free credit and try it out yourself. You can also join us on our community Slack channel, where you can ask me any questions that you have about SignalWire. Stay tuned as we dive down the rabbit hole together into more of SignalWire, on the next installment of Shane’s World!