Ozeki VoIP SDK - Product Guide
Did you know?
This SDK was used to build:Ozeki Phone System XE - VoIP PBX Software for Developers Which is a high performance PBX system supporting Mobile and Desktop phones.
It was also used to create Ozeki 3D VoIP softphone. A cool SIP client that allows 3D Video calls.
How to record a voice call?
![]() |
Download: | Record_Voice_Call.zip |
This article is a detailed guide about recording voice calls
in relation with Ozeki VoIP SIP SDK. After reading through this page you
will be fully familiar with all the essential terms concerning voice call recording
and what you will need for creating your own solution using Ozeki VoIP SIP SDK.
To use this example, you need to have Ozeki VoIP SIP SDK installed,
and a reference to ozeki.dll should be added to your visual studio project.
It's also recommended to study the How to accept incoming call
and the How to make a SIP voice call articles.
What is voice recording? What does it used for?
In Voice over IP model the communication is made through the Internet Protocol and the data that is sent between the two end points is digitized. This data can be recorded and saved in audio files if needed (Figure 1).
VoIP phone calls allow voice call recording in more than one ways. You can record only one of the clients' voice, or record both into separate files or even record them into one mixed file. This last solution makes the most sense, so the example will implement this case.
How to implement voice recording using C#?
The call recording is an easy task with Ozeki VoIP SIP SDK even if you need to record both the incoming and the outgoing voices. You only need to extend your softphone application with some extra tools and the recording can be done automatically when you enter into a call.
You can record audio streams into .wav audio files, and for this purpose you will need a WaveStreamRecorder media handler object. If you want to record both parties' voice in one file, you will also need an AudioMixerMediaHandler that will mix the incoming and the outgoing voices. The two extra strings are used for the .wav file name during the recording. The filename specifies the .wav file's name that will be the parameter for the recorder's constructor.
The recording needs to be established when the call is being answered. In this case the recorder needs to be initialized with the filename that will consist of the caller (as string) and the hour, minute and second information of the current time. This file naming convention is necessary for securing the unique file names (per day), as you do not want to overwrite the recorded files.
You need to connect the microphone and the mediaReceiver objects to the mixer. This will ensure that the two audio streams will be mixed. Then you need to connect the mixer to the recorder that will record the mixed audio stream into the file specified by the filename parameter.
The following example will demonstrate how to store an incoming call as wav file. The softphone records both parties' voice, so you can also see how to use a mixer object.
C# | VB.NET |
using System; using Ozeki.Media; using Ozeki.VoIP; namespace Record_Voice_Call { class Program { static ISoftPhone softphone; // softphone object static IPhoneLine phoneLine; // phoneline object static IPhoneCall call; static string caller; static string filename; static Microphone microphone; static Speaker speaker; static PhoneCallAudioSender mediaSender; static PhoneCallAudioReceiver mediaReceiver; static MediaConnector connector; static WaveStreamRecorder recorder; static void Main(string[] args) { // Create a softphone object with RTP port range 5000-10000 softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000); // SIP account registration data, (supplied by your VoIP service provider) var registrationRequired = true; var userName = "858"; var displayName = "858"; var authenticationId = "858"; var registerPassword = "858"; var domainHost = "192.168.115.100"; var domainPort = 5060; var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort); // Send SIP regitration request RegisterAccount(account); microphone = Microphone.GetDefaultDevice(); speaker = Speaker.GetDefaultDevice(); mediaSender = new PhoneCallAudioSender(); mediaReceiver = new PhoneCallAudioReceiver(); connector = new MediaConnector(); // Prevents the termination of the application Console.ReadLine(); } static void RegisterAccount(SIPAccount account) { try { phoneLine = softphone.CreatePhoneLine(account); phoneLine.RegistrationStateChanged += line_RegStateChanged; softphone.IncomingCall += softphone_IncomingCall; softphone.RegisterPhoneLine(phoneLine); } catch (Exception ex) { Console.WriteLine("Error during SIP registration: " + ex); } } static void line_RegStateChanged(object sender, RegistrationStateChangedArgs e) { if (e.State == RegState.NotRegistered || e.State == RegState.Error) Console.WriteLine("Registration failed!"); if (e.State == RegState.RegistrationSucceeded) Console.WriteLine("Registration succeeded - Online!"); } static void softphone_IncomingCall(object sender, VoIPEventArgse) { call = e.Item; caller = call.DialInfo.CallerID; call.CallStateChanged += call_CallStateChanged; call.Answer(); } static void call_CallStateChanged(object sender, CallStateChangedArgs e) { Console.WriteLine("Call state: {0}.", e.State); if (e.State == CallState.Answered) SetupDevices(); if (e.State.IsCallEnded()) CloseDevices(); } static void SetupDevices() { microphone.Start(); connector.Connect(microphone, mediaSender); speaker.Start(); connector.Connect(mediaReceiver, speaker); filename = string.Format("{0}-{1}-{2}-{3}.wav", caller, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second); // a string to generate file name recorder = new WaveStreamRecorder(filename); // new recorder object connector.Connect(microphone, recorder); // connects the outgoing voice to the recorder connector.Connect(mediaReceiver, recorder); // connects the incoming voice to the recorder mediaSender.AttachToCall(call); mediaReceiver.AttachToCall(call); recorder.Start(); // starts the recording } static void CloseDevices() { recorder.Dispose(); microphone.Dispose(); speaker.Dispose(); mediaReceiver.Detach(); mediaSender.Detach(); connector.Dispose(); } } }
Imports Ozeki.Media Imports Ozeki.VoIP Module OzekiVoIP Private softphone As ISoftPhone ' softphone object Private phoneLine As IPhoneLine ' phoneline object Private [call] As IPhoneCall Private caller As String Private filename As String Private microphone As Microphone Private speaker As Speaker Private mediaSender As PhoneCallAudioSender Private mediaReceiver As PhoneCallAudioReceiver Private connector As MediaConnector Private recorder As WaveStreamRecorder Sub Main() ' Create a softphone object with RTP port range 5000-10000 softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000) ' SIP account registration data, (supplied by your VoIP service provider) Dim registrationRequired = True Dim userName = "858" Dim displayName = "858" Dim authenticationId = "858" Dim registerPassword = "858" Dim domainHost = "192.168.115.100" Dim domainPort = 5060 Dim account = New SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort) ' Send SIP regitration request RegisterAccount(account) microphone = Microphone.GetDefaultDevice() speaker = Speaker.GetDefaultDevice() mediaSender = New PhoneCallAudioSender() mediaReceiver = New PhoneCallAudioReceiver() connector = New MediaConnector() ' Prevents the termination of the application Console.ReadLine() End Sub Private Sub RegisterAccount(ByVal account As SIPAccount) Try phoneLine = softphone.CreatePhoneLine(account) AddHandler phoneLine.RegistrationStateChanged, AddressOf line_RegStateChanged AddHandler softphone.IncomingCall, AddressOf softphone_IncomingCall softphone.RegisterPhoneLine(phoneLine) Catch ex As Exception Console.WriteLine("Error during SIP registration: " & ex.Message) End Try End Sub Private Sub line_RegStateChanged(ByVal sender As Object, ByVal e As RegistrationStateChangedArgs) If e.State = RegState.NotRegistered OrElse e.State = RegState.Error Then Console.WriteLine("Registration failed!") End If If e.State = RegState.RegistrationSucceeded Then Console.WriteLine("Registration succeeded - Online!") End If End Sub Private Sub softphone_IncomingCall(ByVal sender As Object, ByVal e As VoIPEventArgs(Of IPhoneCall)) [call] = e.Item caller = [call].DialInfo.CallerID AddHandler [call].CallStateChanged, AddressOf call_CallStateChanged [call].Answer() End Sub Private Sub call_CallStateChanged(ByVal sender As Object, ByVal e As CallStateChangedArgs) Console.WriteLine("Call state: {0}.", e.State) If e.State = CallState.Answered Then SetupDevices() End If If e.State.IsCallEnded() Then CloseDevices() End If End Sub Private Sub SetupDevices() microphone.Start() connector.Connect(microphone, mediaSender) speaker.Start() connector.Connect(mediaReceiver, speaker) filename = String.Format("{0}-{1}-{2}-{3}.wav", caller, Date.Now.Hour, Date.Now.Minute, Date.Now.Second) ' a string to generate file name recorder = New WaveStreamRecorder(filename) ' new recorder object connector.Connect(microphone, recorder) ' connects the outgoing voice to the recorder connector.Connect(mediaReceiver, recorder) ' connects the incoming voice to the recorder mediaSender.AttachToCall([call]) mediaReceiver.AttachToCall([call]) recorder.Start() ' starts the recording End Sub Private Sub CloseDevices() recorder.Dispose() microphone.Dispose() speaker.Dispose() mediaReceiver.Detach() mediaSender.Detach() connector.Dispose() End Sub End Module
This example program briefly demonstrated how you can record a voice call by mixing the incoming and outgoing voices together. You can use this code to extend your softphone applications with voice recording support or you can invent it further the way you want to use voice recording.
Training guides, simple examples
If you would like to visit the detailed developer documentations, you can learn much more from the Ozeki VoIP SIP SDK Training chapter.
If you have any questions or need assistance, please contact us at info@voip-sip-sdk.com
Related Pages
BEGINNER
Getting started
Downloading VoIP SIP SDK
Installation steps
PBX configuration
Examples with source code
INTERMEDIATE
VoIP technology walkthrough
SIP softphone development
Webphone development
Mobile development
Voice recording
GETTING AROUND
Sitemap
Search the manual
API documentation
FAQ
Acknowledgements