#!/bin/bash # .env contains a line like # BASE64_BEARER_TOKEN='' 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