From 12612a5008a6e95d8b43a4b497046d8f4c734cad Mon Sep 17 00:00:00 2001 From: tosu Date: Thu, 2 Mar 2023 22:45:22 +0100 Subject: [PATCH] Even better progress indication --- download.sh | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/download.sh b/download.sh index 972fb49..a49659e 100755 --- a/download.sh +++ b/download.sh @@ -4,7 +4,7 @@ # BASE64_BEARER_TOKEN='' source .env -OUTFILE_PATTERN="./videos/video_INDEX.mp4" +OUTDIR="./videos" read -r -d '' API_URL <<- 'EOM' https://euwe-1.api.microsoftstream.com/api/videos? @@ -42,24 +42,34 @@ API_URL="$( tr -d '\n' )" -mkdir -p "$(dirname "${OUTFILE_PATTERN}")" || { printf '\033[31m%s\033[m\n' 'Aborting'; exit; } +mkdir -p "${OUTDIR}" || { printf '\033[31m%s\033[m\n' 'Aborting'; exit; } -m3u8_manifest_urls=$( - wget --no-verbose --quiet -O- --header="authorization: Bearer ${BASE64_BEARER_TOKEN}" "${API_URL}" | \ - jq -r '.value[].playbackUrls | map(select(.mimeType == "application/vnd.apple.mpegurl")) | .[].playbackUrl' +# '>' 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}" ]; then +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}" | wc -l) +total="$(printf '%s\n' "${m3u8_manifest_urls_and_metadata}" | wc -l)" ISF="\n" -for m3u8_manifest_url in ${m3u8_manifest_urls}; do - m3u8_highest_res_url=$( +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 | @@ -68,13 +78,13 @@ for m3u8_manifest_url in ${m3u8_manifest_urls}; do cut -d'&' -f2 | cut -c13- | sed 's/keyframes/fragments/g' - ) + )" - outfile="$(printf '%s' "${OUTFILE_PATTERN}" | sed "s/INDEX/${idx}/g")" + filepath="${OUTDIR}/${title}.mp4" - printf '\033[32m%s\033[m\n' "Download '${outfile}' (${idx}/${total})" + 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 "${outfile}" | grep --line-buffered 'out_time=' | sed -u -e 's/out_time=//g' | xargs -I{} printf '{}\r' + 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"