#!/bin/sh
#echo START $0 $* 1>&2
# Generate in-line video player code, both vanilla HTML5 and AMP:
#   $1 must be the operation to perform.
#   $2 must be the declared (external) video file path name or CMS URL.
#   $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 video).
#   $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.
#
# Note that $2, the video name, may be of the form:
#   * img/video/xxx
#   * http://gallery.hd.org/_exhibits/xxx
# and in future possibly:
#   * http://gallery.hd.org/_tn/std/xxx
#
# 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

# Note: depends on avconv/ffmpeg, mediainfo and perl, amongst other things...
# DHD20231227: libav no longer supported nor part of Homebrew.
#FFMPEG=avconv
FFMPEG=ffmpeg

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

#echo "INFO: $0 OP=$OP VIDEOURL=$VIDEOURL 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


# 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}

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


# DISPLACE is true if the files are to be served displaced.
# There are several possible reasons for displacing.
DISPLACE="false"
# INFOFILE is path to EOU-local text/info file, if present.
INFOFILE=""
# VTTFILE is path to EOU-local WebVTT captioning file, if present.
VTTFILE=""
# LASTUPDATEDDTZ is last update / accession datetime (ISO 8601 UTZ).
LASTUPDATEDDTZ=""

# Hi-fi version of original file if present (as .hifi.XXX).
VIDEOFILEHIFI=""

# Verify that the source image is in a valid location and 
# has a valid format.  Abort with an error if not.
# (This script checks earlier for existence as appropriate.)
#
#     img/video/* for static videos
#     http://gallery.hd.org/_exhibits/xxx
# and in future possibly:
#     http://gallery.hd.org/_tn/std/xxx
#
#     http://gallery.hd.org/* from the CMS, mainly intended for body images
#         (HEROFILE should be rewritten to a local file copy from the CMS)
#         pointing to a thumbnail, /_tn/std/<exhibitpath>, eg:
#         http://gallery.hd.org/_tn/std/places-and-sights/England-London-Kennington-The-Prince-of-Wales-frontage-1-DHD.jpg
LOC=""
    case $VIDEOURL in
    img/video/*)
        # Image is local to EOU.
        LOC="img";
        VIDEOFILE="$VIDEOURL";
        if [ ! -s $VIDEOFILE ]; then
            echo "ERROR: missing VIDEOFILE $VIDEOFILE" 1>&2
            exit 1
        fi
        # Name of .hifi.X (maybe lossless) version if present.
        VIDEOFILEHIFI="`echo $VIDEOFILE | sed -e 's/\.\([^.\/ ]*\)$/.hifi.\1/'`"
        # If there is no 'L' lo-fi version then displace the original.
        if [ ! -s ${VIDEOFILE}L ]; then DISPLACE="true"; fi
        # INFOFILE is path to text/info file, if present.
        INFOFILE="$VIDEOFILE.txt"
        if [ ! -s "$INFOFILE" ]; then INFOFILE=""; fi
        # VTTFILE is path to EOU-local WebVTT captioning file, if present.
        VTTFILE="$VIDEOFILE.vtt"
        if [ ! -s "$VTTFILE" ]; then VTTFILE=""; fi

        # Extract EOU file svn last-commit.
        LASTUPDATEDLTMP="`export TZ=UTC; svn info $VIDEOFILE | awk '/^Last Changed Date:/ {print $0;exit}'`"
        LASTUPDATEDDTZ=`echo $LASTUPDATEDLTMP | awk '/^Last Changed Date:/ && $6=="+0000" {print $4"T"$5"Z";exit}'`
        ;;
    http://gallery.hd.org/_exhibits/*)
        if [ "" = "$GALLERYCMSPATH" ]; then
            # If no Gallery CMS path is yet set, use the default.
            GALLERYCMSPATH=/rw/galleryDB/photos/
        fi
        if [ ! -d "$GALLERYCMSPATH" ]; then 
            echo "ERROR: GALLERYCMSPATH $GALLERYCMSPATH not a directory for $ARTBODY." 1>&2
            exit 1;
        fi
        DISPLACE="true"
        # Convert VIDEOURL to local file path.
        # Note that GALLERYCMSPATH ends with '/'.
        IMGGALPATH="`echo $VIDEOURL | sed -e 's/^http:\/\/gallery[.]hd[.]org\/_exhibits\///'`"
        VIDEOFILE="$GALLERYCMSPATH$IMGGALPATH"
        #echo "INFO: rewritten Gallery $VIDEOURL -> $VIDEOFILE for $ARTBODY." 1>&2
        LOC="gallery" # From CMS.
        if [ ! -s $VIDEOFILE ]; then
            echo "ERROR: missing VIDEOFILE $VIDEOFILE" 1>&2
            exit 1
        fi
        # Alongside the exhibit at .../videofile.ext is an accession file
        # at .../.accession.videofile.ext.xml of the form:
        #    <accessionData><date value="892241709000"/><size value="63971"/><hash-CRC32 value="3b4e1597"/><hash-MD5 value="1c4e8fd2a40d8f3e3b7081bdf71a9299"/></accessionData>
        # From this the date (as JAVA time) should be extracted as upload date.
        IMAGEGALACCESSIONXML="`dirname $VIDEOFILE`/.accession.`basename $VIDEOFILE`.xml"
        if [ ! -s "$IMAGEGALACCESSIONXML" ]; then
            echo "WARNING: missing accession file $IMAGEGALACCESSIONXML for Gallery $VIDEOURL -> $VIDEOFILE for $ARTBODY." 1>&2
        else
            #echo "INFO: accession `cat $IMAGEGALACCESSIONXML` for Gallery $VIDEOURL -> $VIDEOFILE for $ARTBODY." 1>&2
            JAVATIME=`sed < $IMAGEGALACCESSIONXML -n -e 's/^.*<date value="\([1-9][0-9]*\)"\/>.*$/\1/p'`
            #echo "INFO: JAVATIME=$JAVATIME for Gallery $VIDEOURL -> $VIDEOFILE for $ARTBODY." 1>&2
            LASTUPDATEDDTZ=`echo $JAVATIME | perl -MPOSIX=strftime -ane 'print strftime("%Y-%m-%dT%H:%M:%SZ", gmtime($F[0]/1000))'`
        fi
        # URL for Gallery catalogue page.
        # Can be switched to https in future.
        IMAGEGALCATPAGE="http://gallery.hd.org/_c/$IMGGALPATH.html"
        IMAGEGALEXHIBIT="http://gallery.hd.org/_exhibits/$IMGGALPATH"
        ;;
    *) echo "ERROR: $0: $OP invalid video location $VIDEOURL for $ARTBODY." 1>&2
       exit 1;;
    esac



# KEEP THIS CONSISTENT WITH SITE CSS AND get_hero_img_inline.sh
#
# Target desktop body max-width (px), eg for page-wide (100vw) images.
# Should match main container width, eg from CSS.
DBODYPX=800
# Target mobile body width (px), eg for page-wide (100vw) images.
# Should match (max) size targeted for 'alternate' page media max-width:
#   <link rel=alternate href="http://m.earth.org.uk/" media="only screen and (max-width:640px)"/>
MBODYPX=640
# Target minimum body width (px), eg for page-wide (100vw) images.
# As of 2017Q1 most popular viewport width ~360 (CSS) pixels.
# This targets a 1.5x density at that minimum viewport size,
# thus 540px effective real pixel width.
MINBODYPX=540
#
# Full Width display PiXels for target device.
FWPX="$DBODYPX"
if [ "false" != "$MOBILE" ]; then
    # Somewhat reduced target image size for mobile.
    FWPX="$MBODYPX"
fi


# Poster and video files can be auto-generated on the fly.
# Poster files always in .jpg format.
# Simplified compared to general still image processing.
AUTOGENFILEDIR=img/a/v
# If the rebuild flags exists and is newer than any cached result flag,
# unconditionally try to rebuild/refresh everything (carefully, under a lock).
# Else return immediately on cached positive or negative results.
# Assumes that a cached positive result is the most likely.
# Should be touched after any substantive change to image selection/generation.
REBUILDFLAGREBUILDFLAG=img/a/.rebuild.flag

# Temporary files.
TEMPFILEBASE=$AUTOGENFILEDIR/.tmp.$$.
# Pre-tidy!
rm -f $TEMPFILEBASE*
# Hook in handler to tidy up temp files on forced exit.
trap "rm -f $TEMPFILEBASE*; exit 1" 1 2 15


# 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:
#
#  simpleVideoEmbed
#     Simple single-source video player embedded in page.
#
#  simpleVideoEmbedWithTranscript
#     As simpleVideoEmbed but immediately followed with
#         texttexttextoftranscript...</blockquote></div>
#     so body ends to bring the text in as a transcript.
#
#  simpleVideoEmbedWithTranscriptInDetails
#     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.
#
# May build derived versions of primary video on the fly
# so may be SLOW.

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

case $OP in


simpleVideoEmbed*) #-------------------------------------------
#  simpleVideoEmbed
#  simpleVideoEmbedWithTranscript
#  simpleVideoEmbedWithTranscriptInDetails
#
# May build derived versions of primary video on the fly
# so may be SLOW.
#
# Note that a low-fi "L" version of the file is looked for,
# and linked if present.
#
# If the L file is not present, or the source file is not MP4,
# or the source is from the Gallery, then the source is displaced,
# and a .mp4 and .mp4L pair are created if possible.
# This may imply an initial transcoding step, but the original
# is always made available as a fallback and via a link.

# The preferred video format file extension for most Web clients.
PREFERREDFORMATEXT=.mp4

        # 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[s]*://'`"
            #echo "INFO: $0: stripped scheme $PREFIX for $ARTBODY." 1>&2
        fi

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

        SRCMIMETYPE=""
        SRCABV=""
        # MIME type of primary source (rejected if unknown).
        case $VIDEOFILE in
            *.avi)  SRCMIMETYPE="video/x-msvideo";   SRCABV="AVI";;
            *.mov)  SRCMIMETYPE="video/quicktime";   SRCABV="MOV";;
            *.mp4)  SRCMIMETYPE="video/mp4";         SRCABV="MP4";;
            *.mpg)  SRCMIMETYPE="video/mpeg";        SRCABV="MPEG";;
            *.ogg)  SRCMIMETYPE="video/ogg";         SRCABV="Ogg";;
            *.qt)   SRCMIMETYPE="video/quicktime";   SRCABV="QT";;
            *.webm) SRCMIMETYPE="video/webm";        SRCABV="WebM";;
            *) echo "ERROR: $0 unknown primary video type for $VIDEOFILE" 1>&2; exit 1;;
        esac

        # Check if a super-lo-fi audio-only 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.
        # For now this need not be displaced,
        # eg because it will not be a fallback source.
        # Try to auto-generate if one is not checked in beside the primary.
        AUDIOFILELOWESTFI=""
        AUDIOFILELOWESTFITYPE=""
        AUDIOFILELOWESTFISOURCE=""
        AUDIOFILELOWESTFIBASE="`echo $VIDEOFILE | sed -e 's/\.[^.\/ ]*$/./'`"
        AUDIOFILELOWESTFIOPUS="${AUDIOFILELOWESTFIBASE}opusL"
        if [ "$AUDIOFILELOWESTFIOPUS" != "$VIDEOFILE" -a -s "$AUDIOFILELOWESTFIOPUS" ]; then
            AUDIOFILELOWESTFI="$AUDIOFILELOWESTFIOPUS"
        elif [ -s script/audioBuildLossy.sh ]; then
            # Attempt to auto-generate from hi-fi source else original.
            if [ -s "$VIDEOFILEHIFI" ]; then
                AUDIOFILELOWESTFIOPUS="$(sh script/audioBuildLossy.sh "$VIDEOFILEHIFI" opusL)"
            else
                AUDIOFILELOWESTFIOPUS="$(sh script/audioBuildLossy.sh "$VIDEOFILE" opusL)"
            fi
            if [ "" != "$AUDIOFILELOWESTFIOPUS" ] && [ -s "$AUDIOFILELOWESTFIOPUS" ]; then
                AUDIOFILELOWESTFI="$AUDIOFILELOWESTFIOPUS"
            fi
        fi
        if [ "" != "$AUDIOFILELOWESTFI" ]; then
            AUDIOFILELOWESTFITYPE="audio/opus"
            AUDIOFILELOWESTFISOURCE="<source src=$PREFIX$AUDIOFILELOWESTFI type=\"audio/ogg;codecs=opus\">"
        fi

        DISPLACEDVIDEOFILE=""
        if [ "true" = "$DISPLACE" ]; then
            # Path to displace (copy/link/transcode) primary to.
            DISPLACEDVIDEOFILEBASE="`basename $VIDEOFILE | sed -e 's/\.[^.\/ ]*$/'$PREFERREDFORMATEXT'/'`"
            DISPLACEDVIDEOFILE=$AUTOGENFILEDIR/$DISPLACEDVIDEOFILEBASE
            # If displaced file doesn't yet exist, or is stale, create it.
            # Also attempt to (re)create a lo-fi version alongside.
            if [ ! -s "$DISPLACEDVIDEOFILE" -o "$VIDEOFILE" -nt "$DISPLACEDVIDEOFILE" -o "$REBUILDFLAG" -nt "$DISPLACEDVIDEOFILE" ]; then
                echo "INFO: $0: $VIDEOFILE being displaced to $DISPLACEDVIDEOFILE for $ARTBODY." 1>&2
                # In the case that the source is in the preferred format,
                # hard link it, else transcode it with defaults.
                DISPLACEDVIDEOFILETMP=$TEMPFILEBASE$DISPLACEDVIDEOFILEBASE
                # TODO: even if in right format a 'recode' may save space.
                case $VIDEOFILE in
                    *$PREFERREDFORMATEXT)
                        # Near-atomically move hard link into place if possible.
                        ln -f $VIDEOFILE $DISPLACEDVIDEOFILE || (cp -f $VIDEOFILE $DISPLACEDVIDEOFILETMP && mv -f $DISPLACEDVIDEOFILETMP $DISPLACEDVIDEOFILE)
                        chmod a+r $DISPLACEDVIDEOFILE
                        echo "INFO: $0 copied/linked displaced $DISPLACEDVIDEOFILE" 1>&2;;
                    *)
                        # Do default-ish conversion to preferred format.
                        # Various options are tried to allow any conversion...
                        VIDOPT="-movflags +faststart"
                        for OPT in "" "-q:a 2" "-an";
                            do
                            rm -f $DISPLACEDVIDEOFILETMP
                            echo "INFO: $0: trying: $FFMPEG -loglevel error -i $VIDEOFILE $VIDOPT $OPT $DISPLACEDVIDEOFILETMP" 1>&2
                            if $FFMPEG </dev/null -loglevel error -i $VIDEOFILE $VIDOPT $OPT $DISPLACEDVIDEOFILETMP && [ -s "$DISPLACEDVIDEOFILETMP" ]; then
                                if [ "" != "$OPT" ]; then
                                    echo "WARNING: $0: $FFMPEG $OPT needed; transcoded video may not be acceptable." 1>&2
                                fi
                                break;
                            fi
                            # Clear extra options if having problems.
                            VIDOPT=""
                            done
                        if [ -s "$DISPLACEDVIDEOFILETMP" ]; then
                            chmod u+w $DISPLACEDVIDEOFILE >/dev/null 2>&1
                            mv -f $DISPLACEDVIDEOFILETMP $DISPLACEDVIDEOFILE
                            chmod a+r $DISPLACEDVIDEOFILE
                            echo "INFO: $0 transcoded $VIDEOFILE" 1>&2
                        else
                            echo "INFO: $0 failed to transcode $VIDEOFILE" 1>&2
                        fi
                        ;;
                esac
                if [ ! -s "$DISPLACEDVIDEOFILE" ]; then
                    echo "ERROR: $0 failed to displace $VIDEOFILE to $DISPLACEDVIDEOFILE" 1>&2; exit 1;
                fi
                # Now create 'L' lo-fi version if possible.
                LOFI="`script/compress_video_mp4 "$DISPLACEDVIDEOFILE"`"
            fi
        fi

        # Use source else displaced/transcoded version (eg in preferred format).
        PRIMARYVIDEOFILE="$VIDEOFILE"
        if [ "" != "$DISPLACEDVIDEOFILE" -a -s "$DISPLACEDVIDEOFILE" ]; then
            PRIMARYVIDEOFILE="$DISPLACEDVIDEOFILE"
        fi

        # Extract source width and height...
        srcwidth="`mediainfo --Inform='Video;%Width%' $PRIMARYVIDEOFILE`"
        srcheight="`mediainfo --Inform='Video;%Height%' $PRIMARYVIDEOFILE`"
        if [ "" = "$srcwidth" -o "" = "$srcheight" ]; then
            echo "ERROR: $0: srcwidth=$srcwidth srcheight=$srcheight for $PRIMARYVIDEOFILE for $ARTBODY." 1>&2
        fi
        # Initially assume that display file/width/height matches source.
        DISPLAYVIDEOFILE=$PRIMARYVIDEOFILE
        width=$srcwidth
        height=$srcheight

        if [ "$srcwidth" -gt "$FWPX" ]; then
            #echo "INFO: $0: srcwidth=$srcwidth for $PRIMARYVIDEOFILE wider than $FWPX display for MOBILE=$MOBILE for $ARTBODY." 1>&2
            # Try to make smaller (narrower) version to fit display.
            # Scale down, and to lower-res to make L versions.
            SMALLER="`script/shrink_video_mp4 $FWPX $PRIMARYVIDEOFILE`"
            if [ "" != "$SMALLER" -a "$PRIMARYVIDEOFILE" != "$SMALLER" ]; then
                DISPLAYVIDEOFILE=$SMALLER
                # Recompute width and height for video in display.
                width="`mediainfo --Inform='Video;%Width%' $DISPLAYVIDEOFILE`"
                height="`mediainfo --Inform='Video;%Height%' $DISPLAYVIDEOFILE`"
            else
                echo "INFO: $0: unable to make lighter/smaller: srcwidth=$srcwidth for $PRIMARYVIDEOFILE wider than $FWPX display for MOBILE=$MOBILE for $ARTBODY." 1>&2
            fi
        fi

        SUPPRESSPOSTER="false"
        if [ "offline" = "$MOBILE" ]; then
            SUPPRESSPOSTER="true"
        fi

        # Poster image for video, at the right size for display.
        # Look first for hand-crafted poster file(s); use if present.
        POSTERFILE="`echo $DISPLAYVIDEOFILE | sed -e 's/\.[^.\/ ]*$/.jpg/'`"
        POSTER=""
        THUMBNAILURL=""
        if [ "false" = "$SUPPRESSPOSTER" -a ! -s "${POSTERFILE}" ]; then
            # Attempt to auto-extract poster image from start of video.
            POSTERFILE=""
            TARGETPOSTERFILEBASE="`basename $VIDEOFILE | sed -e 's/\.[^.\/ ]*$//'`.${width}x${height}.p.jpg"
            TARGETPOSTERFILE=$AUTOGENFILEDIR/$TARGETPOSTERFILEBASE
            # May also need to check age of source and of this script...
            if [ ! -s "$TARGETPOSTERFILE" -o "$DISPLAYVIDEOFILE" -nt "$TARGETPOSTERFILE" -o "$VIDEOFILE" -nt "$TARGETPOSTERFILE" -o "$REBUILDFLAG" -nt "$TARGETPOSTERFILE" ]; then
                echo "INFO: $0: generating poster/thumbnail $TARGETPOSTERFILE for $DISPLAYVIDEOFILE for $ARTBODY." 1>&2
                POSTERTMP=$TEMPFILEBASE.$TARGETPOSTERFILEBASE
                # Extract sample frame.
                script/extract_video_poster_image "$DISPLAYVIDEOFILE" "$POSTERTMP"
                CONVERT="$(sh script/IMPathConvert.sh)"
                # Attempt to keep poster image size reasonable...
                if [ -s "$POSTERTMP" ] && [ -x "$CONVERT" ]; then
                    $CONVERT "$POSTERTMP" -limit memory 200MB -sampling-factor 4:2:0 -strip -quality 82 "$POSTERTMP"2
                    if [ -s "${POSTERTMP}2" -a "`wc -c < ${POSTERTMP}2`" -lt "`wc -c < $POSTERTMP`" ]; then
                        mv "${POSTERTMP}2" "$POSTERTMP"
                    else
                        rm -f "${POSTERTMP}2"
                    fi
                fi
                # Reduce losslessly.
                if [ -s "$POSTERTMP" ]; then
                    script/lossless_JPEG_compress "$POSTERTMP"
                fi
                # Replace atomically.
                if [ -s "$POSTERTMP" ] && [ -x "$CONVERT" ]; then
                    chmod -f u+w "$TARGETPOSTERFILE" > /dev/null 2>&1
                    chmod a+r,go-w "$POSTERTMP"
                    mv -f "$POSTERTMP" "$TARGETPOSTERFILE"
                    # Use new auto-generated poster file.
                    POSTERFILE="$TARGETPOSTERFILE"
                    #
                    # Now attempt to create lo-fi version.
                    # The 'quality' setting is fairly low.
                    $CONVERT "$TARGETPOSTERFILE" -limit memory 200MB -sampling-factor 4:2:0 -strip -quality 25 "$POSTERTMP"
                    # Reduce losslessly.
                    if [ -s "$POSTERTMP" ]; then
                        script/lossless_JPEG_compress "$POSTERTMP"
                    fi
                    # If extant and smaller then use it.
                    if [ -s "$POSTERTMP" -a "`wc -c < $POSTERTMP`" -lt "`wc -c < $TARGETPOSTERFILE`" ]; then
                        chmod -f u+w "$TARGETPOSTERFILE"L > /dev/null 2>&1
                        chmod a+r,go-w "$POSTERTMP"
                        mv -f "$POSTERTMP" "$TARGETPOSTERFILE"L
                    else
                        # Could not make lo-fi poster file; kill any stale one.
                        rm -f "$TARGETPOSTERFILE"L
                    fi
                else
                    # Could not make main poster file; kill any stale one.
                    rm -f "$TARGETPOSTERFILE"
                fi
                # Tidy up.
                rm -f "$POSTERTMP"
            else
                # Poster file exists.
                POSTERFILE="$TARGETPOSTERFILE"
            fi
        fi
        # Look again for hand-crafted or auto-generated poster files.
        if [ "false" != "$SUPPRESSPOSTER" ]; then
            : Do nothing...
        elif [ -s "${POSTERFILE}" ]; then
            THUMBNAILURL="$PREFIX${POSTERFILE}"
            POSTER="poster=$PREFIX${POSTERFILE} "
            if [ "false" != "$MOBILE" -a -s "${POSTERFILE}L" ]; then
                # Use low-fi poster for lite where available.
                THUMBNAILURL="$PREFIX${POSTERFILE}L"
                POSTER="poster=$PREFIX${POSTERFILE}L "
                #echo "INFO: SRCBYTES: IMG: `wc -c < ${POSTERFILE}L`" 1>&2
            #else
            #    echo "INFO: SRCBYTES: IMG: `wc -c < ${POSTERFILE}`" 1>&2
            fi
        else
            echo "ERROR: $0: no poster/thumbnail for $DISPLAYVIDEOFILE for $ARTBODY." 1>&2
            exit 1
        fi

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

        # In 'lite'/AMP mode show lighter content where available.
        SUFFIX=""
        if [ "false" != "$MOBILE" ] && [ -s "${DISPLAYVIDEOFILE}L" ]; then SUFFIX="L"; fi

        # Drop heavy hint about lite mode on first desktop instance.
        if [ "false" = "$MOBILE" ] && [ "1" = "$ORDINAL" ] && [ -s "${DISPLAYVIDEOFILE}L" ]; 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

        printf "<div id=mo-%d itemprop=video itemscope itemtype=http://schema.org/VideoObject>" "$ORDINAL"

        # Provide fallback to original source if a scaled primary is used.
        VIDEOFILEHIFISOURCE="<source src=$PREFIX$VIDEOFILE type=$SRCMIMETYPE>"
        if [ "$DISPLAYVIDEOFILE" = "$VIDEOFILE" ]; then
            # Remove fallback to original as fallback is already the primary.
            VIDEOFILEHIFISOURCE=""
        elif cmp -s "$DISPLAYVIDEOFILE" "$VIDEOFILE"; then
            # Remove fallback to original as fallback byte-for-byte identical.
            VIDEOFILEHIFISOURCE=""
        elif [ "gallery" = "$LOC" ]; then
            VIDEOFILEHIFISOURCE="<source src=$VIDEOURL type=$SRCMIMETYPE>"
        fi

        # Recompute file type if shrunk version has changed.
        DISPLAYMIMETYPE=""
        DISPLAYABV=""
        # MIME type of displayed video (rejected if unknown).
        # A restricted range of widely-supported formats, including preferred.
        case $DISPLAYVIDEOFILE in
            *.mp4)  DISPLAYMIMETYPE="video/mp4";   DISPLAYABV="MP4";;
            *.ogg)  DISPLAYMIMETYPE="video/ogg";   DISPLAYABV="Ogg";;
            *.webm) DISPLAYMIMETYPE="video/webm";  DISPLAYABV="WebM";;
            *) echo "ERROR: $0 unknown resized video type for $DISPLAYVIDEOFILE" 1>&2; exit 1;;
        esac

        # Insert subtitles/captions if available.
        CAPTIONTAG=""
        if [ "" != "$VTTFILE" ]; then
            CAPTIONTAG="<track default kind=captions srclang=en-gb label=English src=$PREFIX$VTTFILE>"
        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

        if [ "amp" != "$MOBILE" ]; then
            # Normal HTML5.
            # Official/lite, then original, then audio-only if available.
            printf "<video class=respF width=%d height=%d style=display:block;max-width:100%%;height:auto;margin:auto title=\"$ALT\" ${POSTER}${PRELOAD}${XOANON}playsinline controls><source src=$PREFIX$DISPLAYVIDEOFILE$SUFFIX type=$DISPLAYMIMETYPE>$VIDEOFILEHIFISOURCE$AUDIOFILELOWESTFISOURCE$CAPTIONTAG<div>Your browser does not support HTML5 video.</div></video>" "$width" "$height"
        else
            # AMP
            # FIXME: omitting fallback from AMP in case http: URL from Gallery.
            printf "<amp-video width=$width height=$height layout=responsive title=\"$ALT\" ${POSTER}${PRELOAD}${XOANON}controls><source src=$PREFIX$DISPLAYVIDEOFILE$SUFFIX type=$DISPLAYMIMETYPE><div fallback>Your browser does not support HTML5 video.</div></amp-video>"
        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.
        printf '<meta itemprop=width content=%s>' "$width"
        printf '<meta itemprop=height content=%s>' "$height"
        if [ "" != "$DISPLAYMIMETYPE" ]; then
            printf '<meta itemprop=encodingFormat content=%s>' "$DISPLAYMIMETYPE"
        fi
        # Duration in seconds.  Display optional.
        DURATION="$(mediainfo --Inform='Video;%Duration%' $DISPLAYVIDEOFILE | 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 - does not use caption.
            printf '<span class=doptsml>"<span itemprop="description name">%s [VIDEO]</span>"</span> ' "$ALT"
        fi

        # Link to poster image in available.
        if [ "" != "$THUMBNAILURL" ]; then
            printf '(<a href=%s itemprop="thumbnail thumbnailUrl">poster</a>) ' "$THUMBNAILURL"
        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='Video;%Encoded_Date%'
        # Will only be present for some media.
        ENCODEDTMP="$(mediainfo --Inform='Video;%Encoded_Date%' $DISPLAYVIDEOFILE)"
        # Use if of form "UTC 2018-12-07 12:25:01" with date on/after 2020.
        # Screen out bogus 1904-01-01 dates.
        ENCODED=$(echo $ENCODEDTMP | awk '$1=="UTC" && $2 ~ /^20/ {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 (last commit time to repo).  Display optional.
        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 largely for Yandex.
        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 < "$DISPLAYVIDEOFILE")"

        # Compute kB awk prog: pipe bytes to stdin, kB on stdout.
        KBF='{print int(($1+512)/1024)}'
        # 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))}'

        # Lowest-fidelity audio-only file if available, ~1/5 size.
        if [ "" != "$AUDIOFILELOWESTFI" ]; then
            WCHANNELS="$(mediainfo --Inform='Audio;%Channels%' ${AUDIOFILELOWESTFI} | awk '$1==1{print"mono "}$1==2{print"stereo "}')"
            BYTES="$(wc -c < "$AUDIOFILELOWESTFI")"
            printf "%s<em>audio-only</em> lo-fi <a href=%s itemprop=\"encoding isBasedOn\" download>%s <span class=dopt>low-bandwidth %s</span> clip</a> %dkB %s" "$DLITEMSTART" "$PREFIX$AUDIOFILELOWESTFI" "$WCHANNELS" "$AUDIOFILELOWESTFITYPE" "$(echo "$BYTES" | awk "$KBF")" "$(echo 1 "$BYTES" "$STDBYTES" | awk "${MSF}")"
        fi

        # Low-fidelity low-bandwidth version if available, ~2/5 size.
        # NON-DESKTOP DEFAULT
        DFS=""
        DFE=""
        if [ -s "${DISPLAYVIDEOFILE}L" ]; then
            if [ "false" != "$MOBILE" ] && [ "false" = "$DONEDEFAULT" ]; then
                DFS="$DEFAULTSTART"
                DFE="$DEFAULTEND"
                DONEDEFAULT=true
            fi
            BYTES="$(wc -c < ${DISPLAYVIDEOFILE}L)"
            printf "%s%s<a href=%s itemprop=encoding download>low-bandwidth %s video clip</a> %dkB %s%s" "$DLITEMSTART" "$DFS" "$PREFIX${DISPLAYVIDEOFILE}L" "$DISPLAYABV" "$(echo "$BYTES" | awk "$KBF")" "$(echo 2 "$BYTES" "$STDBYTES" | awk "${MSF}")" "$DFE"
        elif [ -s "${VIDEOFILE}L" ]; then
            if [ "false" != "$MOBILE" ] && [ "false" = "$DONEDEFAULT" ]; then
                DFS="$DEFAULTSTART"
                DFE="$DEFAULTEND"
                DONEDEFAULT=true
            fi
            BYTES="$(wc -c < ${VIDEOFILE}L)"
            printf "%s%s<a href=%s itemprop=encoding download>low-bandwidth %s video clip</a> %dkB %s%s" "$DLITEMSTART" "$DFS" "$PREFIX${VIDEOFILE}L" "$SRCABV" "$(echo "$BYTES" | awk "$KBF")" "$(echo 2 "$BYTES" "$STDBYTES" | awk "${MSF}")" "$DFE"
        fi

        # Standard, 3/5 size.
        # DESKTOP DEFAULT
        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
        BYTES="$STDBYTES"
        printf "%s%s<a href=%s itemprop=\"contentUrl url\" download>%s video clip</a> <span itemprop=contentSize>%dkB</span> %s%s%s"  "$DLITEMSTART" "$DFS" "$PREFIX$DISPLAYVIDEOFILE" "$DISPLAYABV" "$(echo "$BYTES" | awk "$KBF")" "$(echo 3 "$BYTES" "$STDBYTES" | awk "${MSF}")" "$DFE" "$SAVERWARN"

        # Full-fat video file if available and not the displayed one, 5/5 size.
        if [ "" != "$VIDEOFILEHIFISOURCE" -o -s "$VIDEOFILEHIFI" ]; then
            VIDEOFILEHIFIURL=""
            VIDEOFILESIZE="$(wc -c < "$VIDEOFILE")"
            if [ "img" = "$LOC" ]; then
                VIDEOFILEHIFIURL="$PREFIX$VIDEOFILE"
                if [ -s "$VIDEOFILEHIFI" ]; then
                    # Use hifi (maybe lossless) version if available.
                    VIDEOFILEHIFIURL="$PREFIX$VIDEOFILEHIFI"
                    VIDEOFILESIZE="$(wc -c < $VIDEOFILEHIFI)"
                fi
            elif [ "gallery" = "$LOC" ]; then
                VIDEOFILEHIFIURL="$VIDEOURL"
            fi
            if [ "" != "$VIDEOFILEHIFIURL" ]; then
                BYTES="$VIDEOFILESIZE"
                printf "%shi-fi/original <a href=%s itemprop=\"encoding isBasedOn\" download>%s video clip</a> %dkB %s" "$DLITEMSTART" "$VIDEOFILEHIFIURL" "$SRCABV" "$(echo "$BYTES" | awk "$KBF")" "$(echo 5 "$BYTES" "$STDBYTES" | awk "${MSF}")"
            fi
            if [ "gallery" = "$LOC" ]; then
                printf " (<a href=%s>Gallery page</a>)" "$IMAGEGALCATPAGE"
            fi
        fi

        # DOWNLOADS END
        printf "</ol>"

        printf "</div>"

        if [ "simpleVideoEmbedWithTranscriptInDetails" = "$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 [ "simpleVideoEmbedWithTranscript" = "$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 video player insert for for $VIDEOFILE..." 1>&2
exit 1


##########
# 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
##########
