Switchvox Developer Blog

Browse Call Recordings with iTunes Cover Flow

Author: dblood
Article posted on January 4th, 2012

This tutorial will show you how to convert your call recordings into MP3 files, complete with meta data and cover art, and browse them with Cover Flow in iTunes on a Mac.  Along the way, you’ll also learn about call recordings and making Switchvox API calls with Perl.

Let’s say you are a call queue administrator.  You have 5 people working for you, answering calls in the queue.  You want to be able to easily and quickly review a days worth of calls and determine how everyone is doing.  You want to see, roughly, how may calls each person is taking, how long they are, and listen to a few for quality assurance.

You could do all this with a slick interface if you had each call as an MP3 file in iTunes.  So, let’s do it.

You will need a Linux server running FTP and Samba.  I assume you already know how to set this up, but if not, there are some great resources on the web.

  • For my FTP server, I use ProFTPD.  It’s included with Fedora and most other Linux distributions. http://proftpd.org
  • Samba is a great project that allows you to share files from a Linux server on a Windows network.  Apple and Linux clients also support Windows file sharing.  Samba is also included in most Linux distributions, as well as handy GUI tools to set it up.  http://www.samba.org/
  • To process the call recordings to MP3 files, we will use the open source, command line MP3 encoder called Lame. This is also included in many Linux distributions, but it is often not installed by default.  Please note, to be safe, you should have a company license to use MP3 encoding. http://lame.sourceforge.net/

OK, now that those requirements are out of the way, let’s get started!

Step 1: Setting Up Switchvox
First, let’s set up the call recordings.  Switchvox enables you to backup call recordings to an FTP server, then deletes them from the Switchvox PBX.  We will first enter our FTP server settings, then enable call recording for all calls in our call queue.

In the Switchvox Admin interface, click on “Tools -> Call Recording”.  Then click on “Modify Recording Settings”.  Enter the FTP Hostname, FTP Username, FTP Password and FTP Path, if needed.  Click on “Test FTP Settings”.  A new window will open, and if your entered everything correctly, all five tests should be marked with a green “Passed”.  If not, correct any errors and test again.  When you are finished, click “Save Settings”


Now, click “Create Call Recording”.  At the top of the page, enter a label in the box next to “Call Recording Label”.  This string will be turned into a directory name on your FTP server, and all calls recorded with this recording rule will be placed in that directory.  I labeled mine “Queue Calls”.  Next, in the “Recording Targets” box, click “Call Queues”, and click on the queue(s) you want to record.


Scroll down to “Call Recording Limit” and set a limit.  I chose “Until the date/time” and chose a date 1 year from today.  Then, under “How Long to Keep Recordings”, click “Backup and then delete calls after” and change to 10 to 1.


Click “Save Call Recording” and we’re done with this part.  Now, all calls in the queues you specified will be backed up every 15 minutes to the FTP server specified in the previous step.

Step 2: Processing the Call Recordings
OK, so far so good.  All of our queue calls are getting recorded and then backed up on our FTP server.  Mine are going into the directory “/home/call_recordings/Queue_Calls”.  We now need to take these recordings, which are WAV files, and convert them in MP3 files with cover art and metadata.  To do this, we’ll use a Perl script and the Lame MP3 encoder.

The Perl script needs to do several things:

  • Parse the XML file associated with each call recording to get the data about the call.
  • Use that data to get a profile image from the Switchvox PBX.
  • Make an MP3 file for each call recording, and place it in a directory shared via Samba.
  • Keep track of what it’s already done, so it doesn’t process a file multiple times.

To accomplish this, we’ll use the following CPAN modules:


First, let’s define some global variables that tell the rest of the code where to find things:

my $SOURCE_DIR = '/home/call_recordings/Queue_Calls';
my $DESTINATION_DIR = '/home/dblood/call_recordings';
my $PBX_HOSTNAME = '';
my $PBX_LOGIN = 'admin';
my $PBX_PASSWORD = 'admin';
my $DATA_DIR = '/home/call_recordings';

$SOURCE_DIR is the directory on the server where the call recordings are backed up.
$DESTINATION_DIR is the shared Samba directory where the MP3 file will go.
$DATA_DIR is where the file that holds our history data will be kept.
$PBX_* are the specifics of your Switchvox PBX.

Next, we have the main steps:

my %already_done = load_history();
my @processed;

File::Find::find(\&process, ($SOURCE_DIR));


First we load the history.  This is all the filenames we’ve already processed, so we don’t process them again.  They are saved in a text file, one filename per line.  We load them into a hash for easy look up.

Next, we use File::Find to process every file in the $SOURCE_DIR.  For each file, it calls the subroutine process() with the filename.

Finally, we add the list of processed files to out history.

The important part here is the processing of files.  Let’s take a look at that.

sub process {

	my $filename = $_;

	if ($filename !~ /.xml$/) {

	if ($already_done{$filename}) {

	my $wav_file = $filename;
	$wav_file =~ s/\.xml$/\.wav/;
	$wav_file = $File::Find::dir . "/" . $wav_file;

	# is the wav file here?
	if (! -e $wav_file) {
		print STDERR "$wav_file is missing - skipping\n";

	print "processing $filename\n";

	my $data = XML::Simple::XMLin($File::Find::name, ForceArray => 0, KeyAttr => '' );

	my $call_id = $data->{recorded_call_id};
	my $name = $call_id . ' - ' . $data->{to_caller_id} . " - " . $data->{from_caller_id};
	my $queue = $data->{recorded_cid};
	my $queue_member = $data->{to_caller_id};
	my $date =  $data->{date_created_ts};

	# get the image for the queue member
	my $image_filename = get_profile_image($data->{to_account_id});

	# set up the lame command & arguments
	my @command = ('lame', '--tt', $name, '--tl', $queue, '--ta', $queue_member, '--tc', "Date: $date", '--add-id3v2');

	# if we have an image, use it
	if (defined $image_filename) {
		push @command, '--ti';
		push @command, $image_filename;
	push @command, $wav_file;
	push @command, $DESTINATION_DIR . "/" . $queue . " - " . $name . ".mp3";

	# make the mp3 file

	push @processed, $filename;

Remember, this subroutine is called with the filename of every file in the $SOURCE_DIR directory.  That includes a WAV file and an XML file for each call recording.  We only want the XML files for now, so filter the WAV files out.  Also, don’t process any files we already processed in previous runs.

Next, we need to get the filename of the WAV file associated with the XML file we are proccessing.  They have the same name, but obviously the extension is different.  Also, we need the full path.  That is contained in the package variable $File::Find::dir.

After testing that the WAV file actually exists, we move on to extracting the metadata from the XML file.  We convert  the XML to a hash with XML::Simple::XMLin for easy access, then, for better readability, assign the data we are interested in to individual variables.  The XML looks like this:

  <recording_tag>Queue Calls</recording_tag>
  <recorded_cid>The Queue &lt;301&gt;</recorded_cid>
  <from_caller_id>858 765-9812</from_caller_id>
  <to_caller_id>James Smith &lt;103&gt;</to_caller_id>
  <date_created_ts>2011-10-20 14:18:18.819689</date_created_ts>

Next, we use the Switchvox API get the URL of the profile image for the queue member that took the call, and save it to disk.  I’ll explain this in more detail later.  Then we assemble the lame command line, and pass it to the Perl command “system” for execution.  Last, we push the filename we just just processed onto the @processed array to save to our history at the very end.

This is all everyday Perl stuff.  But how do we use the Switchvox API to get the profile image?  Switchvox::API is available from CPAN, and you can take a look at it here: http://search.cpan.org/~dwp/Switchvox-API-1.0/lib/Switchvox/API.pm

Here’s our get_profile_image subroutine:

sub get_profile_image {

	my ($account_id) = @_;

	my $api = new Switchvox::API(
								 hostname => $PBX_HOSTNAME,
								 username => $PBX_LOGIN,
								 password => $PBX_PASSWORD

	my $method = 'switchvox.extensions.getInfo';

	my $params = {
				  account_ids => {
								  account_id => [$account_id]

	my $response = $api->api_request(
									 method          => $method,
									 parameters      => $params

	my $filename;

	if ($response->{api_status} eq 'success') {
		my $response_data = XML::Simple::XMLin($response->content,  ForceArray => 0, KeyAttr => '' );

		if ($response_data && $response_data->{result} && $response_data->{result}->{extensions} &&
			$response_data->{result}->{extensions}->{extension}) {

			my $url = $response_data->{result}->{extensions}->{extension}->{profile_image_link};
			$filename = '/tmp/' . $account_id . '.jpg';
			system('wget', '-O', $filename,  '--no-check-certificate', $url);


	return $filename;

First, instantiate a Switchvox::API object with the hostname, username and password for your Switchvox PBX.  Next we define the method name, in this case “switchvox.extensions.getInfo”.  The documentation for this method can be found here: http://developers.digium.com/switchvox/wiki/index.php/Switchvox.extensions.getInfo

Then, we define the parameters.  In this case, we have the account ID, so we use that.  The Perl data structure:

  account_ids => {
                  account_id => [$account_id]

is equivalent to the XML


Next, we make the request, check for success, and then access the response hash key “profile_image_link”.  The best way to see what your dealing with in the response is to use Data::Dumper.  The code

print Dumper $response_data;

will print the response data structure to the terminal.  Don’t forget to “use Data::Dumper;” if you do this.

Finally, we need the profile image on disk.  To do this, we use wget.

After all this, we return the filename of the profile image on disk, or undef if we were unable to get one.

The final step in this section is to create a cron that will run our Perl script once or twice a day. I’ll leave that to the reader, but you can find some hints here: http://en.wikipedia.org/wiki/Cron

Step 3: Getting the MP3 Files into iTunes

Now we have an MP3 file for each call recording in the shared Samaba directory.  We just need to get these files into iTunes on our Mac.

iTunes is pretty picky about how it handles media.  It needs the media files to be stored locally.  We’ll use Automator to make an app that will import the files into iTunes from the mounted Samba directory.

First, lets make a playlist that will hold only the call recordings.  Open iTunes, and at the top click on “File” and then “New Playlist”.  A new playlist will apear on the bottom of the left panel, already highlighted.  Name this “Call Recordings”

Next, let’s mount the Samba directory from the server.  In Finder, click “Go -> Connect To Server”.  A list of servers will pop up.  Choose your Smaba server, and your Mac should connect.  If it goes well, a new Finder window will appear.

Now, let’s make a directory on your Mac where we can store the MP3 files. I made it in my home directory and called it “call_recordings”.

Next, let’s make the Automator app.

  • Open Finder, and click on “Applications” in the left panel.
  • Double click “Automator”
  • Make sure “Workflow” is highlighted in the top panel and click “Choose”
  • In the left hand column under “Library” select “Files and Folders”
  • In the next column double-click “Get Specified Finder items”
  • A “Get Specified Finder Items” pane should open on the main screen.
  • Click the “Add” button on this screen and select the Samba folder, in our case “dblood -> call_recordings”
  • Now from the second column from the left double-click on the “Get Folder Contents” action.
  • In the leftmost column click on “Files and Folders” then in the next column click on “Move Finder Items”
  • In this pane, in the first drop down, select “Other” and navigate to the directory you created on your Mac to store the MP3 files. Be sure to also check the box “Replace existing files”
  • Now on the left-most column click on “music” then in the next column dobule-click on “Import Files into iTunes”
  • In the first drop down, “Existing Playlist” should already be selected. In the second drop down, choose the playlist we created earlier, “Call Recordings”

Save it to your desktop, using “File -> Save”, and be sure to save it as File Format: Application.


Find the Automator app you just created, and run it.  It should import the mp3 files into iTunes, and open iTunes.  Click on the “Call Recordings” playlist, and choose “View -> as Cover Flow”.  Now you can easily browse and listen to your call recordings.


Anytime you want to browse new call recordings, just make sure the Samba share is mounted, and run the Automator app again.

Step 4: Additional Steps
My tutorial is done, but there are some further step you might want to take on your own:

  • Schedule the import into iTunes to happen automatically once per day.
  • Change the metadata we pass to Lame to make it more useful to your situation.

I’m sure you can think of many more. You can download the code from this tutorial here Enjoy!

One Response to “Browse Call Recordings with iTunes Cover Flow”

  1. Tourism says:


    [...]Digium - Switchvox Blog[...]…

Leave a Comment