How to Convert Audio Files Using FFMpeg and PHP

April 26, 2023
Written by
Reviewed by

How to Convert Audio Files Using FFMpeg and PHP

Whether you're a Linux, Windows, or macOS user, you'll know that audio files come in a variety of different formats. Three common formats are:

  • MP3: This is, effectively, the de facto audio file format. MP3 files are readable by just about every audio device and player available today. What's more, they do a good job of compressing a file's size while retaining its audio quality or fidelity. That said, during lossy compression to MP3, compression artifacts, such as drop-outs, metallic ringing, and hissing, may be introduced.
  • FLAC: As this format is lossless, it contains a number of advantages over MP3. It's an open-source format. It's error-resistant, meaning that errors won't destroy the entire file, as with MP3s. Converting from FLAC to other formats doesn't result in a loss of quality, as also happens with MP3. And, it's also an excellent choice for audio streaming. That said, FLAC files will be larger than the equivalent using MP3.
  • WAVE (or WAV): Unlike MP3 and FLAC, WAV is an uncompressed file format, which contains all of the original audio. As a result, file sizes are larger than the other two formats. However, it's preferred by audio professionals, arguably the industry standard, as WAV files are better to edit and create derivative content from.

But regardless of the file format you use, there may come a time when you need to convert (or transcode) your audio files to a different format.

For example, you might use Linux at home and store your music in FLAC format. However, at work, you can't listen to your music, as your organisation is standardised on Windows which doesn't support the format, and you're not allowed to modify the operating system or music player to add support. Or, you may run a podcast, recording your sessions in WAV format but need to convert them to MP3 format for your podcast host.

Regardless of the motivation, you need a quick and effective way to convert your audio files to different formats. So what do you do? Well, while there are numerous tools available, likely the most common and also the most readily available is FFmpeg.

Available for all modern operating systems, FFmpeg can convert audio (and video) files to a range of formats, mix stereo files down to mono, limit a file's duration, change a file's bitrate, set file metadata, and so much more. It's the proverbial Swiss Army Knife if you will. What's more, it's open source and free!

In this tutorial, you're going to learn how to use it to convert an MP3 file to FLAC, OGG, and WAV formats, both on the command line and programmatically using PHP.

Prerequisites

To follow along with this tutorial, you will need the following:

  • PHP 8.2 with allow_url_fopen enabled
  • Composer installed globally
  • The mediainfo command. If you're using Linux or macOS, install it using your preferred package manager. If you're using Microsoft Windows, download and install it from the official website.

Install FFMpeg

The first thing to do is to install FFMpeg. If you're using Linux or macOS, use your preferred package manager. If you're using Microsoft Windows, download the official FFMpeg binary and install it manually.

Once installed, confirm that it's available by running the following command.

ffmpeg -version

You should see output similar to the following.

ffmpeg version 5.1.1-1ubuntu2.1 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 12 (Ubuntu 12.2.0-3ubuntu1)
configuration: --prefix=/usr --extra-version=1ubuntu2.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librist --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --disable-sndio --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-libplacebo --enable-shared
libavutil          57. 28.100 / 57. 28.100
libavcodec         59. 37.100 / 59. 37.100
libavformat        59. 27.100 / 59. 27.100
libavdevice        59.  7.100 / 59.  7.100
libavfilter         8. 44.100 /  8. 44.100
libswscale          6.  7.100 /  6.  7.100
libswresample   4.  7.100 /  4.  7.100
libpostproc        56.  6.100 / 56.  6.100

Check that you have all of the required codecs

The next thing to do is to make sure that you have the required codecs. Depending on your operating system and installed tooling, there are a number of ways to do this. Pick the command from the following list that is most applicable.

# If you have Grep installed
ffmpeg -codecs -hide_banner | grep -i -e "FLAC\|Wave\|Vorbis"

# If you have AWK installed
ffmpeg -codecs -hide_banner | awk '$2 ~ /^(flac|vorbis|pcm_s16le)$/ {print $2}'

# If you're using Microsoft Windows Powershell
ffmpeg.exe -codecs -hide_banner | Select-String -Pattern "flac|vorbis|pcm_s16le"

If you see flac, pcm_s16le (for WAV files), and vorbis in the output, then you're ready to continue.

Convert an MP3 file to FLAC, OGG, and WAV formats with FFmpeg

Now, it's time to convert an MP3 file by running the following command.

ffmpeg -i https://demo.twilio.com/docs/classic.mp3 classic.wav classic.flac classic.ogg

If successful, you'll see three new files, classic.wav, classic.flac, and classic.ogg, in the directory where you ran the command. Have a listen to any of them in your preferred music player. You're going to love it!

Set up the PHP project directory

With FFmpeg working, it's time to write some PHP code to transcode the MP3 file programmatically. First, create a project directory, wherever you keep your PHP projects, and change into it, by running the following commands.

mkdir -p ffmpeg-with-php
cd ffmpeg-with-php

Install the required dependencies

Next, install the single required dependency PHP-FFMpeg by running the command below.

composer require php-ffmpeg/php-ffmpeg

Quoting the GitHub repository, the package is "an object oriented PHP driver for FFMpeg binary".

Write the PHP code

In the project's top-level directory, create a new file named index.php and in that file add the following code.

<?php

use FFMpeg\Format\AudioInterface;
use FFMpeg\Media\MediaTypeInterface;

require 'vendor/autoload.php';

$ffmpeg = FFMpeg\FFMpeg::create();
$audioFile = $ffmpeg->open('https://demo.twilio.com/docs/classic.mp3');

$formatWav = new FFMpeg\Format\Audio\Wav();
$formatWav->on(
    'progress',
    function (MediaTypeInterface $audio, AudioInterface $format, float $percentage) {
        printf(
            "Transcoded %s percent of %s using the %s codec.\n",
            $percentage,
            basename($audio->getPathfile()),
            $format->getAudioCodec(),
        );
    }
);

$audioFile->save($formatWav, __DIR__ . "/classic.wav");

The code starts by initialising an FFMpeg instance ($ffmpeg), which is the central class through which all functionality operates. The object then downloads and opens an MP3 file from Twilio using PHP's streams. Following that, a new FFMpeg\Format\Audio\Wav object is initialised, which provides the configuration required to convert the downloaded MP3 to a WAV file.

A listener is then added to the format object to listen for the progress event with the on() method. This event, as the name implies, will be told how much progress has been made in converting or transcoding the file, which will be printed to the terminal. Finally, using the save() method, the transcoded file is then saved to the current directory and named classic.wav.

With the code ready, run it using the following command.

php index.php

You should see output similar to the following.

Transcoded 25 percent of classic.mp3 using the pcm_s16le codec.
Transcoded 99 percent of classic.mp3 using the pcm_s16le codec.

Now, let's augment the code to convert the MP3 file to FLAC and OGG, as well as add some ID3 tags to the transcoded audio files, so that it's clear what the audio file contains using your operating system's file viewer.

To do that, update index.php to match the following code.

<?php

use FFMpeg\Format\AudioInterface;
use FFMpeg\Media\MediaTypeInterface;

require 'vendor/autoload.php';

function showTranscodeProgress(): Closure
{
    return function (MediaTypeInterface $audio, AudioInterface $format, float $percentage) {
        printf(
            "Transcoded %s percent of %s using the %s codec.\n",
            $percentage,
            basename($audio->getPathfile()),
            $format->getAudioCodec(),
        );
    };
}

$ffmpeg = FFMpeg\FFMpeg::create();
$audioFile = $ffmpeg->open('https://demo.twilio.com/docs/classic.mp3');

$formatWav = new FFMpeg\Format\Audio\Wav();
$formatWav->on('progress', showTranscodeProgress());

$formatVorbis = new FFMpeg\Format\Audio\Vorbis();
$formatVorbis->on('progress', showTranscodeProgress());

$formatFlac = new FFMpeg\Format\Audio\Flac();
$formatFlac->on('progress', showTranscodeProgress());
$formatFlac->setAudioChannels(1);

$audioFile->filters()->addMetadata([
        "title" => "Never Gonna Give You Up",
        "album" => "Whenever You Need Somebody",
        "artist" => "Rick Astley",
        "year" => "1987",
]);

$audioFile
        ->save($formatWav, __DIR__ . "/classic.wav")
        ->save($formatVorbis, __DIR__ . "/classic.oga")
        ->save($formatFlac, __DIR__ . "/classic.flac");

The code starts by extracting the listener anonymous function, so that it can be used to report the transcoding progress for the new file formats. Then, two additional Format objects are initialised, one for transcoding to OGG (Vorbis), and another for FLAC. After that, the MP3 file is converted from stereo to mono by passing 1 to setAudioChannels().

With the three Format objects initialised, metadata, including the song's title, album, artist, and year of release is added to each of the transcoded files. Finally, the save() command is called to convert the MP3 file.

If you run the code again, you should see output similar to the following, and have an OGG (Vorbis) and FLAC version of the MP3 file in the same directory.

Transcoded 25 percent of classic.mp3 using the pcm_s16le codec.
Transcoded 99 percent of classic.mp3 using the pcm_s16le codec.
Transcoded 13 percent of classic.mp3 using the vorbis codec.
Transcoded 35 percent of classic.mp3 using the vorbis codec.
Transcoded 57 percent of classic.mp3 using the vorbis codec.
Transcoded 79 percent of classic.mp3 using the vorbis codec.
Transcoded 99 percent of classic.mp3 using the vorbis codec.
Transcoded 21 percent of classic.mp3 using the flac codec.
Transcoded 99 percent of classic.mp3 using the flac codec.

Finally, check that the metadata was written to the file, by running the following command.

mediainfo classic.ogg

General
Complete name                      : classic.ogg
Format                                     : Ogg
File size                                    : 2.83 MiB
Duration                                     : 3 min 34 s
Overall bit rate mode              : Variable
Overall bit rate                             : 111 kb/s
Album                                        : 5orai tea 20080612
Track name                                   : Never Gonna Give You Up
Track name/Position               : 07
Performer                                    : Rick Astley
Genre                                        : Dance
Writing application                  : Lavc59.37.100 libvorbis

Audio
ID                                           : 160014268 (0x9899FBC)
Format                                       : Vorbis
Format settings, Floor            : 1
Duration                                     : 3 min 34 s
Bit rate mode                                : Variable
Bit rate                                     : 112 kb/s
Channel(s)                                   : 2 channels
Sampling rate                                : 44.1 kHz
Compression mode                : Lossy
Stream size                                  : 2.86 MiB
Writing library                              : Lavf59.27.100

That's how to convert audio files using FFMpeg and PHP

If you need to convert your audio files to one or more different formats, you now have the essential skills to do so. However, this is just the start, as there is so much more that you can do.

I hope that this tutorial has encouraged you to learn more. Explore PHP-FFMpeg and tweet me what you found. I'd love to know where your enthusiasm takes you.

Matthew Setter is a PHP Editor in the Twilio Voices team and a PHP, Go, and Rust developer. He’s also the author of Mezzio Essentials and Deploy With Docker Compose. When he's not writing PHP code, he's editing great PHP articles here at Twilio. You can find him at msetter[at]twilio.com, on Twitter, and on GitHub.

Image attributions