• Stars
    star
    270
  • Rank 152,189 (Top 3 %)
  • Language
    Shell
  • License
    BSD 3-Clause "New...
  • Created over 11 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple Bash Script to take a media file, segment it and create an M3U8 playlist for serving using HLS

HLS-Stream-Creator

Introduction

HLS-Stream-Creator is a simple BASH Script designed to take a media file, segment it and create an M3U8 playlist for serving using HLS. There are numerous tools out there which are far better suited to the task, and offer many more options. This project only exists because I was asked to look into HTTP Live Streaming in depth, so after reading the IETF Draft I figured I'd start with the basics by creating a script to encode arbitrary video into a VOD style HLS feed.

Usage

Usage is incredibly simple

./HLS-Stream-Creator.sh -[CeflnS2] [-c segmentcount] -i [inputfile] -s [segmentlength(seconds)] -o [outputdir] -b [bitrates]

Deprecated Legacy usage:
HLS-Stream-Creator.sh inputfile segmentlength(seconds) [outputdir='./output']

So to split a video file called example.avi into segments of 10 seconds, we'd run

./HLS-Stream-Creator.sh -i example.avi -s 10

Arguments

Mandatory Arguments:

-i [file]	Input file
-s [s]		Segment length (seconds)

Optional Arguments:

-b [bitrates]	Output video Bitrates in kb/s (comma seperated list for adaptive streams)
-c [count]	Number of segments to include in playlist (live streams only) - 0 is no limit
-k [prefix]	String to prepend to Key path when encrpytion is used (e.g. https://mykeyserver.com/)
-K [Name]	Name of file for decryption key (will have .key appended)
-o [directory]	Output directory (default: ./output)
-p [name]	Playlist filename prefix
-q [quality]	Change encoding to CFR with [quality]
-t [name]	Segment filename prefix
-u [prefix]	Prefix to prepend to segment and manifest paths
-C		Use constant bitrate as opposed to variable bitrate
-e      	Encrypt the HLS segments (a key will be generated automatically)
-f		Foreground encoding only (adaptive non-live streams only)
-h              Print Usage information
-l		Input is a live stream
    -n              Ignore audio track in input file
-S		Name of a subdirectory to put segments into
-2		Use two-pass encoding

Adaptive Streams

As of HLS-6 the script can now generate adaptive streams with a top-level variant playlist for both VoD and Linear input streams.

In order to create seperate bitrate streams, pass a comma seperated list in with the -b option

./HLS-Stream-Creator.sh -i example.avi -s 10 -b 28,64,128,256

By default, transcoding for each bitrate will be forked into the background - if you wish to process the bitrates sequentially, pass the -f option

./HLS-Stream-Creator.sh -i example.avi -s 10 -b 28,64,128,256 -f

In either case, in accordance with the HLS spec, the audio bitrate will remain unchanged.

Multiple Resolutions

As of HLS-27 it is possible to (optionally) specify a resolution as well as the desired bitrate by appending it to the bitrate it applies to:

./HLS-Stream-Creator.sh -i example.avi -s 10 -b 128-600x400,256-1280x720,2000

In the example above, the first two bitrates will use their specified resolutions, whilst the last will use whatever resolution the source video uses.

The format to use is

[bitrate]-[width]x[height]

Note: There are currently no checks to ensure the specified resolution isn't larger than the source media, so you'll need to check this yourself (for the time being).

You should consider the potential ramifications of player behaviour before using this functionality.

Encrypted Streams

HLS-Stream-Creator can also create encrypted HLS streams, it's enabled by passing -e

./HLS-Stream-Creator.sh -i example.avi -e -s 10 -b 28,64,128,256

The script will generate a 128 bit key and save it to a .key file in the same directory as the segments. Each segment will be AES-128 encrypted using an IV which corresponds to it's segment number (the default behaviour for HLS).

The manifests will then be updated to include the necessary EXT-X-KEY tag:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-KEY:METHOD=AES-128,URI=big_buck_bunny_720p_stereo.avi.key
#EXT-X-TARGETDURATION:17
#EXTINF:10.500000,
big_buck_bunny_720p_stereo.avi_1372_00000.ts

Output

As of version 1, the HLS resources will be output to the directory output (unless a different directory has been specified with -o). These will consist of video segments encoded in H.264 with AAC audio and an m3u8 file in the format

#EXTM3U  
#EXT-X-MEDIA-SEQUENCE:0  
#EXT-X-VERSION:3  
#EXT-X-TARGETDURATION:10  
#EXTINF:10, no desc  
example_00001.ts  
#EXTINF:10, no desc  
example_00002.ts  
#EXTINF:10, no desc  
example_00003.ts  
#EXTINF:5, no desc  
example_00004.ts  
#EXT-X-ENDLIST

Using a Specific FFMPEG binary

There may be occasions where you don't want to use the ffmpeg that appears in PATH. At the top of the script, the ffmpeg command is defined, so change this to suit your needs

FFMPEG='/path/to/different/ffmpeg'

H265 details

Check has been added for libx265 to enforce bitrate limits for H265 since it uses additional parameters.

Audio Codec Availability

Because libfdk_aac is a non-free codec, and is not available in all builds, commit 0796feb switched the default audio codec to aac.

However, in older versions of ffmpeg, aac was marked as experimental - this includes the packages currently in the repos for Ubuntu Xenial. As a result, when running the script, you may see the following error

The encoder 'aac' is experimental but experimental codecs are not enabled, add '-strict -2' if you want to use it.

There are two ways to work around this. If you have the libfdk_aac codec installed, you can specify that it should be used instead

export AUDIO_CODEC="libfdk_aac"

Alternatively, you can update the ffmpeg flags to enable experimental codecs

export FFMPEG_FLAGS='-strict -2'

And the re-run HLS-Stream-Creator.

HLS-23 will, in future, update the script to check for this automatically.

Additional Environment Variables

There are few environment variables which can control the ffmpeg behaviour.

  • VIDEO_CODEC - The encoder which will be used by ffmpeg for video streams. Examples: libx264, nvenc
  • AUDIO_CODEC - Encoder for the audio streams. Examples: aac, libfdk_acc, mp3, libfaac
  • NUMTHREADS - A number which will be passed to the -threads argument of ffmpeg. Newer ffmpegs with modern libx264 encoders will use the optimal number of threads by default.
  • FFMPEG_FLAGS - Additional flags for ffmpeg. They will be passed without any modification.
  • FFMPEG_INPUT_FLAGS - Additional flags for ffmpeg which apply to the input file only. They will also be passed without any modification.

Example usage:

export VIDEO_CODEC="nvenc"
export FFMPEG_FLAGS="-pix_fmt yuv420p -profile:v"
./HLS-Stream-Creator.sh example.avi 10

OS X Users

Segment encryption won't work out of the box on OS X as it relies on arguments which the BSD grep and sed commands don't support. In order to use encryption on OS X you must first install their GNU counterparts

brew install gnu-sed
brew install grep

Note: As of HLS-33 it is no longer necessary to force brew to expose default names (since support has been dropped for --with-default-names).

It should be possible to get HLS-Stream-Creator up and running on a Mac by running the following

# Install Xcode
xcode-select --install

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

# Needed for segment encryption
brew install openssl 
brew install gnu-sed 
brew install grep

# Clone the codebase
git clone [email protected]:bentasker/HLS-Stream-Creator.git

Automation

HLS-Stream-Creator was originally created as a short bit of research and has since grown significantly. The consequence of this, is that it was primarily focused on being run manually.

Although still not a perfect solution to automation, an example of automating HLS-Stream-Creator can be found here. Better automation support will hopefully be added sometime in the future (pull requests very welcome).

License

HLS-Stream-Creator is licensed under the BSD 3 Clause License and is Copyright (C) 2013 Ben Tasker

Issue Tracking

Although the Github issue tracker can be used, the bulk of project management (such as it is) happens in JIRA. See projects.bentasker.co.uk for a HTML mirror of the tracking.

More Repositories

1

Wake-On-Lan-Python

A small Python script to allow the sending of a WOL Magic packet
Python
175
star
2

HomeAssistantAddons

Shell
30
star
3

PHP-GPX-Ingest

Simple class to ingest a basic GPX file and extract data/stats from it
PHP
26
star
4

RemoveAMP

A small script to be pulled in by Greasemonkey, attempting to locate non AMP versions of pages and direct the user there
JavaScript
17
star
5

Ecowitt_to_InfluxDB

Python
8
star
6

telegraf-plugins

Python
6
star
7

Golang-SSH-Tarpit

Go
5
star
8

BackupEncryptionScripts

Simple BASH scripts for encrypting backups
Shell
5
star
9

gadgetbridge_to_influxdb

Script to fetch a copy of the Gadgetbridge database and extract data for Huami devices for writing onwards into InfluxDB
Python
5
star
10

tplink_to_influxdb

Python
4
star
11

mod_bgithub_feed

Simple Joomla module to embed a list of a user's repositories into a Joomla! based web site
PHP
3
star
12

adblocklists

I've been running my own AdblockPlus/UblockOrigin list for a while, but wanted to start recording why certain domains were blocked. So moving into a repo for that purpose
JavaScript
3
star
13

PHPCredLocker

PHPCredLocker is a secure web-based repository for credentials. Intended for teams who need to share credentials, the system aims to store all content securely
PHP
3
star
14

Jira-Webhook-Listener

A small script to catch JIRA webhook events and send notifications/run custom code
PHP
3
star
15

docker_openresty_geoip

Dockerfile
2
star
16

adblock_lists_v2

Shell
2
star
17

nginx_log_actions

NGinx Log Actions is a small processing script designed to read in an NGinx access log and perform custom actions on a per domain basis.
PHP
2
star
18

nikola_ssg_webmentions

Python
1
star
19

zepp_to_influxdb

A script to pull data from the Zepp/AmznFit/Huami/MiFit and write it onwards into InfluxDB
Python
1
star
20

article_scripts

A repo to hold miscellaneous scripts that I create for articles/posts (the plan is to also backfill a bit at some point)
C
1
star
21

docker-nextcloud

Dockerfile
1
star
22

DNSChat

A simple proof of concept
Python
1
star
23

URLBrand

URLBrand is a small PHP Project allowing for the generation of short URLs (so long as you have a short domain name to use).
PHP
1
star
24

LocalChat

Localchat is a simple and lightweight chat application. It's primary purpose is to provide a means to have a multi-user Off-The-Record transient chat
Python
1
star