diff --git a/download.sh b/download.sh index f62fa48..181dc0b 100755 --- a/download.sh +++ b/download.sh @@ -3,33 +3,78 @@ # .env contains a line like # BASE64_BEARER_TOKEN='' source .env -OUTFILE_PATTERN="./videos/video_INDEX.mp4" -API_URL='https://euwe-1.api.microsoftstream.com/api/videos?'\ -'$top=100&'\ -'$skip=0&'\ -'$orderby=metrics/trendingScore desc&'\ -'$filter=published and ((state eq %27Completed%27 and contentSource ne %27livestream%27) or (contentSource eq %27livestream%27 and not (state eq %27Completed%27 and not liveEvent/LiveEventOptions/OnDemandOptions/EnablePlayback)))&'\ -'api-version=1.4-private' -mkdir -p "$(dirname "${OUTFILE_PATTERN}")" || { echo -e '\033[31mAborting\033[m'; 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') +OUTFILE_PATTERN="./videos/video_INDEX.mp4" + +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 "$(dirname "${OUTFILE_PATTERN}")" || { 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' +) + +if [ -z "${m3u8_manifest_urls}" ]; 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=$(echo "${m3u8_manifest_urls}" | wc -l) -echo "${m3u8_manifest_urls}" | while IFS= read -r m3u8_manifest_url; do +total=$(printf '%s\n' "${m3u8_manifest_urls}" | wc -l) -m3u8_highest_res_url=$(curl -s "${m3u8_manifest_url}" | tail -n1 | rev | cut -c3- | rev | cut -d'&' -f2 | cut -c13- | sed 's/keyframes/fragments/g') +ISF="\n" +for m3u8_manifest_url in ${m3u8_manifest_urls}; do + 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' + ) -echo -e "\033[32mDownload video ${idx} of ${total}\033[m" + outfile="$(printf '%s' "${OUTFILE_PATTERN}" | sed "s/INDEX/${idx}/g")" -outfile="$(echo "${OUTFILE_PATTERN}" | sed "s/INDEX/${idx}/g")" - -# This doesn't work for some reason -# ffmpeg -loglevel 24 -headers "authorization: Bearer ${BASE64_BEARER_TOKEN}" -i "${m3u8_highest_res_url}" -c copy "${outfile}" -# Don't know what the f is going on, but it only works this hacky way -echo 'ffmpeg -loglevel 24 -headers "authorization: Bearer '${BASE64_BEARER_TOKEN}'" -i "'${m3u8_highest_res_url}'" -c copy "'${outfile}'"' | sh -echo -e "\033[33mDone\033[m" - -idx=$((idx+1)) + printf '\033[32m%s\033[m\n' "Download video ${idx} of ${total}" + ffmpeg -loglevel 24 -headers "authorization: Bearer ${BASE64_BEARER_TOKEN}" -i "${m3u8_highest_res_url}" -c copy "${outfile}" + printf '\033[33m%s\033[m\n' "Done" + idx=$(( idx + 1 )) done