How to Play an Audio Stream Into a Phone Call With Python
Published on March 13, 2023

There are various reasons you might want to play an audio stream into a call. An everyday use case is where developers want to put the caller on hold to help keep them relaxed, and you can play the music that gets their stress levels down.

Some example scenarios include:

  • Playing caller on-hold music.

  • Conference call - play music into a conference call until you have a quorum.

  • Pre Recorded message - useful where Vonage doesn't support your language in its Text-to-Speech engine.

  • Voicemail - when you call and leave a message, the voice message can be played back into a later call.

Below, you will see how to implement scenarios 1 and 2. The other scenarios will be covered in future blog posts.

There are also two methods for playing an audio stream into a call:

  1. Using a Call Control Object (NCCO)

  2. Using the Voice API (VAPI)

You will use method 1 for scenario 1, and method 2 for scenario 2.

Call Control Objects (NCCOs) provide a convenient way to control an inbound call. NCCOs consist of some JSON configuration that describes how to handle the Call. There is a detailed reference guide on NCCOs where the many actions that can be carried out are described. There is only one action we are interested in our scenarios, stream. There are actually two ways you can use the stream action: synchronous and asynchronous. Asynchronous means the caller can interrupt the audio stream using the phone keypad. There are some stream action options that are of interest:

Option Description

Syntax Description
streamUrl An array containing a single URL to an MP3 or WAV (16-bit) audio file to stream to the Call or Conversation.
level Set the audio level of the stream in the range -1 >=level<=1 with a precision of 0.1. The default value is 0.
bargeIn If set to true, this action is terminated when the user presses a button on the keypad. Use this feature to enable users to choose an option without having to listen to the whole message in your Interactive Voice Response (IVR) system. If you set bargeIn to true on one more Stream actions then the next action in the NCCO stack must be an input action. The default value is false.
loop The Number of times audio is repeated before the Call is closed. The default value is 1. Set to 0 to loop infinitely.

An example Python NCCO for playing audio into a call:

[
  {
    "action": "stream",
    "streamUrl": ["https://acme.com/music/relaxing_music.mp3"]
  }
]

The audio file formats supported are MP3 and 16-bit WAV.

We've already developed a starter Vonage application to receive a call and play music into your Call using two scenarios. With the starter application, you need to add your credentials to the .env file and deploy the app using Github Codespaces. A codespace is a development environment that's hosted in the GitHub cloud. GitHub Codespaces are customizable on a per-project basis, and users can set the Linux-based operating system to use, forward commonly used ports, set environment variables, etc. Also, you can edit the starter application and experiment.

To get started: Fork this repository. Open it in Codespaces by clicking "Create codespace on main"

Alternatively, you can deploy the app with Python and ngrok.

Create a new Vonage app

Sign in/Sign up for free developer.vonage.com; to use the Vonage Voice API, you'll have to create a Vonage Application from the developer portal. All requests to the Vonage Voice API require authentication. We will use the API key and private.key.

In the left menu here, click API Settings. Under the API keys tab, you will find your API key. Open Application and create your new app by clicking the "Create a new application" button.

Create a new Vonage appCreate a new Vonage app

And click the button "Generate public and private key". Paste the key in private.key file in related Codespace. Switch on Voice capabilities.

In Codespase terminal, run the following commands:

echo "https://${CODESPACE_NAME}-9000.preview.app.github.dev/webhooks/answer"

and

echo "https://${CODESPACE_NAME}-9000.preview.app.github.dev/webhooks/event"

Copy and paste this in the Answer URL and Event URL in accordance with fields in the Vonage Application settings.

Codespase URLsCodespase URLs

And click the "Generate new application" button at the bottom.

This tutorial also uses a virtual phone number.

We need to buy a virtual number for our app to accept phone calls:

  • Search and buy virtual phone numbers using Vonage Dashboard.

  • Select Voice feature from the dropdown menu. Link numbers using Vonage Dashboard, go to Applications, open related App (e.g. VoiceApp), and click the 'Link' button in the list of numbers.

Link number with the applicationLink number with the application

Streamed audio into your Call using an NCCO

In this scenario, users will call a Vonage number, and music will be streamed into users' calls using an NCCO with a stream action. We will use the following scenario-1.py file:

from dotenv import load_dotenv
from flask import Flask, request, jsonify

from os import environ as env

# Load environment variables from a .env file:
load_dotenv('.env')

# Load in configuration from environment variables:
VONAGE_APPLICATION_ID = env['VONAGE_APPLICATION_ID']
CONF_NAME = env['CONF_NAME']
STREAM_URL = env['STREAM_URL']

app = Flask(__name__)

ncco = [
   {
       "action": "stream",
       "streamUrl": [
           STREAM_URL
       ]
   }
]

@app.route("/webhooks/answer")
def answer_call():
   return jsonify(ncco)

@app.route("/webhooks/event", methods=['POST'])
def events():
   return ("200")

if __name__ == '__main__':
   app.run(host="localhost", port=9000)

Try It Out

You can run your code in Codespace. Run the following commands:

Install the dependencies

pip install -r requirements.txt

Start your app with the following command

python3 scenario-1.py

In the terminal, open the Port tab. Click on Private in the Visibility column, and change it to Public.

Change port visibilityChange port visibility

The sequence of events in this scenario is as follows:

  • Dial your Vonage Number.

  • Vonage receives the Call.

  • A callback is generated on the Answer webhook URL you specified.

  • Your application receives the callback and responds with an NCCO.

  • Music is played into your Call.

Streamed audio into your Call using Voice API

In this scenario, you call your Vonage Number, and you are joined into a conference (in our case Soothing Conference). You can then navigate to the /stream URL to initiate streaming into the conference. Music is then played into your conference using Voice API.

Try It Out

You can run your code in Codespace, run the following steps: Install the dependencies

pip install -r requirements.txt

Start your app with the following command

python3 scenario-2.py

In the terminal, open the Port tab. Click on Private in the Visibility column, and change it to Public.

Change port visibilityChange port visibility

Now you're here, we're ready to stream some audio!

Do these extra things:

  1. Dial your Vonage Number.

  2. Run the next command in the new terminal window echo "https://${CODESPACE_NAME}-9000.preview.app.github.dev/stream". Navigate to the link (in case of running on a local machine, localhost:9000/stream), and music will be played into your conference.

The following actions will happen:

  • Vonage receives the Call.

  • Callback is generated on the Answer webhook URL you specified.

  • Your application receives the callback and responds with an NCCO.

  • Callers joined a conference.

  • Music played at your conference

Wrap-Up

Congrats! You can use the workflow and prepare code samples to stream related audio into a call, and play related music when callers are on hold.

Show off your creations, or let us know how we can help! Join the conversation on our Vonage Community Slack or send us a message on Twitter.

Oleksii BorysenkoVonage Alumni

Oleksii is a Developer Advocate at Vonage, author and storyteller. His interests include AI/ML, unified communications, education technologies, cloud technologies, and open source.

Ready to start building?

Experience seamless connectivity, real-time messaging, and crystal-clear voice and video calls-all at your fingertips.

Subscribe to Our Developer Newsletter

Subscribe to our monthly newsletter to receive our latest updates on tutorials, releases, and events. No spam.