#!/bin/sh
#echo START $0 $* 1>&2
# Generate in-line audio player code, both vanilla HTML5 and AMP:
#   $1 must be the operation to perform.
#   $2 must be the declared (external) audio file path name.
#   $3 must be the source document that this HTML is being created for.
#      Mainly used for error messages.
#   $4 must be the static host prefix ($4$2 should be external URL for audio).
#   $5 must be "false" if desktop, "true" if HTML5 mobile, "offline" or "amp".
#   $6 must be the ordinal of this audio/video on the page, eg 1 for the first,
#      or can start at 2 if deep below the fold.
#
# Additional parameters may be supplied for some operations.
#
# The object will get labelled as ID mo-$6 (multimedia object).
#
if [ $# -lt 5 ]; then
    echo "ERROR: missing parameter(s), have: $@" 1>&2
    exit 2
fi

# The default format is MP3 for maximum compatibility with browsers.
# DHD20250901: now Opus is offered ahead of MP3 to the audio player.

OP="$1"
AUDIOFILE="$2"
ARTBODY="$3"
STATICCDNPREFIX="$4"
MOBILE="$5"
ORDINAL="$6"

#echo "INFO: $0 OP=$OP AUDIOFILE=$AUDIOFILE ARTBODY=$ARTBODY STATICCDNPREFIX=$STATICCDNPREFIX MOBILE=$MOBILE ORDINAL=$ORDINAL" 1>&2

# Some simple parameter validation.
if [ "" = "$OP" ]; then
    echo "ERROR: missing OP" 1>&2
    exit 2
fi
if [ "" = "$STATICCDNPREFIX" ]; then
    echo "ERROR: missing STATICCDNPREFIX" 1>&2
    exit 2
fi

if [ ! -s $AUDIOFILE ]; then
    echo "ERROR: missing AUDIOFILE $AUDIOFILE" 1>&2
    exit 1
fi


# Load in default URLs/locations.
. script/SITE.loc

# DHD20190613: temporarily hacked in: should be passed in as arg.
# Secure server prefix for static objects.
# Can be HOSTMAIN https connection in due course.
#SECURESTATICCDNPREFIX=https://www.jworkers.co.uk/ext/e/
#SECURESTATICCDNPREFIX=https://static.earth.org.uk/
SECURESTATICCDNPREFIX=${DEFAULTSECURESTATICCDNPREFIX}

# VTTFILE is path to EOU-local WebVTT captioning file, if present.
VTTFILE=""

# Page about licensing of photos, etc.
LICENSINGURL="/about-us.html#License"


# Returns on stdout the HTML to insert in the document; empty if none.
# There may be non-error cases where an empty value is returned,
# eg we may not always want to generate a hero image for mobile.
# In case of error this returns a non-zero value.
#
# Supported operations:
#
#  simpleAudioEmbed
#     Simple single-source audio player embedded in page.
#
#  simpleAudioEmbedWithTranscript
#     As simpleAudioEmbed but immediately followed with
#         texttexttextoftranscript...</blockquote></div>
#     so body ends to bring the text in as a transcript.
#
#  simpleAudioEmbedWithTranscriptInDetails
#     As simpleVideoEmbedWithTranscript but immediately followed with
#         texttexttextoftranscript...</blockquote></details></div>
#     so body ends to bring the text in as a transcript in a details block.
#

#============================

case $OP in


simpleAudioEmbed*) #-------------------------------------------
#  simpleAudioEmbed
#  simpleAudioEmbedWithTranscript
#  simpleAudioEmbedWithTranscriptInDetails
#
# Note that a low-fi "L" version of the file is looked for, and linked,
# as well as a lossless (and fully-open codec) .flac version.

        MIMETYPE=""
        ABV=""
        # MIME type of primary source (rejected if unknown).
        case $AUDIOFILE in
            *.flac) MIMETYPE="audio/flac";  ABV="FLAC";;
            *.m4a)  MIMETYPE="audio/mp4";   ABV="M4A";; # Firefox needs .mp4.
            *.mp3)  MIMETYPE="audio/mpeg";  ABV="MP3";;
            *.mp4)  MIMETYPE="audio/mp4";   ABV="MP4";;
            *.ogg)  MIMETYPE="audio/ogg";   ABV="Ogg";;
            #*.opus) MIMETYPE="audio/opus";  ABV="Opus";;
            *.opus) MIMETYPE="audio/ogg;codecs=opus";   ABV="Opus";;
            *.wav)  MIMETYPE="audio/wav";   ABV="WAV";;
            # Allow upper-case WAV for easiest compatibility with ZOOM H1n.
            *.WAV)  MIMETYPE="audio/wav";   ABV="WAV";;
            *) echo "ERROR: unknown audio type for $AUDIOFILE" 1>&2; exit 1;;
        esac

        # By default use the primary file as the source of any lo-fi conversion.
        AUDIOFILECONVERTSRC="$AUDIOFILE"

        # Default URL prefix.
        PREFIX=$STATICCDNPREFIX
        if [ "false" = "$MOBILE" ]; then
            # No prefix needed for desktop.
            PREFIX=""
        elif [ "offline" = "$MOBILE" -o "amp" = "$MOBILE" ]; then
            # Force https:// address for offline / AMP.
            PREFIX=$SECURESTATICCDNPREFIX
        else
            # Strip scheme to leave protocol-relative form for lite.
            PREFIX="`echo $PREFIX | sed -e 's/^http[a-z]*://'`"
            #echo "INFO: $0: stripped scheme $PREFIX for $ARTBODY." 1>&2
        fi

        # Base including trailing '.'.
        AUDIOFILEBASE="`echo $AUDIOFILE | sed -e 's/\.[^.\/ ]*$/./'`"

        # Check if a lossless (hi-fi) source version is available.
        # Can both be linked to and be a fallback in the audio tag.
        # If present will be used as the source for creating lo-fi versions.
        AUDIOFILEHIFI=""
        AUDIOFILEHIFITYPE=""
        AUDIOFILEHIFIHUMANTYPE=""
        AUDIOFILEHIFISOURCE=""
        # FLAC is preferred (as more compact) but WAV also accepted.
        AUDIOFILEHIFIBASE="$AUDIOFILEBASE"
        AUDIOFILEHIFIFLAC="${AUDIOFILEHIFIBASE}flac"
        AUDIOFILEHIFIWAV="${AUDIOFILEHIFIBASE}wav"
        # Allow all-upper-case for easiest compatibility with ZOOM H1n.
        AUDIOFILEHIFIWAVu="${AUDIOFILEHIFIBASE}WAV"
        # Use high-fi form as a fall-back audio source for browsers
        # that don't handle the primary type for some reason.
        # This file must be different to the primary version to be used.
        # It must also exist and not be zero length.
        if [ "$AUDIOFILEHIFIFLAC" != "$AUDIOFILE" -a -s "$AUDIOFILEHIFIFLAC" ]; then
            AUDIOFILECONVERTSRC="$AUDIOFILEHIFIFLAC"
            AUDIOFILEHIFI="$AUDIOFILEHIFIFLAC"
            AUDIOFILEHIFITYPE="audio/flac"
            AUDIOFILEHIFIHUMANTYPE="FLAC"
            AUDIOFILEHIFISOURCE="<source src=$PREFIX$AUDIOFILEHIFI type=audio/flac>"
        elif [ "$AUDIOFILEHIFIWAV" != "$AUDIOFILE" -a "$AUDIOFILEHIFIWAVu" != "$AUDIOFILE" -a -s "$AUDIOFILEHIFIWAV" ]; then
            AUDIOFILEHIFI="$AUDIOFILEHIFIWAV"
            AUDIOFILEHIFITYPE="audio/wav"
            AUDIOFILEHIFIHUMANTYPE="WAV"
            AUDIOFILEHIFISOURCE="<source src=$PREFIX$AUDIOFILEHIFI type=audio/wav>"
        elif [ "$AUDIOFILEHIFIWAV" != "$AUDIOFILE" -a "$AUDIOFILEHIFIWAVu" != "$AUDIOFILE" -a -s "$AUDIOFILEHIFIWAVu" ]; then
            AUDIOFILECONVERTSRC="$AUDIOFILEHIFIWAVu"
            AUDIOFILEHIFI="$AUDIOFILEHIFIWAVu"
            AUDIOFILEHIFITYPE="audio/wav"
            AUDIOFILEHIFIHUMANTYPE="WAV"
            AUDIOFILEHIFISOURCE="<source src=$PREFIX$AUDIOFILEHIFI type=audio/wav>"
        fi

        # Find or generate a standard lo-fi MP3 version.
        LOFIMP3=""
        # Higher-fi version of the output file, if this is an 'L' file,
        # else input or lossless version.
        if [ -s "${AUDIOFILE}L" ]; then
            LOFIMP3="${AUDIOFILE}L";
        else
            # Attempt to generate a .mp3L.
            PUTATIVEMP3L="$(sh script/audioBuildLossy.sh "${AUDIOFILECONVERTSRC}" mp3L)"
            if [ "" != "$PUTATIVEMP3L" ] && [ -s "$PUTATIVEMP3L" ] && [ "$(wc -c < "$PUTATIVEMP3L")" -lt "$(wc -c < "$AUDIOFILE")" ]; then
                LOFIMP3="$PUTATIVEMP3L"
            fi
        fi

        # Use the lo-fi version as primary for non-desktop, if available.
        PRIMARYAUDIO="${AUDIOFILE}"
        if [ "false" != "$MOBILE" ]; then
            if [ "" != "$LOFIMP3" ]; then PRIMARYAUDIO="$LOFIMP3"; fi
        fi

        # Check if a MIDI version is available.
        AUDIOFILEMIDI=""
        AUDIOFILEMIDITYPE=""
        AUDIOFILEMIDIHUMANTYPE=""
        #AUDIOFILEMIDISOURCE=""
        AUDIOFILEMIDIBASE="$AUDIOFILEBASE"
        AUDIOFILEMIDIFILE="${AUDIOFILEMIDIBASE}mid"
        if [ "$AUDIOFILEMIDIFILE" != "$AUDIOFILE" -a -s "$AUDIOFILEMIDIFILE" ]; then
            AUDIOFILEMIDI="$AUDIOFILEMIDIFILE"
            AUDIOFILEMIDITYPE="audio/midi"
            AUDIOFILEMIDIHUMANTYPE="MIDI"
            #AUDIOFILEMIDISOURCE="<source src=$PREFIX$AUDIOFILEMIDI type=\"audio/midi\">"
        fi

        # Check if a super-lo-fi non-MP3 (Opus) source version is available.
        # Can both be linked to and be a fallback in the audio tag.
        # Can also be used in the RSS podcast as an alternateEnclosure.
        # For the moment this can only be a .opusL file.
        # Try to auto-generate if one is not checked in beside the primary.
        AUDIOFILELOWESTFI=""
        AUDIOFILELOWESTFITYPE=""
        AUDIOFILELOWESTFIHUMANTYPE=""
        AUDIOFILELOWESTFISOURCE=""
        AUDIOFILELOWESTFIBASE="$AUDIOFILEBASE"
        AUDIOFILELOWESTFIOPUS="${AUDIOFILELOWESTFIBASE}opusL"
        if [ "$AUDIOFILELOWESTFIOPUS" != "$AUDIOFILE" -a -s "$AUDIOFILELOWESTFIOPUS" ]; then
            AUDIOFILELOWESTFI="$AUDIOFILELOWESTFIOPUS"
        elif [ -s script/audioBuildLossy.sh ]; then
            # Attempt to auto-generate.
            AUDIOFILELOWESTFIOPUS="$(sh script/audioBuildLossy.sh "$AUDIOFILECONVERTSRC" opusL)"
            if [ "" != "$AUDIOFILELOWESTFIOPUS" ] && [ -s "$AUDIOFILELOWESTFIOPUS" ]; then
                AUDIOFILELOWESTFI="$AUDIOFILELOWESTFIOPUS"
            fi
        fi
        if [ "" != "$AUDIOFILELOWESTFI" ]; then
            AUDIOFILELOWESTFITYPE="audio/opus"
            AUDIOFILELOWESTFIHUMANTYPE="Opus"
            AUDIOFILELOWESTFISOURCE="<source src=$PREFIX$AUDIOFILELOWESTFI type=\"audio/ogg;codecs=opus\">"
        fi

        # Check if a medium-fi non-MP3 (Opus) source version is available.
        # Can both be linked to and be a fallback in the audio tag.
        # Can also be used in the RSS podcast as an alternateEnclosure.
        # For the moment this can only be a .opus file.
        # Try to auto-generate if one is not checked in beside the primary.
        AUDIOFILEALTMEDIUMFI=""
        AUDIOFILEALTMEDIUMFITYPE=""
        AUDIOFILEALTMEDIUMFIHUMANTYPE=""
        AUDIOFILEALTMEDIUMFISOURCE=""
        AUDIOFILEALTMEDIUMFIBASE="$AUDIOFILEBASE"
        AUDIOFILEALTMEDIUMFIOPUS="${AUDIOFILEALTMEDIUMFIBASE}opus"
        if [ "$AUDIOFILEALTMEDIUMFIOPUS" != "$AUDIOFILE" -a -s "$AUDIOFILEALTMEDIUMFIOPUS" ]; then
            AUDIOFILEALTMEDIUMFI="$AUDIOFILEALTMEDIUMFIOPUS"
        elif [ -s script/audioBuildLossy.sh ]; then
            # Attempt to auto-generate.
            AUDIOFILEALTMEDIUMFIOPUS="$(sh script/audioBuildLossy.sh "$AUDIOFILECONVERTSRC" opus)"
            # Only use auto-generated result if smaller than original/default.
            if [ "" != "$AUDIOFILEALTMEDIUMFIOPUS" ] && [ -s "$AUDIOFILEALTMEDIUMFIOPUS" ] && [ "$(wc -c < "$AUDIOFILEALTMEDIUMFIOPUS")" -lt "$(wc -c < "$AUDIOFILE")" ] ; then
                AUDIOFILEALTMEDIUMFI="$AUDIOFILEALTMEDIUMFIOPUS"
            fi
        fi
        if [ "" != "$AUDIOFILEALTMEDIUMFI" ]; then
            AUDIOFILEALTMEDIUMFITYPE="audio/opus"
            AUDIOFILEALTMEDIUMFIHUMANTYPE="Opus"
            AUDIOFILEALTMEDIUMFISOURCE="<source src=$PREFIX$AUDIOFILEALTMEDIUMFI type=\"audio/ogg;codecs=opus\">"
        fi

        # INFOFILE is path to text/info file, if present.
        INFOFILE="$AUDIOFILE.txt"
        if [ ! -s "$INFOFILE" ]; then INFOFILE=""; fi

        # VTTFILE is path to EOU-local WebVTT captioning file, if present.
        VTTFILE="$AUDIOFILE.vtt"
        if [ ! -s "$VTTFILE" ]; then VTTFILE=""; fi

        # Text for alt/title/caption.
        ALT="`script/altTextFromFilename $AUDIOFILE`"

        # Suppress preload except for desktop (offline/lite/AMP).
        # Suppress preload for anything other than the first track on a page.
        PRELOAD="preload=metadata "
        if [ "false" != "$MOBILE" ] || [ "1" != "$ORDINAL" ]; then
            PRELOAD="preload=none ";
        fi

        # Insert subtitles/captions if available.
        # DHD20250609: Note that currently browsers ignore 'track' within audio.
        CAPTIONTAG=""
        if [ "" != "$VTTFILE" ]; then
            CAPTIONTAG="<track default kind=captions srclang=en-gb label=English src=$PREFIX$VTTFILE>"
        fi

        # Drop heavy hint about lite mode on first desktop instance.
        if [ "false" = "$MOBILE" ] && [ "1" = "$ORDINAL" ] && [ "" != "$AUDIOFILELOWESTFI" ]; then
            printf '<div class=dmob style=font-size:smaller><aside>(Slow or expensive connection? Switch to the <a href="//m.earth.org.uk/%s">mobile/lite view</a>.)</aside></div>' "$(echo $ARTBODY | sed -e 's/^[.]//')"
        fi

        # cross-origin anon access (for VTT file) for non-desktop to www host.
        XOANON="" # Trailing whitespace when non-empty.
        if [ "false" != "$MOBILE" ]; then
            XOANON="crossorigin " # Equivalent to =anonymous
        fi

        printf "<div id=mo-%d itemprop=audio itemscope itemtype=http://schema.org/AudioObject>" "$ORDINAL"
        if [ "amp" != "$MOBILE" ]; then
            # Normal HTML5.
            LATEAUDIOFILELOWESTFISOURCE="$AUDIOFILELOWESTFISOURCE"
            EARLYAUDIOFILELOWESTFISOURCE=""
            if [ "false" != "$MOBILE" ]; then
                # For non-desktop (eg lite) have Opus as default.
                LATEAUDIOFILELOWESTFISOURCE=""
                EARLYAUDIOFILELOWESTFISOURCE="$AUDIOFILELOWESTFISOURCE"
            fi
            # Have player fall back first to very-lo-fi then hi-fi formats.
            # Have player try medium-fi alternate (small) ahead of default.
            printf "<audio title=\"$ALT\" id=vtt-player-a$ORDINAL style=display:block;max-width:100%% ${PRELOAD}${XOANON}controls>$EARLYAUDIOFILELOWESTFISOURCE$AUDIOFILEALTMEDIUMFISOURCE<source src=$PREFIX$PRIMARYAUDIO type=$MIMETYPE>$LATEAUDIOFILELOWESTFISOURCE$AUDIOFILEHIFISOURCE$CAPTIONTAG<div>Your browser does not support HTML5 audio.</div></audio>"
            # For desktop, the first AUDIO tag can have captions.
            if [ "false" = "$MOBILE" ] && [ "" != "$VTTFILE" ] && [ "1" = "$ORDINAL" ]; then
                # DHD20250609: see https://james.cridland.net/blog/2025/html-audio-player-with-captions/
                # DHD20250609: create space to display caption text in.
                #printf "<div style=display:none;text-align:center;font-family:monospace;font-weight:bold;text-wrap:balance id=vtt-text-a%d></div>" "$ORDINAL"
                printf "<div style=display:none;text-align:center;font-family:monospace;font-weight:bold;min-height:15ex id=vtt-text-a%d></div>" "$ORDINAL"
                # JS to support this for first audio tag (#1) on page.
                printf "<script async src=//WWW.earth.org.uk/script/audio_inline_captions_1.min.js></script>"
                #printf "<script>"
                #printf "document.getElementById('vtt-player-a%d').textTracks[0].mode=\"showing\";" "$ORDINAL"
                #printf "document.getElementById('vtt-player-a%d').addEventListener('play', function() { document.getElementById('vtt-text-a%d').style.display=\"block\"; });" "$ORDINAL" "$ORDINAL"
                #printf "document.getElementById('vtt-player-a%d').textTracks[0].addEventListener('cuechange', function() { document.getElementById('vtt-text-a%d').innerText = this.activeCues[0].text; });" "$ORDINAL" "$ORDINAL"
                #printf "</script>"
            fi
        else
            # AMP
            printf "<amp-audio title=\"$ALT\" style=display:block;max-width:100%% ${PRELOAD}controls><source src=$PREFIX$PRIMARYAUDIO type=$MIMETYPE>$AUDIOFILEHIFISOURCE$CAPTIONTAG<div fallback>Your browser does not support HTML5 audio.</div></amp-audio>"
        fi

        if [ "offline" = "$MOBILE" ]; then
            printf "<p><strong>Playback requires an Internet connection.</strong></p>"
        fi

        printf "<div class=sml>"

        # Metadata and links to full file, data-saver and lossless, if extant.
        # Name if present from 'alt' text.
        if [ "" != "$MIMETYPE" ]; then
            printf '<meta itemprop=encodingFormat content=%s>' "$MIMETYPE"
        fi
        # Duration in seconds.  Display optional.
        DURATION="`mediainfo --Inform='Audio;%Duration%' $AUDIOFILE | awk '{if($1>0){printf("%d", int(($1+500)/1000))}}'`"
        if [ "" != "$DURATION" ]; then
            printf "<span class=dopt>%ss<meta itemprop=duration content=PT%sS></span> " $DURATION $DURATION
        fi
        if [ "" != "$ALT" ]; then
            # DHD20190617: description is for Yandex - doesn't use caption.
            printf '<span class=dopt>"<span itemprop="description name">%s</span>"</span> ' "$ALT"
        fi

        # Insert info if available.
        if [ "" != "$INFOFILE" ]; then
            printf "(<a href=%s itemprop=subjectOf>i</a>) " "$PREFIX$INFOFILE"
        fi

        # Link to captions if available.
        # TODO: correct metadata.
        if [ "" != "$VTTFILE" ]; then
            printf "(<span itemprop=caption itemscope itemtype=http://schema.org/MediaObject><meta itemprop=encodingFormat content=text/vtt><a href=%s itemprop=contentUrl>captions</a></span>) " "$PREFIX$VTTFILE"
        fi

        # Extract dateCreated with mediainfo --Inform='Audio;%Encoded_Date%'
        # Will only be present for some media.
        ENCODEDTMP="`mediainfo --Inform='Audio;%Encoded_Date%' $AUDIOFILE`"
        # Use if of form "UTC 2018-12-07 12:25:01"
        ENCODED=`echo $ENCODEDTMP | awk '$1=="UTC"{print $2"T"$3"Z";exit}'`
        if [ "" != "$ENCODED" ]; then
            printf "Created/encoded <time itemprop=dateCreated datetime=%s>%s</time>. " $ENCODED "`echo $ENCODED | awk -FT '{print $1}'`"
        fi

        # Upload date (commit time to repo).  Display optional.
        LASTUPDATEDLTMP="`export TZ=UTC; svn info $AUDIOFILE | awk '/^Last Changed Date:/ {print $0;exit}'`"
        LASTUPDATEDDTZ=`echo $LASTUPDATEDLTMP | awk '/^Last Changed Date:/ && $6=="+0000" {print $4"T"$5"Z";exit}'`
        if [ "" != "$LASTUPDATEDDTZ" ]; then
            printf "<span class=dopt>Uploaded <time itemprop=\"dateModified uploadDate\" datetime=%s>%s</time>.</span> " $LASTUPDATEDDTZ "`echo $LASTUPDATEDDTZ | awk -FT '{print $1}'`"
        fi

        # isFamilyFriendly to match VideoObject and RSS feed !isExplicit.
        printf "<meta itemprop=isFamilyFriendly content=true>"
        # Access/licensing.
        printf "<meta itemprop=isAccessibleForFree content=true>"
        printf "<meta itemprop=requiresSubscription content=false>"
        printf "<link href=${LICENSINGURL} itemprop=acquireLicensePage>"

        # DOWNLOADS START
        # Smallest to largest, with the default highlighted.
        # Cheat and format as a navigation breadcrumb list for now.
        DLITEMSTART=" <li>&bull; "
        printf " Downloads:<ol class=navbclist>"
        # Has default been marked yet?
        DONEDEFAULT="false"
        DEFAULTSTART="<strong>"
        DEFAULTEND="</strong>"
        # Number of bytes of the 'standard' desktop object.
        STDBYTES="$(wc -c < "$AUDIOFILE")"

        # Compute kB awk prog: pipe bytes to stdin, kB on stdout.
        KBF='{print int(($1+512)/1024)}'
        # Compute (integer) kbps awk prog: pipe bytes and seconds to stdin.
        KBPSF='{if($2<=0){print 0}else{print int($1/(125*$2))}}'
        # Gen size meter given on stdin: default:1-5 actualBytes stdObjectBytes
        # Normalise standard object to be 0.5/1 (2.5/5).
        MSF='{rawvalue=($2/$3)*.5; value=rawvalue; if(value>1){value=1} printf("<meter value=%.1f", value); if(rawvalue>=1){printf(" high=0.9");} printf(">%s</meter>", substr("+++++", 1, $1))}'

        # MIDI version file if available, ~0/5 size.
        if [ "" != "$AUDIOFILEMIDI" -a "$AUDIOFILE" != "$AUDIOFILEMIDI" ]; then
            BYTES="$(wc -c < "$AUDIOFILEMIDI")"
            printf "%s tiny <a href=%s itemprop=\"encoding isBasedOn\" download>%s track</a> %dkB %s%s" "$DLITEMSTART" "$PREFIX$AUDIOFILEMIDI" "$AUDIOFILEMIDIHUMANTYPE" "$(echo "$BYTES" | awk "$KBF")" "$(echo 1 "$BYTES" "$STDBYTES" | awk "${MSF}")"
        fi

        # Lowest-fidelity alternative-codec file if available, ~1/5 size.
        # NON-DESKTOP DEFAULT
        DFS=""
        DFE=""
        if [ "" != "$AUDIOFILELOWESTFI" -a "$AUDIOFILE" != "$AUDIOFILELOWESTFI" ]; then
            if [ "false" != "$MOBILE" ] && [ "false" = "$DONEDEFAULT" ]; then
                DFS="$DEFAULTSTART"
                DFE="$DEFAULTEND"
                DONEDEFAULT=true
            fi
            WCHANNELS=`mediainfo --Inform='Audio;%Channels%' ${AUDIOFILELOWESTFI} | awk '$1==1{print"mono "}$1==2{print"stereo "}'`
            BYTES="$(wc -c < "$AUDIOFILELOWESTFI")"
            printf "%s%ssmall lo-fi <a href=%s itemprop=\"encoding isBasedOn\" download><span class=dopt>very-low-bandwidth %s</span> %s clip</a> %dkB (%dkbps) %s%s" "$DLITEMSTART" "$DFS" "$PREFIX$AUDIOFILELOWESTFI" "$AUDIOFILELOWESTFIHUMANTYPE" "$WCHANNELS" "$(echo "$BYTES" | awk "$KBF")" "$(echo "$BYTES" "$DURATION" | awk "$KBPSF")" "$(echo 1 "$BYTES" "$STDBYTES" | awk "${MSF}")" "$DFE"
        fi

        # Very-low-fidelity low-bandwidth same-codec version if available, ~1/5.
        if [ -s ${AUDIOFILE}LL ]; then
            WCHANNELS=`mediainfo --Inform='Audio;%Channels%' ${AUDIOFILE}LL | awk '$1==1{print"mono "}$1==2{print"stereo "}'`
            BYTES="$(wc -c < "${AUDIOFILE}LL")"
            printf "%svery-lo-fi <a href=%s itemprop=\"encoding isBasedOn\" download>very-low-bandwidth %s %s clip</a> %dkB (%dkbps) %s" "$DLITEMSTART" "$PREFIX${AUDIOFILE}LL" "$ABV" "$WCHANNELS" "$(echo "$BYTES" | awk "$KBF")" "$(echo "$BYTES" "$DURATION" | awk "$KBPSF")" "$(echo 1 "$BYTES" "$STDBYTES" | awk "${MSF}")"
        fi

        # Low-fidelity low-bandwidth MP3 version if available, size ~2/5.
        # NON-DESKTOP SECOND-PRIORITY DEFAULT
        DFS=""
        DFE=""
        if [ "" != "$LOFIMP3" ] && [ -s "${LOFIMP3}" ]; then
            if [ "false" != "$MOBILE" ] && [ "false" = "$DONEDEFAULT" ]; then
                DFS="$DEFAULTSTART"
                DFE="$DEFAULTEND"
                DONEDEFAULT=true
            fi
            WCHANNELS=`mediainfo --Inform='Audio;%Channels%' $LOFIMP3 | awk '$1==1{print"mono "}$1==2{print"stereo "}'`
            BYTES="$(wc -c < "${LOFIMP3}")"
            printf "%s%slo-fi <a href=%s itemprop=\"encoding isBasedOn\" download>low-bandwidth %s %s clip</a> %dkB (%dkbps) %s%s" "$DLITEMSTART" "$DFS" "$PREFIX$LOFIMP3" "MP3" "$WCHANNELS" "$(echo "$BYTES" | awk "$KBF")" "$(echo "$BYTES" "$DURATION" | awk "$KBPSF")" "$(echo 2 "$BYTES" "$STDBYTES" | awk "${MSF}")" "$DFE"
        fi

        # DESKTOP DEFAULT, ALTERNATE (OPUS) CODEC, NEAR TRANSPARENT, ~2/5 size.
        DFS=""
        DFE=""
        if [ "" != "$AUDIOFILEALTMEDIUMFI" -a "$AUDIOFILE" != "$AUDIOFILEALTMEDIUMFI" ]; then
            if [ "false" = "$MOBILE" ] && [ "false" = "$DONEDEFAULT" ]; then
                DFS="$DEFAULTSTART"
                DFE="$DEFAULTEND"
                DONEDEFAULT=true
            fi
            WCHANNELS=`mediainfo --Inform='Audio;%Channels%' ${AUDIOFILEALTMEDIUMFI} | awk '$1==1{print"mono "}$1==2{print"stereo "}'`
            BYTES="$(wc -c < "$AUDIOFILEALTMEDIUMFI")"
            printf "%s%s<a href=%s itemprop=\"encoding isBasedOn\" download><span class=dopt>reduced-bandwidth %s</span> %s clip</a> %dkB (%dkbps) %s%s" "$DLITEMSTART" "$DFS" "$PREFIX$AUDIOFILEALTMEDIUMFI" "$AUDIOFILEALTMEDIUMFIHUMANTYPE" "$WCHANNELS" "$(echo "$BYTES" | awk "$KBF")" "$(echo "$BYTES" "$DURATION" | awk "$KBPSF")" "$(echo 2 "$BYTES" "$STDBYTES" | awk "${MSF}")" "$DFE"
        fi

        # FALLBACK DESKTOP VERSION, DEFAULT (MP3) CODEC, ~3/5 size.
        DFS=""
        DFE=""
        if [ "false" = "$MOBILE" ] && [ "false" = "$DONEDEFAULT" ]; then
            DFS="$DEFAULTSTART"
            DFE="$DEFAULTEND"
            DONEDEFAULT=true
        fi
        SAVERWARN=""
        if [ -s "${DISPLAYVIDEOFILE}L" ]; then
            SAVERWARN=" (may not be available in data-saver/lite mode)";
        fi
        WCHANNELS=`mediainfo --Inform='Audio;%Channels%' ${AUDIOFILE} | awk '$1==1{print"mono "}$1==2{print"stereo "}'`
        BYTES="$STDBYTES"
        printf "%s%s<a href=%s itemprop=\"encoding isBasedOn\" download>%s %s clip</a> %dkB (%dkbps) %s%s%s" "$DLITEMSTART" "$DFS" "$PREFIX${AUDIOFILE}" "$ABV" "$WCHANNELS" "$(echo "$BYTES" | awk "$KBF")" "$(echo "$BYTES" "$DURATION" | awk "$KBPSF")" "$(echo 3 "$BYTES" "$STDBYTES" | awk "${MSF}")" "$SAVERWARN" "$DFE"

        # High-fidelity lossless file if available, ~5/5 size.
        if [ "" != "$AUDIOFILEHIFI" -a "$AUDIOFILE" != "$AUDIOFILEHIFI" ]; then
            WCHANNELS=`mediainfo --Inform='Audio;%Channels%' ${AUDIOFILEHIFI} | awk '$1==1{print"mono "}$1==2{print"stereo "}'`
            BYTES="$(wc -c < "$AUDIOFILEHIFI")"
            printf "%shi-fi <a href=%s itemprop=\"encoding isBasedOn\" download>lossless <span class=dopt>%s</span> %s clip</a> %dkB (%dkbps) %s" "$DLITEMSTART" "$PREFIX$AUDIOFILEHIFI" "$AUDIOFILEHIFIHUMANTYPE" "$WCHANNELS" "$(echo "$BYTES" | awk "$KBF")" "$(echo "$BYTES" "$DURATION" | awk "$KBPSF")" "$(echo 5 "$BYTES" "$STDBYTES" | awk "${MSF}")"
        fi

        # DOWNLOADS END
        printf "</ol>"

        printf "</div>"

        if [ "simpleAudioEmbedWithTranscriptInDetails" = "$OP" ]; then
            # Lead into following transcript block wrapped in details.
            # Economise on space on RHS.
            printf '<details><summary>Transcript...</summary><blockquote style=margin-right:0 id=mo-%d-transcript itemprop=transcript>' "$ORDINAL"
        elif [ "simpleAudioEmbedWithTranscript" = "$OP" ]; then
            # Lead into following transcript block.
            # Economise on space on RHS.
            printf 'Transcript:<blockquote style=margin-right:0 id=mo-%d-transcript itemprop=transcript>' "$ORDINAL"
        else
            # End outer div/itemscope in usual way.
            echo "</div>"
        fi

exit 0;;


*) #---------------------------------------------------------
echo "ERROR: $0: bad operation $OP for $ARTBODY." 1>&2
exit 2;;

esac

echo "Unable to create audio player insert for for $AUDIOFILE..." 1>&2
exit 1


# DHD20250609: thanks to James Cridland for audio captions steer: https://james.cridland.net/blog/2025/html-audio-player-with-captions/
# DHD20250609: it does actually work, but the JS (and CSS) breaks some of my tooling, so it is disabled for now.



##########
# May be used / adapted / etc without any promise of fitness for purpose
# under the terms of the Apache License Version 2.0, January 2004
#     http://www.apache.org/licenses/LICENSE-2.0
##########
