Made EXT-X-ENDLIST addition conditional. See HLS-15
--- a/HLS-Stream-Creator.sh
+++ b/HLS-Stream-Creator.sh
@@ -94,6 +94,7 @@
-f Foreground encoding only (don't fork the encoding processes into the background - adaptive non-live streams only)
-p Playlist filename
-t Segment filename prefix
+ -S Segment directory name (default none)
Deprecated Legacy usage:
HLS-Stream-Creator.sh inputfile segmentlength(seconds) [outputdir='./output']
@@ -113,8 +114,9 @@
playlist_name="$1"
output_name="$2"
bitrate="$3"
-
-$FFMPEG -i "$INPUTFILE" \
+infile="$4"
+
+$FFMPEG -i "$infile" \
-loglevel error -y \
-vcodec "$VIDEO_CODEC" \
-acodec "$AUDIO_CODEC" \
@@ -165,6 +167,13 @@
if ! kill -0 ${PIDS[$i]} 2> /dev/null
then
echo "Encoding for bitrate ${BITRATE_PROCESSES[$i]}k completed"
+
+ if [ "$LIVE_STREAM" == "1" ] && [ `grep 'EXT-X-ENDLIST' "$OUTPUT_DIRECTORY/${PLAYLIST_PREFIX}_${BITRATE_PROCESSES[$i]}.m3u8 | wc -l " == "0" ]
+ then
+ # Correctly terminate the manifest. See HLS-15 for info on why
+ echo "#EXT-X-ENDLIST" >> "$OUTPUT_DIRECTORY/${PLAYLIST_PREFIX}_${BITRATE_PROCESSES[$i]}.m3u8"
+ fi
+
unset BITRATE_PROCESSES[$i]
unset PIDS[$i]
fi
@@ -179,14 +188,16 @@
# setting FFMPEG_FLAGS
FFMPEG_ADDITIONAL=''
LIVE_SEGMENT_COUNT=0
-
+IS_FIFO=0
+TMPDIR=${TMPDIR:-"/tmp"}
+MYPID=$$
# 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:b:p:t:lf" flag
+while getopts "i:o:s:c:b:p:t:S:lf" flag
do
LEGACY_ARGS=0
case "$flag" in
@@ -199,6 +210,7 @@
f) NO_FORK=1;;
p) PLAYLIST_PREFIX="$OPTARG";;
t) SEGMENT_PREFIX="$OPTARG";;
+ S) SEGMENT_DIRECTORY="$OPTARG";;
esac
done
@@ -234,6 +246,14 @@
exit 1
fi
+# Check whether the input is a named pipe
+if [ -p "$INPUTFILE" ]
+then
+ echo "Warning: Input is FIFO - EXPERIMENTAL"
+ IS_FIFO=1
+
+fi
+
# Check output directory exists otherwise create it
if [ ! -w $OUTPUT_DIRECTORY ]
then
@@ -259,6 +279,20 @@
PLAYLIST_PREFIX=${PLAYLIST_PREFIX:-$INPUTFILENAME}
SEGMENT_PREFIX=${SEGMENT_PREFIX:-$PLAYLIST_PREFIX}
+# The 'S' option allows segments and bitrate specific manifests to be placed in a subdir
+SEGMENT_DIRECTORY=${SEGMENT_DIRECTORY:-''}
+
+if [ ! "$SEGMENT_DIRECTORY" == "" ]
+then
+
+ if [ ! -d "${OUTPUT_DIRECTORY}/${SEGMENT_DIRECTORY}" ]
+ then
+ mkdir "${OUTPUT_DIRECTORY}/${SEGMENT_DIRECTORY}"
+ fi
+
+ SEGMENT_DIRECTORY+="/"
+fi
+
# Set the bitrate
if [ ! "$OP_BITRATES" == "" ]
then
@@ -273,33 +307,48 @@
createVariantPlaylist "$OUTPUT_DIRECTORY/${PLAYLIST_PREFIX}_master.m3u8"
for br in $OP_BITRATES
do
- appendVariantPlaylistentry "$OUTPUT_DIRECTORY/${PLAYLIST_PREFIX}_master.m3u8" "${PLAYLIST_PREFIX}_${br}.m3u8" "$br"
+ appendVariantPlaylistentry "$OUTPUT_DIRECTORY/${PLAYLIST_PREFIX}_master.m3u8" "${SEGMENT_DIRECTORY}${PLAYLIST_PREFIX}_${br}.m3u8" "$br"
done
+
+ OUTPUT_DIRECTORY+=$SEGMENT_DIRECTORY
# Now for the longer running bit, transcode the video
for br in $OP_BITRATES
do
- BITRATE="-b:v ${br}k -bufsize ${br}k"
+ BITRATE="-b:v ${br}k"
# Finally, lets build the output filename format
OUT_NAME="${SEGMENT_PREFIX}_${br}_%05d.ts"
PLAYLIST_NAME="$OUTPUT_DIRECTORY/${PLAYLIST_PREFIX}_${br}.m3u8"
-
+ SOURCE_FILE="$INPUTFILE"
echo "Generating HLS segments for bitrate ${br}k - this may take some time"
if [ "$NO_FORK" == "0" ] || [ "$LIVE_STREAM" == "1" ]
then
# Processing Starts
- createStream "$PLAYLIST_NAME" "$OUT_NAME" "$BITRATE" &
+ if [ "$IS_FIFO" == "1" ]
+ then
+ # Create a FIFO specially for this bitrate
+ SOURCE_FILE="$TMPDIR/hlsc.encode.$MYPID.$br"
+ mknod "$SOURCE_FILE" p
+ fi
+
+ # Schedule the encode
+ createStream "$PLAYLIST_NAME" "$OUT_NAME" "$BITRATE" "$SOURCE_FILE" &
PID=$!
PIDS=(${PIDS[@]} $PID)
BITRATE_PROCESSES=(${BITRATE_PROCESSES[@]} $br)
else
- createStream "$PLAYLIST_NAME" "$OUT_NAME" "$BITRATE"
+ createStream "$PLAYLIST_NAME" "$OUT_NAME" "$BITRATE" "$SOURCE_FILE"
fi
- # Will deal with exit statuses shortly.
- #|| exit 1
done
+
+ if [ "$IS_FIFO" == "1" ]
+ then
+ # If the input was a FIFO we need to read from it and push into the new FIFOs
+ cat "$INPUTFILE" | tee $(for br in $OP_BITRATES; do echo "$TMPDIR/hlsc.encode.$MYPID.$br"; done) > /dev/null &
+ TEE_PID=$!
+ fi
if [ "$NO_FORK" == "0" ] || [ "$LIVE_STREAM" == "1" ]
then
@@ -308,8 +357,19 @@
awaitCompletion
fi
+ if [ "$IS_FIFO" == "1" ]
+ then
+ for br in $OP_BITRATES
+ do
+ rm -f "$TMPDIR/hlsc.encode.$MYPID.$br";
+ done
+ # If we were interrupted, tee may still be running
+ kill $TEE_PID 2> /dev/null
+ fi
+
else
+ OUTPUT_DIRECTORY+=$SEGMENT_DIRECTORY
# No bitrate specified
# Finally, lets build the output filename format
@@ -320,8 +380,8 @@
# Processing Starts
- createStream "$PLAYLIST_NAME" "$OUT_NAME" "$BITRATE"
-
-
-fi
-
+ createStream "$PLAYLIST_NAME" "$OUT_NAME" "$BITRATE" "$INPUTFILE"
+
+
+fi
+
--- a/README.md
+++ b/README.md
@@ -43,8 +43,11 @@
-o [directory] Output directory (default: ./output)
-c [count] Number of segments to include in playlist (live streams only) - 0 is no limit
-b [bitrates] Output video Bitrates in kb/s (comma seperated list for adaptive streams)
+ -p [name] Playlist filename prefix
+ -t [name] Segment filename prefix
-l Input is a live stream
-f Foreground encoding only (adaptive non-live streams only)
+ -S Name of a subdirectory to put segments into
```