Merge branch 'FRHLS-8' of /home/ben/Documents/src.old/HLS-Stream-Creator
Merge branch 'FRHLS-8' of /home/ben/Documents/src.old/HLS-Stream-Creator

file:b/.gitignore (new)
--- /dev/null
+++ b/.gitignore
@@ -1,1 +1,2 @@
+*~
 

--- /dev/null
+++ b/HLS-Stream-Creator.sh
@@ -1,1 +1,201 @@
-
+#!/bin/bash
+#
+# A very simple BASH script to take an input video and split it down into Segments 
+# before creating an M3U8 Playlist, allowing the file to be served using HLS
+#
+#
+
+######################################################################################
+#
+# Copyright (c) 2013, Ben Tasker
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+# 
+#   Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# 
+#   Redistributions in binary form must reproduce the above copyright notice, this
+#   list of conditions and the following disclaimer in the documentation and/or
+#   other materials provided with the distribution.
+# 
+#   Neither the name of Ben Tasker nor the names of his
+#   contributors may be used to endorse or promote products derived from
+#   this software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# 
+######################################################################################
+
+# Basic config
+OUTPUT_DIRECTORY=${OUTPUT_DIRECTORY:-'./output'}
+
+# Change this if you want to specify a path to use a specific version of FFMPeg
+FFMPEG=${FFMPEG:-'ffmpeg'}
+
+# Number of threads which will be used for transcoding. With newer FFMPEGs and x264
+# encoders "0" means "optimal". This is normally the number of CPU cores.
+NUMTHREADS=${NUMTHREADS:-"0"}
+
+# Video codec for the output video. Will be used as an value for the -vcodec argument
+VIDEO_CODEC=${VIDEO_CODEC:-"libx264"}
+
+# Video codec for the output video. Will be used as an value for the -acodec argument
+AUDIO_CODEC=${AUDIO_CODEC:-"libfdk_aac"}
+
+# Additional flags for ffmpeg
+FFMPEG_FLAGS=${FFMPEG_FLAGS:-""}
+
+# If the input is a live stream (i.e. linear video) this should be 1
+LIVE_STREAM=${LIVE_STREAM:-0}
+
+# Lets put our functions here
+
+
+## Output the script's CLI Usage
+#
+#
+function print_usage(){
+
+cat << EOM
+HTTP Live Stream Creator
+Version 1
+
+Copyright (C) 2013 B Tasker, D Atanasov
+Released under BSD 3 Clause License
+See LICENSE
+
+
+Usage: HLS-Stream-Creator.sh -[l] [-c segmentcount] -i [inputfile] -s [segmentlength(seconds)] -o [outputdir]
+
+	-i	Input file
+	-s	Segment length (seconds)
+	-o	Output directory (default: ./output)
+	-l	Input is a live stream
+	-c	Number of segments to include in playlist (live streams only) - 0 is no limit
+
+Deprecated Legacy usage:
+	HLS-Stream-Creator.sh inputfile segmentlength(seconds) [outputdir='./output']
+
+EOM
+
+exit
+
+}
+
+# This is used internally, if the user wants to specify their own flags they should be
+# setting FFMPEG_FLAGS
+FFMPEG_ADDITIONAL=''
+LIVE_SEGMENT_COUNT=0
+
+# Get the input data
+
+# This exists to maintain b/c
+LEGACY_ARGS=1
+
+# If even one argument is supplied, switch off legacy argument style
+while getopts "i:o:s:c:l" flag
+do
+	LEGACY_ARGS=0
+        case "$flag" in
+                i) INPUTFILE="$OPTARG";;
+                o) OUTPUT_DIRECTORY="$OPTARG";;
+                s) SEGLENGTH="$OPTARG";;
+		l) LIVE_STREAM=1;;
+		c) LIVE_SEGMENT_COUNT="$OPTARG";;
+        esac
+done
+
+
+if [ "$LEGACY_ARGS" == "1" ]
+then
+  # Old Basic Usage is 
+  # cmd.sh inputfile segmentlength 
+
+  INPUTFILE=${INPUTFILE:-$1}
+  SEGLENGTH=${SEGLENGTH:-$2}
+  if ! [ -z "$3" ]
+  then
+    OUTPUT_DIRECTORY=$3
+  fi
+fi
+
+
+# Check we've got the arguments we need
+if [ "$INPUTFILE" == "" ] || [ "$SEGLENGTH" == "" ]
+then
+  print_usage
+fi
+
+# FFMpeg is a pre-requisite, so let check for it
+if hash $FFMPEG 2> /dev/null
+then
+  # FFMpeg exists
+  echo "ffmpeg command found.... continuing"
+else
+  # FFMPeg doesn't exist, uh-oh!
+  echo "Error: FFmpeg doesn't appear to exist in your PATH. Please addresss and try again"
+  exit 1
+fi
+
+
+# Now we want to make sure out input file actually exists
+# This will need tweaking in future if we want to allow a RTMP stream (for example) to be used as input
+if ! [ -f "$INPUTFILE" ]
+then
+  echo "Error: You gave me an incorrect filename. Please re-run specifying something that actually exists!"
+  exit 1
+fi
+
+# Check output directory exists otherwise create it
+if [ ! -w $OUTPUT_DIRECTORY ]
+then
+  echo "Creating $OUTPUT_DIRECTORY"
+  mkdir -p $OUTPUT_DIRECTORY
+fi
+
+if [ "$LIVE_STREAM" == "1" ]
+then
+    FFMPEG_ADDITIONAL+="-segment_list_flags +live"
+
+    if [ "$LIVE_SEGMENT_COUNT" -gt 0 ]
+    then
+	FFMPEG_ADDITIONAL+=" -segment_list_size $LIVE_SEGMENT_COUNT"
+    fi
+fi
+
+# Pulls file name from INPUTFILE which may be an absolute or relative path.
+INPUTFILENAME=${INPUTFILE##*/}
+
+# Finally, lets build the output filename format
+OUT_NAME=$INPUTFILENAME"_%05d.ts"
+
+echo "Generating HLS segments - this may take some time"
+
+# Processing Starts
+$FFMPEG -i "$INPUTFILE" \
+  -loglevel error -y \
+  -vcodec "$VIDEO_CODEC" \
+  -acodec "$AUDIO_CODEC" \
+  -threads "$NUMTHREADS" \
+  -map 0 \
+  -flags \
+  -global_header \
+  -f segment \
+  -segment_list "$OUTPUT_DIRECTORY/$INPUTFILENAME.m3u8" \
+  -segment_time "$SEGLENGTH" \
+  -segment_format mpeg_ts \
+  $FFMPEG_ADDITIONAL \
+  $FFMPEG_FLAGS \
+  $OUTPUT_DIRECTORY/"$OUT_NAME" || exit 1
+

file:a/README.md -> file:b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,105 @@
 HLS-Stream-Creator
 ==================
 
-Simple Bash Script to take a media file, segment it and create an M3U8 playlist for serving using HLS
+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](http://tools.ietf.org/html/draft-pantos-http-live-streaming-11 "HLS on IETF") 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 -[l] [-c segmentcount] -i [inputfile] -s [segmentlength(seconds)] -o [outputdir]
+
+
+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**
+
+```
+	-i [file]	Input file
+	-s [s]  	Segment length (seconds)
+	-o [directory]	Output directory (default: ./output)
+	-c [count]	Number of segments to include in playlist (live streams only) - 0 is no limit
+	-l	Input is a live stream
+
+```
+
+
+
+Output
+-------
+
+As of version 1, the HLS resources will be output to the directory *output*. 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'
+```
+
+
+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.
+
+Example usage:
+
+```
+export VIDEO_CODEC="nvenc"
+export FFMPEG_FLAGS="-pix_fmt yuv420p -profile:v"
+./HLS-Stream-Creator.sh example.avi 10
+```
+
+License
+--------
+
+HLS-Stream-Creator is licensed under the [BSD 3 Clause License](http://opensource.org/licenses/BSD-3-Clause) and is Copyright (C) 2013 [Ben Tasker](http://www.bentasker.co.uk)
+
+
+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](http://projects.bentasker.co.uk/jira_projects/browse/HLS.html) for a HTML mirror of the tracking.
+

file:b/output/readme.txt (new)
--- /dev/null
+++ b/output/readme.txt
@@ -1,1 +1,2 @@
+This directory is where your output video (and playlist) should end up - it's just tidier that way!