Skip to content

Instantly share code, notes, and snippets.

@iatrou
Created Jul 19, 2011
Embed
What would you like to do?
#!/usr/bin/env bash
# An oversimplistic HLS player
# Usage:
# $ hls.sh http://example.com/path/to/list.m3u8
CURLOPTS="--buffer --connect-timeout 2 --retry 3 --retry-max-time 3"
F="/tmp/.hls.$(mcookie).ts"
L="$(tempfile -d /tmp/ -p .hls.)"
LL="$(tempfile -d /tmp/ -p .hls.)"
# Download the segment and feed it to VLC
play_segment()
{
# The segment URLs can be absolute or relative to the current path
echo $1 | grep -q http
if [ $? -eq 1 ]; then
SS="$(dirname $P)/$1"
else
SS="$1"
fi
echo "Getting $SS"
curl $CURLOPTS $SS > $F
}
# On termination cleanup temporary files
exit_cleanup()
{
trap '' 0 1 2 15
rm -f $F $L $LL
exit 0
}
trap "exit_cleanup" 0 1 2 15
# Detect whether it's a master or variant playlist
curl $CURLOPTS "$1" > $L
M=$(grep m3u8$ $L)
if [ $? -eq 0 ]; then
# If it's a master, typically the first variant entry has the lower
# bitrate, play it safe
V=$(echo $M | tr ' ' '\n' | head -1)
P="$(dirname $1)/$V"
else
P="$1"
fi
echo "Using playlist: $P"
# Use a named pipe to pass the TS data from curl to VLC
mkfifo $F
vlc $F > /dev/null 2>&1 &
S=""
SS=""
while :; do
# Get the playlist and find the new/unused segments
curl $CURLOPTS $P > $L
S=$(diff -u $LL $L | grep -v ^+# | grep ^+ | grep -v ^+++ | sed -r 's/^\+//')
cat $L > $LL
if [ ! -z $SS ]; then
N="$(echo $S | tr ' ' '\n' | grep -n $SS | cut -f1 -d:)"
N=$((N+1))
T="$(echo $S | tr ' ' '\n' | tail -n +${N})"
fi
if [ ! -z "$T" ]; then
S="$T"
else
sleep 1
fi
for SS in $S; do
play_segment $SS
done
done
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment