#!/bin/bash

### Config ###

THREADS=2
PLAYLIST_URL="https://example.com:8000/playlist.m3u8?token=***"
SCREENSHOT_PATH="/var/lib/astra/mosaic"
API_PORT="8000"
API_AUTH="admin:******"

LEGACY=0

### Docs

# Script should be launched on the same server with Astra
#
# Options:
#
# - THREADS - number of threads with ffmpeg launched at once
# - PLAYLIST_URL - URL to HTTP Play playlist
# - SCREENSHOT_PATH - full path to directory with screenshots
# - API_PORT - primary port to Astra API and web interface
# - API_AUTH - admin login and password separated with colon
# - LEGACY - 0 for version 230501 and newer, for other versions set 1

### Script ###

# Check if the SCREENSHOT_PATH exists
if [ ! -d "$SCREENSHOT_PATH" ]; then
    echo "Error: \"$SCREENSHOT_PATH\" does not exist. Exiting"
    exit 1
fi

# Check API
call_api() {
    curl \
        -f -s -o /dev/null \
        -H "Content-Type: application/json" \
        -X POST -d "@-" \
        -u "$API_AUTH" \
        "http://127.0.0.1:$API_PORT/control/"
}

if ! echo "{\"cmd\":\"version\"}" | call_api ; then
    echo "Error: API not available"
    exit 1
fi

# Function to extract channel id from channel url
extract_channel_id() {
    echo "$1" |  awk -F'?' '{print $1}' | awk -F'/' '{print $5}'
}

# Function to create screenshot for a given channel url
create_screenshot() {
    CHANNEL_URL="$1"
    CHANNEL_ID=$(extract_channel_id "$CHANNEL_URL")
    IMG_PATH="$SCREENSHOT_PATH/$CHANNEL_ID.png"

    timeout 30 ffmpeg \
        -i "$CHANNEL_URL" \
        -v quiet \
        -ss 2 -y -t 1 -vframes 1 -vf scale=160:100 \
        -f image2 \
        "$IMG_PATH"

    if [ ! -f "$IMG_PATH" ] ; then
        return 0
    fi

    # Notify Cesbo Astra with an HTTP POST request
    if [ $LEGACY -eq 0 ]; then
        TIME=$(date +"%s")
        echo "{\"cmd\":\"set-stream-image\", \"id\":\"$CHANNEL_ID\", \"url\":\"/playlist/screenshots/$CHANNEL_ID.png?t=$TIME\"}" | call_api
    else
        IMG=$(cat $IMG_PATH | base64)
        echo "{\"cmd\":\"set-stream-image\", \"id\":\"$CHANNEL_ID\", \"url\":\"data:image/png;base64,$IMG\"}" | call_api
    fi
}

# Function to handle the termination signal
terminate_script() {
    echo "Terminating script..."
    exit 0
}

# Catch the termination signal
trap 'terminate_script' SIGINT

# Check if the script is being called for creating a screenshot
if [ "$1" == "create_screenshot" ]; then
    create_screenshot "$2"
    exit 0
fi

while true; do
    # Download the playlist and store it in a variable
    PLAYLIST=$(curl -s "$PLAYLIST_URL")

    # Check if the PLAYLIST is empty
    if [ -z "$PLAYLIST" ]; then
        echo "The playlist is empty. Waiting for 10 seconds before trying again."
        sleep 10
        continue
    fi

    # Extract channel urls from the playlist
    CHANNEL_URLS=$(echo "$PLAYLIST" | grep -oP '^http.*')

    # Launch create_screenshot in parallel
    echo "$CHANNEL_URLS" | xargs -I {} -P "$THREADS" bash "$0" create_screenshot {}

    sleep 1
done
