msstreamdownloader/download.sh

92 lines
2.7 KiB
Bash
Executable File

#!/bin/bash
# .env contains a line like
# BASE64_BEARER_TOKEN='<literal base64 encoded string>'
source .env
OUTDIR="./videos"
read -r -d '' API_URL <<- 'EOM'
https://euwe-1.api.microsoftstream.com/api/videos?
$top=100
&
$skip=0
&
$orderby=metrics/trendingScore desc
&
$filter=
published{SPACE}
and{SPACE}
(
(
state eq 'Completed' and contentSource ne 'livestream'
){SPACE}
or{SPACE}
(
contentSource eq 'livestream'{SPACE}
and not
(
state eq 'Completed'{SPACE}
and not
liveEvent/LiveEventOptions/OnDemandOptions/EnablePlayback
)
)
)
&
api-version=1.4-private
EOM
API_URL="$(
printf '%s' "${API_URL}" |
sed 's/{SPACE}/ /g' |
tr -d '\n'
)"
mkdir -p "${OUTDIR}" || { printf '\033[31m%s\033[m\n' 'Aborting'; exit; }
# '>' without quotes is delimiter, since it's one of the few chars disallowed in a URL. Title must not include this char
# https://www.ietf.org/rfc/rfc2396.txt
# 2.4.3. Excluded US-ASCII Characters
m3u8_manifest_urls_and_metadata=$(
wget --no-verbose --quiet -O- --header="authorization: Bearer ${BASE64_BEARER_TOKEN}" "${API_URL}" |
jq -r '.value[] | .name + ">" + .media.duration[2:] + ">" + (.playbackUrls | map(select(.mimeType == "application/vnd.apple.mpegurl")) | .[].playbackUrl)'
)
if [ -z "${m3u8_manifest_urls_and_metadata}" ]; then
printf '\033[31m%s\033[m\n' 'Error GETting manifest urls (response empty) or Bearer token invalid/expired. Exiting.'
exit
fi
idx=1
total="$(printf '%s\n' "${m3u8_manifest_urls_and_metadata}" | wc -l)"
for m3u8_manifest_url_and_metadata in ${m3u8_manifest_urls_and_metadata}; do
IFS='>' read -ra META <<< "${m3u8_manifest_url_and_metadata}"
title="${META[0]}"
length="${META[1]}"
length="$(echo "${length}" | sed -e 's/\..*S/S/g' -e 's/M/:/g' -e 's/H/:/g')"
m3u8_manifest_url="${META[2]}"
m3u8_highest_res_url="$(
curl --silent "${m3u8_manifest_url}" |
tail -n1 |
rev |
cut -c3- |
rev |
cut -d'&' -f2 |
cut -c13- |
sed 's/keyframes/fragments/g'
)"
filepath="${OUTDIR}/${title}.mp4"
printf '\033[32m%s\033[m\n' "Download '${filepath}' (${idx}/${total})"
ffmpeg -hide_banner -loglevel error -headers "authorization: Bearer ${BASE64_BEARER_TOKEN}" -i "${m3u8_highest_res_url}" -progress - -c copy "${filepath}" | grep --line-buffered 'out_time=' | sed -u -e 's/out_time=//g' -e 's/\..*//g' -e 's/^-//g' | xargs -I{} printf "{} of ${length} \r"
printf '\n\033[33m%s\033[m\n' "Done"
idx=$(( idx + 1 ))
done