api.video

Features

Documentation

Live Stream to the Browser with FFMPEG CLI and Python

March 4, 2021 - Erikka Innes in live - create, Python

Let's learn how to live stream using the FFMPEG command-line interface for Mac and Python, then write a program that will do everything for us in Python. For the camera and audio, we'll use what's built-in to your Mac. You can attach another camera if you want, this tutorial should help with figuring out how to do that too. We recommend trying this tutorial as-is first. And then...


Requirements

  • Mac (as always, you can tweak the instructions for Linux or PC but it's a Mac focused tutorial)
  • Homebrew - if you don't have it we'll include a little about installing it
  • Xcode - you can add this as part of a homebrew installation
  • api.video account - you can get one for FREE right here - SIGN UP
  • Python
  • requests module for Python
  • ffmpeg-python
  • OSX10.7 or higher

Install FFMPEG

Sometimes an FFMPEG install can get complicated. You'll see a lot of people online asking why their installation doesn't work. If you have a Mac, there is an easy answer to this problem...hopefully. Let's go over one simple way you can install FFMPEG so it starts working at the command line for you right away. We're going to use the homebrew method, because it makes installation simple if you already have homebrew installed.

For Users Who Already Have Homebrew

If you've got homebrew installed, all you need to do is this:

brew install ffmpeg

That's it. It should install without issue. (Famous last words right?) Test that it works with this:

ffmpeg -version

If it's installed, you will get back a bunch of information about your configuration. If not you will get an error of some type. Troubleshooting installation is beyond the scope of this tutorial, but you can post questions in the community forum and we'll help you figure it out.

For Users Who Don't Have Homebrew

If you fall into this category, you may be wondering what homebrew is. It's a free, open-source software package manager. It simplifies installation of software on macOS and Linux.

To install homebrew, you'll need to run this command:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

If you don't have Xcode, or the appropriate Xcode components installed, you'll have to install those. Fortunately, you'll be told what's missing so you can install it. Follow the instructions to install and if you run into problems, there is a lot of documentation online to help you through. We can't be more specific for Xcode, because there's a lot of ways your installation can differ from another one. However, if you need help, feel free to contact us in the community forum.

Let's Use FFMPEG CLI and Python to Live Stream

Now that we have FFMPEG installed, let's try using it to set up a live stream.

  1. Let's set up the container for our live stream. With api.video, you create a container for your live stream, then you send your stream to it to be played. The code for this is:
import requests

url = "https://ws.api.video/auth/api-key"

payload = {"apiKey": "api key here"}
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json"
}

response = requests.request("POST", url, json=payload, headers=headers)
response = response.json()
token = response.get("access_token")

url = "https://ws.api.video/live-streams"

payload = {
    "record": False,
    "name": "Bob"
}
headers = {
    "Accept": "application/vnd.api.video+json",
    "Content-Type": "application/json",
    "Authorization": token
}

response = requests.request("POST", url, json=payload, headers=headers)
  1. Now that we have our container, open the api.video dashboard and click My Videos.
  2. Click Live. You should see your livestream (mine's named Bob) here. But it's not working yet. That's okay, we're going to change that. Click on the picture representing your livestream.
  3. You'll see some information about your livestream. The information we're interested in, is the RTMP Stream Url. Go ahead and make a note of that and leave the dashboard open - we're going to add that url into our script.
  4. Open a Terminal window.
  5. Let's list the available video and audio devices on your Mac using FFMPEG. At the CLI prompt, type: ffmpeg -f avfoundation -list_devices true -i "" This will list all the devices available to you. You should see something similar to this:
[AVFoundation indev @ 0x7fed75d21fc0] AVFoundation video devices:
[AVFoundation indev @ 0x7fed75d21fc0] [0] FaceTime HD Camera (Built-in)
[AVFoundation indev @ 0x7fed75d21fc0] [1] Capture screen 0
[AVFoundation indev @ 0x7fed75d21fc0] AVFoundation audio devices:
[AVFoundation indev @ 0x7fed75d21fc0] [0] Built-in Microphone 

So you might be asking what's going on here? Let's go over the command. First, you're telling the system that you're using the ffmpeg CLI by saying 'ffmpeg.' Then your script says for our input file format (-f) use the framework avfoundation and list available devices. We know it's for the input file because of the -i flag. There's more to this explanation, but it's a little outside the scope of this tutorial. Without getting too into the details here, the device is your input instead of a file. When you run the script a list comes back and it shows you two arrays. One array is for video choices, and one is for audio. Note the number for each item you want to use. For this tutorial we're going to use 0 and 0.

  1. And now for the script. Type: ffmpeg -f avfoundation -framerate 25 -i "0:0" -f flv rtmp://broadcast.api.video/s/streamKey

We have a few things going on in this script. We start by telling the system we want to use the ffmpeg command line, then we provide information about our input "file" (camera and audio in this case). We say for the input file format -f we want to use the AVFoundation framework (avfoundation) at framerate (-framerate) 25. And we mention it's for input here too (-i) and what kind of input with "0:0." If you're like what the heck is "0:0" you're in good company. This is basically a key value pair for the video and audio. Think of it like "video:audio." And what you did, is you said for video use what's in slot 0 of the video choices array. For audio use what's in slot 0 of the audio choices array. You can also use just the first word of each item in the array, typed exactly the same way. That would look like "FaceTime:Built-in." Finally you say for your output file format (-f) you want to send the format of flv (flv) to the RTMP server with your stream key. That's where it will be turned into beautiful HLS and streamed for you.

If you've seen FFMPEG before, you might wonder where the codecs are. You can add them in to your script, but for the sake of simplicity they're excluded here. By excluding them, your system will choose what it thinks are the best codecs. You can see what was selected, and then manually include them in your script if you feel like it. This can be a good way to test that you understand where to put the codec flags in your script. After that works, if you don't like a codec you can trade it out for something else and see if it runs better (or in some cases at all, codecs are finnicky).

At this point, if your script is running, you have a bunch of choices available to you:

  • You can grab the embed iframe information and add the live stream to a web page.
  • You can grab the embed link and add it to a page, or just put it in the browser search bar and open it to play there.
  • You can associate it with a player.
  1. It won't stop running! That's okay, you have two choices here. You can click on the Terminal window and press q or you can use CTRL-C.

If you want to try running this entire process programmatically, read on!

Run ffmpeg CLI with ffmpeg-Python

This is a pretty cool Python module. It's a wrapper for your CLI commands, meaning you can run everything using a Python file. We're going to need it for this next code snippet.

  1. Install ffmpeg-python. It's a little confusing because the install command looks different than the module title. On the command line, install with: pip install ffmpeg-python

NOTE: Don't mess up and try installing ffmpeg. It will install something, but in our case, not something useful.

  1. In your code sample, make sure you add import ffmpeg.

  2. And now the code sample:

import requests
import ffmpeg

url = "https://ws.api.video/auth/api-key"

payload = {"apiKey": "your API key here"}
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json"
}

response = requests.request("POST", url, json=payload, headers=headers)
response = response.json()
token = response.get("access_token")

url = "https://ws.api.video/live-streams"

payload = {
    "record": False,
    "name": "Bob"
}
headers = {
    "Accept": "application/vnd.api.video+json",
    "Content-Type": "application/json",
    "Authorization": token
}

response = requests.request("POST", url, json=payload, headers=headers)
response = response.json()

stream_key = response.get("streamKey")
iframe = response["assets"]["iframe"]
player = response["assets"]["player"]
print("iFrame :", iframe)
print("player :", player)
rtmp_url = "rtmp://broadcast.api.video/s/" + stream_key

(
ffmpeg
.input('0:0', format='avfoundation', framerate=25)
.output(rtmp_url, format='flv', flvflags='no_duration_filesize')
.run()
)

The code sample will authenticate, grab a token, set up the container for your livestream, fetch the livestream key and build your server URL, then start up your live stream. It prints out the iframe embed code and the live stream link. You can take the iframe code and paste it into an HTML page for viewing or you can use the live stream (player) link and put it in your web browser. Press play and you're streaming!

Clean up on Aisle 9 - Delete Your Live Streams

After trying the code sample a few times, you may have a bunch of live streams when you only wanted one or two.

You can remove the live streams one at a time with this code:

import requests

url = "https://ws.api.video/auth/api-key"

payload = {"apiKey": "your API key here"}
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json"
}

response = requests.request("POST", url, json=payload, headers=headers)
response = response.json()
token = response.get("access_token")

url = "https://ws.api.video/live-streams"
payload = {"record": False}
headers = {
    "Accept": "application/vnd.api.video+json",
    "Content-Type": "application/json",
    "Authorization": token
}

response = requests.request("POST", url, json=payload, headers=headers)
print(response.json())


url = "https://ws.api.video/live-streams/liveStreamId"

response = requests.request("DELETE", url, headers=headers)

Note that the liveStreamId is not the stream key. It's the value that shows at the end of the player link. This is an example player link: https://embed.api.video/live/li6pLlinklOtQ6aK6u7Ktc6N

Add the part that comes after 'live/' after 'live-streams/' in the code sample and send your request. The live stream will be deleted for you.

Thanks for reading today! If you have trouble setting this up, please contact us in the community forum. We can include troubleshooting content based on issues you run into.

You May Also Like...

Erikka Innes

Developer Evangelist

Get started now

Connect your users with videos