Record the voice of the Caller
By studying the following article, you can learn how to record the
voice of the caller and how to play it back.
First of all, please install an
API Extension and subscribe to
Incoming Call URL
with the URL of your application.
Learn how to record the voice of the caller and how to play it back.
First of all, please login and connect to the API Extension.
Wait for an Incoming call, and when it is occured just attach a WaveStreamRecorder object into the call and start it.
Example code coming soon...
[HttpPost] public ActionResult RecordCall(string notificationName, string callLegID, string caller, string apiExtension) { return Content( "<Response>" + "<UserInput timeout=\"10\" repeat=\"true\">" + "<InitialCommands>" + "<Speak>Hello.</Speak> " + "<Speak>To record your own voice, please press 1.</Speak>" + "<Speak>To hang up the line, please press 2.</Speak>" + "</InitialCommands>" + "<Inputs>" + "<Input key=\"1\">" + "<Speak>Press 9 for stop recording! Recording start now:</Speak>" + "<Record finishedUrl=\"http://yoursite.com/Home/RecordFinished\" FinishDigits=\"9\"/>" + "</Input>" + "<Input key=\"2\">" + "<Speak>Good bye!</Speak>" + "<Hangup></Hangup>" + "</Input>" + "</Inputs>" + "</UserInput>" + "</Response>", "text/xml"); }
class RecordCallController < ApplicationController protect_from_forgery except: :index # In routes.rb you need to set the following routing rule # post '/record_call' => 'record_call#index' def index render :xml => '<?xml version="1.0" encoding="UTF-8"?> <Response> <UserInput timeout="10" repeat="true"> <InitialCommands> <Speak>Hello.</Speak> <Speak>To record your own voice, please press 1.</Speak> <Speak>To hang up the line, please press 2.</Speak> </InitialCommands> <Inputs> <Input key="1"> <Speak>Press 9 for stop recording! Recording start now:</Speak> <Record finishedUrl="http://yoursite.com:3000/record_finished" FinishDigits="9"/> </Input> <Input key="2"> <Speak>Good bye!</Speak> <Hangup></Hangup> </Input> </Inputs> </UserInput> </Response>' end end
<?php print "<Response>"; print "<UserInput timeout=\"10\" repeat=\"true\">"; print "<InitialCommands>"; print "<Speak>Hello.</Speak>"; print "<Speak>To record your own voice, please press 1.</Speak>"; print "<Speak>To hang up the line, please press 2.</Speak>"; print "</InitialCommands>"; print "<Inputs>"; print "<Input key=\"1\">"; print "<Speak>"; print "Press 9 for stop recording! Recording start now:"; print "</Speak>"; print "<Record finishedUrl=\"http://yoursite.com/RecordFinished.php\" FinishDigits=\"9\"/>"; print "</Input>"; print "<Input key=\"2\">"; print "<Speak>Good bye!</Speak>"; print "<Hangup></Hangup>"; print "</Input>"; print "</Inputs>"; print "</UserInput>"; print "</Response>"; ?>
using System; using OPSSDK; using OPSSDKCommon.Model.Call; using Ozeki.Media.MediaHandlers; using Ozeki.VoIP; namespace OPS_QuickStartExample_CSharp { class Program { static void Main(string[] args) { var client = new OpsClient(); client.ErrorOccurred += (sender, info) => Console.WriteLine(info.Message); if (!client.Login("ozekixepbx.ip", "admin", "12345")) return; var apiExtension = client.GetAPIExtension("9000"); apiExtension.IncomingCall += IncomingCall; Console.ReadLine(); } private static void IncomingCall(object sender, VoIPEventArgse) { var call = e.Item; var lastRecordedFilePath = "c://" + Guid.NewGuid() + ".wav"; WaveStreamRecorder recorder = null; WaveStreamPlayback player = null; var tts = new TextToSpeech(); call.ConnectAudioSender(tts); call.DtmfReceived += (s, ev) => { if (ev.Item.Signal == DtmfNamedEvents.Dtmf1) { if (tts == null) return; tts.Dispose(); tts = null; recorder = new WaveStreamRecorder(lastRecordedFilePath); call.ConnectAudioReceiver(recorder); recorder.StartStreaming(); } else if (ev.Item.Signal == DtmfNamedEvents.Dtmf9) { if (recorder == null) return; recorder.Dispose(); recorder = null; player = new WaveStreamPlayback(lastRecordedFilePath); call.ConnectAudioSender(player); player.StartStreaming(); player.Stopped += (sen, eve) => call.HangUp(); } }; call.CallStateChanged += (s, ev) => { if (ev.Item == CallState.Answered) tts.AddAndStartText("To record your own voice, please press 1. " + "Press 9 for stop recording!"); else if (ev.Item.IsCallEnded()) { if (recorder != null) recorder.Dispose(); if (tts != null) tts.Dispose(); if (player != null) player.Dispose(); } }; call.Accept(); } } }
#!c:/Perl64/bin/perl.exe print "Content-Type: text/plain\n\n"; #You have to add the directory route of perl.exe, and print the content type #Send response by print print '<?xml version="1.0" encoding="UTF-8"?> <Response> <UserInput timeout="10" repeat="true"> <InitialCommands> <Speak>Hello.</Speak> <Speak>To record your own voice, please press 1.</Speak> <Speak>To hang up the line, please press 2.</Speak> </InitialCommands> <Inputs> <Input key="1"> <Speak>Press 9 for stop recording! Recording start now:</Speak> <Record finishedUrl="http://yoursite.com/RecordFinished.pl" FinishDigits="9"/> </Input> <Input key="2"> <Speak>Good bye!</Speak> <Hangup></Hangup> </Input> </Inputs> </UserInput> </Response>'
Imports Ozeki.Media.MediaHandlers Imports OPSSDKCommon.Model.Call Imports OPSSDK Imports Ozeki.VoIP Module Module1 Public Sub Main(args As String()) Dim client = New OpsClient() AddHandler client.ErrorOccurred, Sub(sender, info) Console.WriteLine(info.Message) End Sub If Not client.Login("ozekixepbx.ip", "admin", "12345") Then Return End If Dim apiExtension = client.GetAPIExtension("9000") AddHandler apiExtension.IncomingCall, AddressOf IncomingCall Console.ReadLine() End Sub Private Sub IncomingCall(sender As Object, e As VoIPEventArgs(Of ICall)) Dim [call] = e.Item Dim lastRecordedFilePath = "c://" & Guid.NewGuid().ToString() & ".wav" Dim recorder As WaveStreamRecorder = Nothing Dim player As WaveStreamPlayback = Nothing Dim tts = New TextToSpeech() [call].ConnectAudioSender(tts) AddHandler [call].DtmfReceived, Sub(s, ev) If ev.Item.Signal = DtmfNamedEvents.Dtmf1 Then If tts Is Nothing Then Return End If tts.Dispose() tts = Nothing recorder = New WaveStreamRecorder(lastRecordedFilePath) [call].ConnectAudioReceiver(recorder) recorder.StartStreaming() ElseIf ev.Item.Signal = DtmfNamedEvents.Dtmf9 Then If recorder Is Nothing Then Return End If recorder.Dispose() recorder = Nothing player = New WaveStreamPlayback(lastRecordedFilePath) [call].ConnectAudioSender(player) player.StartStreaming() AddHandler player.Stopped, Sub(sen, eve) [call].HangUp() End Sub End If End Sub AddHandler [call].CallStateChanged, Sub(s, ev) If ev.Item = CallState.Answered Then tts.AddAndStartText("To record your own voice, please press 1. " & "Press 9 for stop recording!") ElseIf ev.Item.IsCallEnded() Then If recorder IsNot Nothing Then recorder.Dispose() End If If tts IsNot Nothing Then tts.Dispose() End If If player IsNot Nothing Then player.Dispose() End If End If End Sub [call].Accept() End Sub End Module
import urllib.parse import datetime from cgi import escape def application(environ, start_response): if(environ["PATH_INFO"] == ''): result = receiveCall(environ) elif(environ["PATH_INFO"] == '/RecordFinished'): result = recordFinished(environ) response_headers = [('Content-type', 'text/plain'), ('Content-Length', str(len(result)))] start_response('200 OK', response_headers) return [result] def receiveCall(environ): return """<?xml version="1.0" encoding="UTF-8"?> <Response> <UserInput timeout="10" repeat="true"> <InitialCommands> <Speak>Hello.</Speak> <Speak>To record your own voice, please press 1.</Speak> <Speak>To hang up the line, please press 2.</Speak> </InitialCommands> <Inputs> <Input key="1"> <Speak>Press 9 for stop recording! Recording start now:</Speak> <Record finishedUrl="{0}" FinishDigits="9"/> </Input> <Input key="2"> <Speak>Good bye!</Speak> <Hangup></Hangup> </Input> </Inputs> </UserInput> </Response>""".format("http://yoursite.com/RecordFinished")
package pbxsampleapp; import com.sun.net.httpserver.*; import java.io.*; import java.net.*; import java.util.*; public class RecordCall { public static void main(String[] args) { try { System.out.println("Starting http server..."); HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getByAddress(new byte[] { 0, 0, 0, 0 }), 12345), 0); server.createContext("/callrecoding", new PbxSampleApp.PBXRequestHandler()); server.start(); System.out.println("http server running on " + server.getAddress().toString()); } catch (IOException ex) { System.out.println("Error" + ex.toString()); } } static class PBXRequestHandler implements HttpHandler { @Override public void handle(HttpExchange httpExchange) throws IOException { Map parameters = parseQuery(httpExchange.getRequestURI().getQuery()); String response = GetResponse(parameters); httpExchange.getResponseHeaders().add("Content-type", "text/xml"); if (response.length()==0) httpExchange.sendResponseHeaders(404, response.length()); else httpExchange.sendResponseHeaders(200, response.length()); OutputStream os = httpExchange.getResponseBody(); os.write(response.getBytes()); os.close(); } private String GetResponse(Map queryparams) { if (queryparams.containsKey("action")) { switch (queryparams.get("action").toString()) { case "RecordCall": return getRecordCallOzML(queryparams); case "RecordFinished": return getRecordFinishedOzMl(queryparams); } } return ""; } private String getRecordCallOzML(Map queryparams) { return "<?xml version=\"1.0\"?>" + "<Response>" + "<UserInput timeout=\"10\" repeat=\"true\">" + "<InitialCommands>" + "<Speak>Hello.</Speak> " + "<Speak>To record your own voice, please press 1.</Speak>" + "<Speak>To hang up the line, please press 2.</Speak>" + "</InitialCommands>" + "<Inputs>" + "<Input key=\"1\">" + "<Speak>Press 9 for stop recording! Recording start now:</Speak>" + "<Record finishedUrl=\"http://yoursite.com/callrecoding?action=RecordFinished\" FinishDigits=\"9\"/>" + "</Input>" + "<Input key=\"2\">" + "<Speak>Good bye!</Speak>" + "<Hangup></Hangup>" + "</Input>" + "</Inputs>" + "</UserInput>" + "</Response>"; } private Map<String, String> parseQuery(String params) throws UnsupportedEncodingException { Map<String, String> query_pairs = new LinkedHashMap<String, String>(); String[] pairs = params.split("&"); String paramname; String value; for (String pair : pairs) { int idx = pair.indexOf("="); paramname = pair.substring(0, idx); value = pair.substring(idx + 1); query_pairs.put(paramname, value); System.out.println(String.format("%s: %s", paramname, value)); } return query_pairs; } } }
Code example 1
- Recording the voice of the Caller by pressing button
IN MORE DETAILS
Get the OPSSDK.dll
First you need to add the OPSSDK.dll reference to your project
(You can find OPSSDK.dll at C:\Program Files\Ozeki\Ozeki Phone System\Examples.NET API\OPSSDK.dll).
Login and connect
Create a new instance of OpsClient, and subscribe to the ErrorOccurred event. Your program will communicate with the Ozeki Phone System through this client. Try to login with the client into the running Ozeki Phone System, with the address of the server(ozekixepbx.ip) and a valid username, password combination.
If you are ready, try to get an existing API Extension, with the GetApiExtension method of the OpsClient. Read more about installation of API Extension.
Further steps
When you are ready with the initial steps above, subscribe the IncomingCall event of the apiExtension. This event will be triggered every time when the selected API Extension is called. In the mentioned event handler you will see the e.Item parameter, this parameter will be the call object. This call object has a CallState property, when the CallState is Ringing subscribe the CallStateChanged and the DtmfReceived events of the call object and Accept the call.
The CallStateChanged event will trigger when the call is going to another state . When the CallState is Answered, you can connect the devices to the call. When the call has ended, please do not forget to disconnect all devices from the call.
When the CallState is Answered, start and connect a TextToSpeech object to the call, that will read to the caller the "To record your own voice, please press 1. Press 9 for stop recording!! When button 1 is pressed the program will start and connect a WaveStreamRecorder object to the call. This object will record the caller's voice into a file (what you can give). When the caller press button 9 what will stop the recording, and start a WaveStreamPlayback to play back the recorded voice to the caller.
With these steps, you learnt how to receive an incoming call, record the caller's voice and play back it to him/her.
At the beginning of the call, the caller is asked, whether he accept the Call Recording or not.
If the Caller presses the 1 button, the call recording is started by Record command.
Else if the pressed button is 2 then the call will hang up by the Hangup command.
When the record is finished (by HangUp, or pressing the 9 button),
an HTTP Request will be sent
to the specified finishedUrl URL with the help of the API Extension.
Please change the yoursite.com text to that ip address where the
sample applications are running. At this URL you can add more commands as
response, for example playing back his own voice to the Caller.
Write this code to the file at the given finishedUrl URL:
Write this code to the file at the given finishedUrl URL:
IN MORE DETAILS
Get the OPSSDK.dll
First you need to add the OPSSDK.dll reference to your project
(You can find OPSSDK.dll at C:\Program Files\Ozeki\Ozeki Phone System\Examples.NET API\OPSSDK.dll).
Login and connect
Create a new instance of OpsClient, and subscribe to the ErrorOccurred event. Your program will communicate with the Ozeki Phone System through this client. Try to login with the client into the running Ozeki Phone System, with the address of the server(ozekixepbx.ip) and a valid username, password combination.
If you are ready, try to get an existing API Extension, with the GetApiExtension method of the OpsClient. Read more about installation of API Extension.
Further steps
When you are ready with the initial steps above, subscribe the IncomingCall event of the apiExtension. This event will be triggered every time when the selected API Extension is called. In the mentioned event handler you will see the e.Item parameter, this parameter will be the call object. This call object has a CallState property, when the CallState is Ringing subscribe the CallStateChanged and the DtmfReceived events of the call object and Accept the call.
The CallStateChanged event will trigger when the call is going to another state . When the CallState is Answered, you can connect the devices to the call. When the call has ended, please do not forget to disconnect all devices from the call.
When the CallState is Answered, start and connect a TextToSpeech object to the call, that will read to the caller the "To record your own voice, please press 1. Press 9 for stop recording!! When button 1 is pressed the program will start and connect a WaveStreamRecorder object to the call. This object will record the caller's voice into a file (what you can give). When the caller press button 9 what will stop the recording, and start a WaveStreamPlayback to play back the recorded voice to the caller.
With these steps, you learnt how to receive an incoming call, record the caller's voice and play back it to him/her.
Example code coming soon...
[HttpPost] public ActionResult RecordFinished(string success, string duration, string recordURL, string callId, string caller, string callee, string notificationName) { return Content( "<Response>" + "<Speak>Recorded voice:</Speak>" + "<Play Repeat=\"false\">" + recordURL + "</Play>" + "<Speak>Good bye!</Speak>" + "</Response>", "text/xml"); }
class RecordFinishedController < ApplicationController protect_from_forgery except: :index # In routes.rb you need to set the following routing rule # post '/record_finished' => 'record_finished#index' # http://yoursite.com:3000/record_finished def index render :xml => '<?xml version="1.0" encoding="UTF-8"?> <Response> <Speak>Recorded voice:</Speak> <Play>' + params['RecordURL'] + '</Play> <Speak>Good bye!</Speak> </Response>' end end
<?php print "<Response>"; print "<Speak>Recorded voice:</Speak>"; print "<Play>".$_REQUEST['RecordURL']."</Play>"; print "<Speak>Good bye!</Speak>"; print "</Response>"; ?>
#!c:/Perl64/bin/perl.exe print "Content-Type: text/plain\n\n"; #You have to add the directory route of perl.exe, and print the content type use CGI qw(:cgi-lib :standard); # Use CGI modules that let read data passed &ReadParse(%in); #Read in from HTTPPost parameters #Send response by print print '<?xml version="1.0" encoding="UTF-8"?> <Response> <Speak>Recorded voice:</Speak> <Play>'. $in{'RecordURL'} .'</Play> <Speak>Good bye!</Speak> </Response>'
def recordFinished(environ): try: length= int(environ.get('CONTENT_LENGTH', '0')) if(length != 0): body = environ['wsgi.input'].read(length) receivedData = urllib.parse.parse_qs(body.decode("utf-8")) recordURL = escape(receivedData['RecordURL'][0]) return """<?xml version="1.0" encoding="UTF-8"?> <Response> <Speak>Recorded voice:</Speak> <Play>{}</Play> <Speak>Good bye!</Speak> </Response>""".format(recordURL) except IOError: return ""
private String getRecordFinishedOzMl(Map queryparams) { return "<Response>" + "<Speak>Recorded voice:</Speak>" + "<Play Repeat=\"false\">" + queryparams.get("recordurl").toString() + "</Play>" + "<Speak>Good bye!</Speak>" + "</Response>"; }
Code example 2
- Handling the finishing of the CallRecord
When the sent HTTP Request is arrived, the parameters of this request are
processed into a variable. The important parameter now is the RecordUrl.
You can execute the Play command, with this parameter. With that command
in the response, the caller will hear his own recorded voice.
Next: Transfer Call
More information
- Greet Caller by Name in PHP
- Greet Caller by Name in C#.net
- Greet Caller by Name in Ruby
- Greet Caller by Name in VB
- Greet Caller by Name in ASP.net
- Greet Caller by Name in Perl
- How to record the voice of the Caller with Ozeki Phone System VoIP PBX
- How to transfer a call to another phone with Ozeki Phone System
- Greet Caller by Name in Python
- Greet Caller by Name in Java