Simplifying legacy args handling
Simplifying legacy args handling

--- a/HLS-Stream-Creator.sh
+++ b/HLS-Stream-Creator.sh
@@ -20,7 +20,7 @@
 #   list of conditions and the following disclaimer in the documentation and/or
 #   other materials provided with the distribution.
 # 
-#   Neither the name of the {organization} nor the names of its
+#   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.
 # 
@@ -38,10 +38,23 @@
 ######################################################################################
 
 # Basic config
-OUTPUT_DIRECTORY='./output'
+OUTPUT_DIRECTORY=${OUTPUT_DIRECTORY:-'./output'}
 
 # Change this if you want to specify a path to use a specific version of FFMPeg
-FFMPEG='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:-""}
 
 # Lets put our functions here
 
@@ -55,12 +68,19 @@
 HTTP Live Stream Creator
 Version 1
 
-Copyright (C) 2013 B Tasker
+Copyright (C) 2013 B Tasker, D Atanasov
 Released under BSD 3 Clause License
 See LICENSE
 
 
-Usage: HLS-Stream-Creator.sh inputfile segmentlength(seconds) [outputdir='./output']
+Usage: HLS-Stream-Creator.sh -i [inputfile] -s [segmentlength(seconds)] -o [outputdir]
+
+	-i	Input file
+	-s	Segment length (seconds)
+	-o	Output directory (default: ./output)
+
+Deprecated Legacy usage:
+	HLS-Stream-Creator.sh inputfile segmentlength(seconds) [outputdir='./output']
 
 EOM
 
@@ -68,72 +88,42 @@
 
 }
 
+# Get the input data
 
-## Create the Initial M3U8 file including the requisite headers
-#
-# Usage: create_m3u8 streamname segmentlength
-#
-function create_m3u8(){
+# This exists to maintain b/c
+LEGACY_ARGS=1
 
-# We'll add some more headers in a later version, basic support is all we need for now
-# The draft says we need CRLF so we'll use SED to ensure that happens
-cat << EOM | sed 's/$/\r/g' > $OUTPUT_DIRECTORY/$1.m3u8
-#EXTM3U
-#EXT-X-TARGETDURATION:$2
-#EXT-X-MEDIA-SEQUENCE:0
-#EXT-X-VERSION:3
-EOM
-}
+# If even one argument is supplied, switch off legacy argument style
+while getopts "i:o:s:" flag
+do
+	LEGACY_ARGS=0
+        case "$flag" in
+                i) INPUTFILE="$OPTARG";;
+                o) OUTPUT_DIRECTORY="$OPTARG";;
+                s) SEGLENGTH="$OPTARG";;
+        esac
+done
 
 
-## Append a movie segment to the M3U8
-#
-# Usage: append_segment streamname SegmentLength(Seconds) SegmentFilename
-#
-function append_segment(){
+if [ "$LEGACY_ARGS" == "1" ]
+then
+  # Old Basic Usage is 
+  # cmd.sh inputfile segmentlength 
 
-cat << EOM | sed 's/$/\r/g' >> $OUTPUT_DIRECTORY/$1.m3u8
-#EXTINF:$2
-$3
-EOM
-}
+  INPUTFILE=${INPUTFILE:-$1}
+  SEGLENGTH=${SEGLENGTH:-$2}
+  if ! [ -z "$3" ]
+  then
+    OUTPUT_DIRECTORY=$3
+  fi
+fi
 
-
-## Close the M3U8 file
-#
-# Found that ffplay skips the first few segments if this isn't included.
-#
-# Usage: close_m3u8 streamname
-#
-function close_m3u8(){
-cat << EOM | sed 's/$/\r/g' >> $OUTPUT_DIRECTORY/$1.m3u8
-#EXT-X-ENDLIST
-EOM
-}
-
-
-# The fun begins! Think of this as function main
-
-
-# Get the input data
-
-# Basic Usage is going to be
-# cmd.sh inputfile segmentlength 
-
-INPUTFILE=$1
-SEGLENGTH=$2
-if ! [ -z "$3" ]
-then
-  OUTPUT_DIRECTORY=$3
-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
@@ -154,42 +144,6 @@
   exit 1
 fi
 
-
-
-# OK, so from here, what we want to do is to split the file into appropriately sized chunks,
-# re-encoding each to H.264 with MP3 audio, all to go into an MPEG2TS container
-#
-# The protocol appears to support MP4 as well though, so we may well look at that later.
-#
-# Essentially we want to create the chunks by running
-#
-# ffmpeg -i "$INPUTFILE" -vcodec libx264 -acodec mp3 -ss "START_POINT" -t "$SEGLENGTH" -f mpegts $OUTPUT_DIRECTORY/"$INPUTFILE"_"$N".ts
-
-# First we need the duration of the video
-DURATION=$($FFMPEG -i "$INPUTFILE" 2>&1 | grep Duration | cut -f 4 -d ' ')
-
-# Now we need to break out the duration into a time we can use
-DUR_H=$(echo "$DURATION" | cut -d ':' -f 1)
-DUR_M=$(echo "$DURATION" | cut -d ':' -f 2)
-DUR_X=$(echo "$DURATION" | cut -d ':' -f 3 | cut -d '.' -f 1)
-
-# Calculate the duration in seconds
-DURATION_S=$(expr \( $DUR_H \* 60 + $DUR_M \) \* 60 + $DUR_X)
-
-
-# Check we've not got empty media
-if [ "$DURATION_S" == "0" ]
-then
-  echo "You've given me an empty media file!"
-  exit 1
-fi
-
-
-# Now we've got our Duration, we need to work out how many segments to create
-N='1'
-START_POS='0'
-let 'N_FILES = DURATION_S / SEGLENGTH + 1'
-
 # Check output directory exists otherwise create it
 if [ ! -w $OUTPUT_DIRECTORY ]
 then
@@ -200,42 +154,22 @@
 # Pulls file name from INPUTFILE which may be an absolute or relative path.
 INPUTFILENAME=${INPUTFILE##*/}
 
-# Create the M3U8 file
-create_m3u8 "$INPUTFILENAME" "$SEGLENGTH"
-
 # Finally, lets build the output filename format
-OUT_NAME=$INPUTFILENAME"_%03d.ts"
+OUT_NAME=$INPUTFILENAME"_%05d.ts"
 
 # 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_FLAGS \
+  $OUTPUT_DIRECTORY/"$OUT_NAME" || exit 1
 
-while [ "$START_POS" -lt "$DURATION_S" ]
-do
-
-  OUTPUT=$( printf "$OUT_NAME" "$N" )
-  echo "Creating $OUTPUT ($N/$N_FILES)..."
-  $FFMPEG -i "$INPUTFILE" -loglevel quiet -vcodec libx264 -acodec mp3 -ss "$START_POS" -t "$SEGLENGTH" -f mpegts $OUTPUT_DIRECTORY/"$OUTPUT"
-
-  let "N = N + 1"
-  let "START_POS = START_POS + SEGLENGTH"
-
-  # If we're on the last segment, the duration may be less than the seglenth, so we need to reflect this in the m3u8
-  if ! [ "$START_POS" -lt "$DURATION_S" ]
-  then
-    SEG_DURATION=$($FFMPEG -i $OUTPUT_DIRECTORY/"$OUTPUT" 2>&1 | grep Duration | cut -f 4 -d ' ')
-    # Now we need to break out the duration into a time we can use
-    DUR_H=$(echo "$SEG_DURATION" | cut -d ':' -f 1)
-    DUR_M=$(echo "$SEG_DURATION" | cut -d ':' -f 2)
-    DUR_X=$(echo "$SEG_DURATION" | cut -d ':' -f 3 | cut -d '.' -f 1)
-
-    # Calculate the duration in seconds
-    let "SEGLENGTH = ( DUR_H * 60 + DUR_M ) * 60 + DUR_X"
-  fi
-
-  # Append the file reference to the M3U8
-  append_segment "$INPUTFILENAME" "$SEGLENGTH" "$OUTPUT"
-
-done
-
-# Add the close tag (ffplay gives some weird behaviour without this!)
-close_m3u8 "$INPUTFILENAME"
-

file:a/README.md -> file:b/README.md
--- a/README.md
+++ b/README.md
@@ -16,13 +16,18 @@
 Usage is incredibly simple
 
 ```
-./HLS-Stream-Creator.sh inputfile segmentlength(seconds) [outputdir='./output']
+./HLS-Stream-Creator.sh -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 example.avi 10
+./HLS-Stream-Creator.sh -i example.avi -s 10
 ```
 
 
@@ -30,24 +35,21 @@
 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 MP3 audio (should be AAC really, but I'd compiled *ffmpeg* without) and an m3u8 file in the format
+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_001.ts  
+>example_00001.ts  
 >\#EXTINF:10, no desc  
->example_002.ts  
+>example_00002.ts  
 >\#EXTINF:10, no desc  
->example_003.ts  
+>example_00003.ts  
 >\#EXTINF:5, no desc  
->example_004.ts  
+>example_00004.ts  
 >\#EXT-X-ENDLIST
-
-
-
 
 
 
@@ -61,6 +63,23 @@
 ```
 
 
+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
 --------
@@ -68,4 +87,8 @@
 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.
+