218 lines
6.9 KiB
Bash
Executable File
218 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
MPVTV_DATA_DIR=${XDG_DATA_HOME:-$HOME/.local/share}/mpvtv
|
|
|
|
apiurl="https://epg.pw"
|
|
RESPONSE1_FILE="${MPVTV_DATA_DIR}/response1.txt"
|
|
RESPONSE2_FILE="${MPVTV_DATA_DIR}/response2.txt"
|
|
RESPONSE3_FILE="${MPVTV_DATA_DIR}/response3.txt"
|
|
COOKIES_FILE="${MPVTV_DATA_DIR}/cookies.txt"
|
|
CHANNELS_FILE="${MPVTV_DATA_DIR}/channels.txt"
|
|
SCHEDULE_FILE="${MPVTV_DATA_DIR}/schedule.json"
|
|
CORRECT_SCHEDULE_FILE="${MPVTV_DATA_DIR}/correct_schedule.json"
|
|
M3U8_FILE="${MPVTV_DATA_DIR}/m3u8.txt"
|
|
USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0"
|
|
ACCEPT="Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
|
|
MPV_OPTS='--vo=gpu \
|
|
--gpu-api=opengl \
|
|
--opengl-es=yes \
|
|
--really-quiet \
|
|
--msg-level=all=no \
|
|
--no-load-scripts \
|
|
--profile=sw-fast \
|
|
--no-ytdl \
|
|
--http-header-fields="User-Agent: '"$USER_AGENT"'" \
|
|
--fs'
|
|
|
|
mkdir -p "${MPVTV_DATA_DIR}"
|
|
|
|
function usage {
|
|
echo "Usage: $(basename "$0") [stream|schedule]"
|
|
exit 0
|
|
}
|
|
|
|
function curlRequest {
|
|
local url="$1"
|
|
shift
|
|
response="$(curl -s -L \
|
|
-c "$COOKIES_FILE" \
|
|
-b "$COOKIES_FILE" \
|
|
"$url" \
|
|
-A "$USER_AGENT" \
|
|
-H "$ACCEPT" \
|
|
"$@"
|
|
)"
|
|
|
|
exit_code="$?"
|
|
if [[ "$exit_code" -ne 0 ]]; then
|
|
echo "Error: Failed to execute curl request."
|
|
exit 1
|
|
fi
|
|
echo "$response"
|
|
}
|
|
|
|
function clearFiles {
|
|
[[ -f "$RESPONSE2_FILE" ]] && rm "$RESPONSE2_FILE"
|
|
[[ -f "$RESPONSE3_FILE" ]] && rm "$RESPONSE3_FILE"
|
|
[[ -f "$SCHEDULE_FILE" ]] && rm "$SCHEDULE_FILE"
|
|
[[ -f "$CORRECT_SCHEDULE_FILE" ]] && rm "$CORRECT_SCHEDULE_FILE"
|
|
}
|
|
|
|
[[ "$#" -lt 1 ]] && usage
|
|
[[ "$#" -gt 1 ]] && usage
|
|
if [[ "$#" -eq 1 ]]; then
|
|
if [[ "$1" != "stream" ]] && [[ "$1" != "schedule" ]]; then
|
|
usage
|
|
fi
|
|
fi
|
|
|
|
if [[ ! -f "$RESPONSE1_FILE" ]]; then
|
|
response="$(curlRequest "$apiurl/areas/gb.html?lang=en")"
|
|
echo "$response" > "$RESPONSE1_FILE"
|
|
fi
|
|
|
|
# shellcheck disable=SC1143
|
|
if [[ ! -f "$CHANNELS_FILE" ]]; then
|
|
CHANNELS="$(
|
|
sed '1,/<tbody>/d' "$RESPONSE1_FILE" | \
|
|
sed '/<\/table>/,$d' | \
|
|
awk '/<tr>/ {block = ""} {block = block $0 "\n"} /<\/tr>/ {if (!(block ~ /<td>0<\/td>/)) print block}' | \
|
|
sed '/^[[:space:]]*$/d' | \
|
|
awk 'NF {print $0}' | \
|
|
sed 's/^[[:space:]]*//' | \
|
|
sed 'N;/\n<\/tr>/!P;D' | \
|
|
# awk '/<tr>/ {block=""; count=0} {block=block $0 "\n"} /<\/tr>/ {if (count >= 2) block=""; else printf "%s", block; block=""; next} /<td><\/td>/ {count++}' | \
|
|
# awk 'NR==1 {prev=$0; next} /<td><\/td>/ {prev=""; next} {if (prev) print prev; prev=$0} END {if (prev) print prev}' | \
|
|
sed '/<td>SkyTV<\/td>/d' | \
|
|
sed -n '/href=/ {s/.*href="\([^"]*\)".*/\1/p; b}; p' | \
|
|
sed -n '/title=/ {s/.*>\(.*\)<\/a>/\1/p; b}; p' | \
|
|
sed '/<tr>/d; /<\/tr>/d; /<td>/d' | \
|
|
sed 's/<\/td>//g' | \
|
|
awk 'NR%2{printf "%s ", $0; next} 1' | \
|
|
awk '!seen[$2]++'
|
|
)"
|
|
|
|
echo "$CHANNELS" > "$CHANNELS_FILE"
|
|
fi
|
|
|
|
function getSchedule {
|
|
if [[ ! -f "$CORRECT_SCHEDULE_FILE" ]]; then
|
|
echo "Nothing to get"
|
|
exit 0
|
|
fi
|
|
|
|
channel_name="$(jq -r '.name' "$CORRECT_SCHEDULE_FILE")"
|
|
echo -e "Schedule for $channel_name\n"
|
|
|
|
# Get the current time in your local time zone in the format used in start_date
|
|
current_time=$(date +"%d-%m-%Y %H:%M")
|
|
|
|
# Print the current time
|
|
echo "Current Time: $current_time"
|
|
|
|
# Use jq to find the item with the closest start_date and calculate time differences in a readable format
|
|
closest_item=$(jq --arg current_time "$current_time" '
|
|
.epg_list
|
|
| map(
|
|
.start_date |= sub(" \\+0200"; "")
|
|
| .current_time_parsed = ($current_time | strptime("%d-%m-%Y %H:%M") | mktime)
|
|
| .start_time_parsed = (try (.start_date | strptime("%d-%m-%Y %H:%M") | mktime) catch 99999999)
|
|
| .time_diff = (.start_time_parsed - .current_time_parsed)
|
|
| .abs_time_diff = (if .time_diff < 0 then -(.time_diff) else .time_diff end)
|
|
)
|
|
| sort_by(.abs_time_diff)
|
|
| map(
|
|
.hours_diff = (.time_diff / 3600 | floor)
|
|
| .minutes_diff = ((.time_diff % 3600) / 60 | floor)
|
|
| .seconds_diff = (.time_diff % 60 | floor)
|
|
| .time_diff_readable = (.hours_diff | tostring) + " hours, " + (.minutes_diff | tostring) + " minutes, " + (.seconds_diff | tostring) + " seconds"
|
|
)
|
|
| .[0]
|
|
' "$CORRECT_SCHEDULE_FILE")
|
|
|
|
echo "Closest Item:"
|
|
echo "$closest_item"
|
|
exit 0
|
|
}
|
|
|
|
function getChannel {
|
|
|
|
CHANNEL_SELECTED="$(awk '{for (i=2; i<=NF; i++) printf "%s ", $i; print ""}' "$CHANNELS_FILE" | fuzzel -d -p "Channel? ")"
|
|
if [[ -z "$CHANNEL_SELECTED" ]]; then
|
|
echo "Nothing selected"
|
|
exit 0
|
|
else
|
|
CHANNEL_SELECTED="$(echo "$CHANNEL_SELECTED" | awk '{$1=$1};1')"
|
|
CHANNEL_LINE="$(grep -n "$CHANNEL_SELECTED" "$CHANNELS_FILE" | awk -F: '{print $1}')"
|
|
CHANNEL_URL="$(sed -n "${CHANNEL_LINE}"p "$CHANNELS_FILE" | cut -d' ' -f1)"
|
|
CHANNEL_URL="${apiurl}${CHANNEL_URL}"
|
|
fi
|
|
|
|
if [[ -f "$CORRECT_SCHEDULE_FILE" ]]; then
|
|
mydate="$(date '+%Y-%m-%d')"
|
|
schedule_end_date="$(jq -r '.end_date' "$CORRECT_SCHEDULE_FILE")"
|
|
timestamp1="$(date -d "$mydate" +%s)"
|
|
timestamp2="$(date -d "$schedule_end_date" +%s)"
|
|
|
|
if [[ "$timestamp1" -gt "$timestamp2" ]]; then
|
|
echo "Fetching new data"
|
|
clearFiles
|
|
fi
|
|
fi
|
|
|
|
if [[ -f "$CORRECT_SCHEDULE_FILE" ]]; then
|
|
PREVIOUS_CHANNEL="$(jq -r '.name' "$CORRECT_SCHEDULE_FILE")"
|
|
if [[ "$PREVIOUS_CHANNEL" == "$CHANNEL_SELECTED" ]]; then
|
|
echo "No need for new stuff"
|
|
play
|
|
exit 0
|
|
else
|
|
clearFiles
|
|
fi
|
|
fi
|
|
|
|
if [[ ! -f "$RESPONSE2_FILE" ]]; then
|
|
response2="$(curlRequest "$CHANNEL_URL")"
|
|
echo "$response2" > "$RESPONSE2_FILE"
|
|
fi
|
|
|
|
CHANNEL_LIVE="$(grep livestream "$RESPONSE2_FILE" | sed 's/^[[:space:]]*//' | sed -n '/href=/ {s/.*href="\([^"]*\)".*/\1/p; b}; p' )"
|
|
CHANNEL_LIVE="${apiurl}${CHANNEL_LIVE}"
|
|
|
|
if [[ ! -f "$RESPONSE3_FILE" ]]; then
|
|
response3="$(curlRequest "$CHANNEL_LIVE")"
|
|
echo "$response3" > "$RESPONSE3_FILE"
|
|
fi
|
|
|
|
M3U8_LINK="$(grep m3u8 "$RESPONSE3_FILE" | sed 's/^[[:space:]]*//' | grep -v href | head -n1 | sed -n 's/.*"\([^"]*\)".*/\1/p')"
|
|
|
|
echo "$M3U8_LINK" > "$M3U8_FILE"
|
|
SCHEDULE="$(grep json "$RESPONSE2_FILE" | sed 's/^[[:space:]]*//' | grep -v "Content-Type" | grep -v "class" | sed 's/\(.*\)<\/a.*/\1/')"
|
|
[[ -z "$SCHEDULE" ]] && echo "Nothing there" && exit 0
|
|
|
|
if [[ ! -f "$SCHEDULE_FILE" ]]; then
|
|
response4="$(curlRequest "$SCHEDULE")"
|
|
echo "$response4" > "$SCHEDULE_FILE"
|
|
fi
|
|
|
|
if [[ ! -f "$CORRECT_SCHEDULE_FILE" ]]; then
|
|
jq '.epg_list |= map(if .start_date then .start_date |= (sub(" +0000"; "") | strptime("%Y%m%d%H%M%S") | mktime | . + 7200 | strftime("%d-%m-%Y %H:%M +0200")) else . end)' "$SCHEDULE_FILE" > "$CORRECT_SCHEDULE_FILE"
|
|
fi
|
|
|
|
play
|
|
|
|
}
|
|
|
|
function play {
|
|
STREAM_LINK="$(cat "$M3U8_FILE")"
|
|
notify-send -t 2000 "Loading $CHANNEL_SELECTED"
|
|
MPVPID="$(pidof mpv | cut -d' ' -f1)"
|
|
[[ -n "$MPVPID" ]] && kill -s SIGTERM "$MPVPID"
|
|
eval setsid -f "mpv ${MPV_OPTS} ${STREAM_LINK}"
|
|
}
|
|
|
|
[[ "$1" == "schedule" ]] && getSchedule
|
|
[[ "$1" == "stream" ]] && getChannel
|
|
|
|
exit 0
|