FFmpeg Tutorial: How to convert MP4 to HLS format with ffmpeg: A step-by-step guide

0:00

Ever wonder, when watching

0:01

video on the internet,

0:02

when it goes from really

0:02

blurry, to then super high

0:04

quality, and then back down?

0:05

How does that happen?

0:06

And why does that happen?

0:07

This is usually the result

0:09

of a video implementing

0:10

Adaptive Bitrate Streaming,

0:11

a technology that allows

0:12

video quality to adjust

0:14

automatically based on a

0:15

viewer's network conditions,

0:16

such So that the playback

0:17

is always seamless.

0:19

And one way to implement ABR

0:20

is with the HLS protocol.

0:22

That is what we're going to

0:23

be talking through today.

0:25

And in this tutorial using

0:26

FFmpeg, of course, we're

0:28

going to show you how to

0:29

take an MP4 file and package

0:31

it into the HLS format.

0:34

So we have our terminal here.

0:36

We have our input video here.

0:38

Um, you need FFmpeg

0:40

to be installed.

0:41

If not, you can

0:42

install with Homebrew.

0:43

So it would be brew

0:45

install FFmpeg.

0:47

So there are two different

0:48

ways that we're going to

0:50

create HLS streams here.

0:52

The first one is

0:53

kind of simple.

0:53

It's just using one rendition.

0:55

We're just going to take

0:56

the input video and output

0:58

kind of a chunked segmented.

1:00

HLS format, so I stands for

1:02

input, we have our input

1:04

video here, and the first

1:07

option is going to be dash

1:08

C, which stands for codec, so

1:10

this is referring to audio,

1:13

video, data, subtitles,

1:15

captions, um, any of the like.

1:17

So we're just going to copy

1:18

all of those over, right?

1:19

We're not encoding, we're not

1:20

transcoding, and so the first

1:22

option is HLS underscore time.

1:26

And we're going to set

1:26

this to five seconds.

1:27

So what this means is each

1:29

segment that we're creating

1:30

is at a max of five seconds.

1:31

And of course the last

1:32

one, um, is five or below.

1:34

And this is just a good

1:35

kind of middle ground

1:37

for HLS in general.

1:39

The next one to be list size.

1:43

So list size is the

1:45

size of the manifest.

1:46

How many segments are within

1:47

that, um, to turn that off and

1:48

just have all of them we're

1:49

going to type zero there and

1:51

then dash F stands for format.

1:54

And of course we're going

1:54

to have the HLS format.

1:56

Um, and then we can

2:00

Output.

2:00

So this is just going

2:02

to create all of the TS

2:04

segments that we want.

2:06

Um, if you check it

2:07

out here, we can just

2:09

take a look, right?

2:10

We have all of our, all

2:12

of our TS segments here.

2:13

Um, let's see if we play

2:14

it here, it's using VLC.

2:20

Look at that.

2:21

Everything's great.

2:21

I have it muted here.

2:24

So that's exactly

2:25

what we want, right?

2:26

Okay, so we have

2:27

that first one done.

2:28

Now we're going to get on

2:29

to the more complicated one.

2:31

This one includes

2:33

three renditions.

2:33

We're going to be encoding our

2:35

input video into three, which

2:37

are at 1080, 720, and 480p.

2:40

And this allows the player

2:41

that we're going to be using

2:42

to alternate between each one,

2:45

depending on the, you know,

2:46

the user's network connection.

2:47

So you get all the benefits

2:48

of HLS with this one.

2:50

All right, so first

2:51

part, uh, ffmpeg i.

2:54

We have our input video.

2:55

The way that we get it into

2:56

three is we're going to

2:57

be using a complex filter.

2:59

And then we have a string.

3:02

And if you can see here, it's

3:03

going to be the first stream.

3:05

So index zero, the video

3:07

relating to that, we're

3:07

going to split it into

3:08

three different, uh,

3:10

videos, program V1,

3:12

program V2, and program V3.

3:14

So the first V1, it's

3:16

going to be 1920 by 1080.

3:18

Our second one is

3:19

going to be 720.

3:21

So 1280 by 720.

3:23

And then our third

3:25

is going to be 480.

3:26

Uh, V3.

3:27

Alrighty.

3:30

The next one is we're going

3:30

to map with V1 out, and C

3:34

stands for codec, so we're

3:35

doing the video codec for

3:37

the, uh, index stream of 0,

3:40

um, and we're going to be

3:41

using the lib x264 encoder,

3:43

which is just an h264 encoder.

3:46

The bitrate of the video

3:47

stream, and the Xero

3:48

is going to be 5, 000

3:50

kilobytes per second.

3:52

That's our target.

3:53

The max rate is

3:54

going to be 5, 350.

3:57

Um, and the buff size

3:58

is going to be 7, 500.

4:00

So that's just

4:01

for the first one.

4:03

That's going to be for 1080.

4:04

So the next one is going

4:05

to be for that 720.

4:07

Be the target bitrate

4:08

is going to be 2, 800.

4:10

The max is going to be roughly

4:12

3, 000, and then the buff size

4:14

is going to be about 4, 200.

4:15

Alright, I'm going to

4:17

do the last one for 480.

4:19

So that's for the video,

4:20

and now we have the audio

4:23

encoding controls here.

4:24

So again, we have to map

4:25

each one because that's

4:26

how we select each stream.

4:28

So the audio stream at stream

4:30

index 0 or program index 0,

4:32

I'm using an AAC encoder.

4:34

Um, and the bitrate is going

4:35

to be 192, uh, kilobytes per

4:38

second, and the audio channels

4:40

or dash AC is going to be 2.

4:43

So we're just keeping

4:44

it at a, at a stereo

4:46

channel mapping here.

4:47

And so that's for

4:48

the first 1081.

4:49

Now we're going to do the 720.

4:51

So we're dropping it

4:52

down to 128, right?

4:54

We're trying to save some,

4:55

uh, save some data here.

4:57

And then the last one is going

4:58

to be 96 kilobytes per second.

5:01

And now on to the

5:03

HLS kind of settings.

5:05

All right, so the first

5:05

one is going to be format.

5:08

We saw that earlier

5:10

and HLS time.

5:12

We're going to use

5:12

five for this one.

5:14

And then a playlist type.

5:15

Uh, so you see here

5:16

they're independent

5:17

segments, um, segment type.

5:20

It's going to be MPEG TS.

5:21

That's kind of

5:22

what we had before.

5:22

That's the default.

5:24

And then segment file name.

5:25

And so the file name, it's

5:26

just like a way to, to kind of

5:30

template every single segment.

5:32

And so we're going to

5:32

do that using this.

5:34

Um, and so you see here

5:35

the stream underscore,

5:38

uh, and this placeholders

5:39

for the video stream

5:41

or the video rendition.

5:42

So it would be 0, 1, 2,

5:43

and then the data, right?

5:45

This is just the number

5:47

of segment that we're

5:47

going to be using.

5:49

Alrighty.

5:49

And then the master

5:50

playlist name.

5:52

It's going to be

5:53

called Master.

5:54

Um, and then we're going

5:55

to map based on the

5:57

rendition playlists.

5:59

You see here the, you know,

6:00

variable, uh, stream map.

6:03

So we're going to do video

6:04

as index zero, audio as

6:06

index zero, so on and

6:07

so forth for each one.

6:08

And that's just kind of

6:09

mapping all of these to

6:11

each playlist rendition.

6:14

And finally, we are going to

6:16

map the playlist rendition

6:19

playlists to the Master.

6:22

And that's going to be N.

6:22

So if you see here

6:23

it's a pretty lengthy.

6:25

Uh, command, but we're

6:26

going to hit run here and

6:28

see what gets created.

6:30

As you see here, it's

6:31

encoding everything.

6:32

Whereas, uh, before we

6:33

were just stream copying.

6:34

So it's going to take a

6:35

little bit and it's doing

6:37

all three simultaneously.

6:40

Alrighty.

6:40

So just finished.

6:41

So we're now going

6:42

to take a look.

6:43

So here's the master, right?

6:45

So if you take a look, it's

6:46

going to have all of the

6:47

rendition, uh, playlists.

6:49

And you can see here, it

6:50

kind of, in the tags, it

6:52

copied our average, uh,

6:53

bandwidth, our bitrate, our

6:55

resolution, and the, the

6:57

codec, uh, minetypes that

6:58

we'd be using for the web.

7:01

Alright, and so, what we can

7:02

do, just set up a simple,

7:04

simple server, just so we

7:06

can kind of access this, you

7:08

know, on the web and kind

7:08

of get the full benefits.

7:10

So we're just going to

7:10

copy this over, and we're

7:12

going to go into Safari.

7:13

It natively supports this.

7:15

And boom.

7:16

So here's our master.

7:17

If I hit it, right,

7:19

it's gonna change size

7:22

based on the resolution.

7:25

And yeah.

7:27

And show some midi stats here.

7:29

Look at that.

7:31

And that is it.

7:32

Thanks for following along.

7:34

Make sure to check out

7:34

the link below if you

7:35

want to follow this

7:36

tutorial in written form.

7:38

Till next time,

7:39

happy streaming.