Skip to content
Sascha Nösberger edited this page Oct 1, 2024 · 4 revisions

Description

With this feature, users are able to either upload thumbnail or to set a timepoint of the uploaded video to extract the thumbnail from during the video upload.

Requirements

  • Opencast 15 or higher
  • Opencast ingest service
  • Opencast Workflows with thumbnail support
  • ILIAS 8
  • Plugin branch release_8, version 8.1.1 or higher

Configurations

Navigation

Admins can find the related page for thumbnails configuration under:

OpenCast plugin configuration > Settings > Thumbnails

Setting options

  • Enable thumbnail Upload: Enabling this will provide the feature to the end users.
    • Accepted File Types: File types accepted to be uploaded as thumbnail.
    • Upload Mode: several modes of providing this feature to the end user.
      • Both: Users must select one mode (either by file upload ot timepoint)
      • Timepoint: a timepicker input is provided to the users to select the timepoint of the video from whihc the thumbnail should be extracted.
      • File Upload: a file input to upload thumbnail file is provided to the users.

Extra: By default, straightToPublishing workflow parameter must be set to active, in order for this feature to work. This is because having straightToPublishing deactivated, puts the event in cutting mode, by which no thumbnail process is performed.

Overview

Screenshot 2024-07-12 at 14 16 17

Workflow Changes in Opencast

In order to support Thumbnail upload in Opencast, it is necessary to install the following workflows and encoding properties in your Opencast system.

Encoding Profiles

To support the thumbnail upload, the following encoding profiles need to be installed in your Opencast.

  1. Copy the following encoding profiles content:
# Player preview image regular size
profile.preview-regular.image.name = player preview image regular size
profile.preview-regular.image.input = image
profile.preview-regular.image.output = image
profile.preview-regular.image.suffix = -preview-regular.jpg
profile.preview-regular.image.mimetype = image/jpeg
profile.preview-regular.image.ffmpeg.command = -i #{in.video.path} \
-vf "scale=1280:720" \
#{out.dir}/#{out.name}#{out.suffix}
# Player preview image small size
profile.preview-small.image.name = player preview image regular size
profile.preview-small.image.input = image
profile.preview-small.image.output = image
profile.preview-small.image.suffix = -preview-small.jpg
profile.preview-small.image.mimetype = image/jpeg
profile.preview-small.image.ffmpeg.command = -i #{in.video.path} \
-vf "scale=160:90" \
#{out.dir}/#{out.name}#{out.suffix}
  1. Create a file in your Opencast under /etc/opencast/encoding/manual-thumb.properties
  2. Paste the copied content in that newly created file

Note

You could name the file anything you want to, but keep in mind that it needs to finish with .properties. No restart is needed.

Workflow: fast-with-thumbnail-support

This is a customized “fast” workflow. IF you are currently using that workflow, and you would like to use upload thumbnail feature in ILIAS you would need to do the following:

  1. Create a new workflow file in your Opencast under /etc/opencast/workflows/fast-with-thumbnail-support.xml with the following content:
fast-with-thumbnail-support.xml
<?xml version="1.0" encoding="UTF-8"?>
<definition xmlns="http://workflow.opencastproject.org">
    <id>fast-with-thumbnail-support</id>
    <title>Fast Testing Workflow With Thumbnail Support</title>
    <tags>
        <tag>upload</tag>
        <tag>schedule</tag>
        <tag>thumb</tag>
    </tags>
    <displayOrder>1000</displayOrder>
    <description>
        A minimal workflow that transcodes media into distribution formats,
        then publishes the resulting distribution files, along with their
        associated metadata. It is also capable of processing manual thumbnail
        upload or time selection.
    </description>
    <configuration_panel>
        <![CDATA[
        <div id="workflow-configuration">
        <fieldset>
        <input id="straightToPublishing" name="straightToPublishing" type="checkbox" class="configField" value="true" />
        <label for="straightToPublishing">Straight to publishing</label>
        </fieldset>
        </div>
        ]]>
    </configuration_panel>
    <configuration_panel_json>
        [{
            "fieldset": [
            {
                "type": "checkbox",
                "name": "straightToPublishing",
                "label": "Straight to publishing",
                "value": true
            }
            ]
        }]
    </configuration_panel_json>
    <operations>
        <operation
            id="defaults"
            description="Applying default configuration values">
            <configurations>
                <configuration key="straightToPublishing">true</configuration>
                <configuration key="withUploadedThumbnail">false</configuration>
                <configuration key="snapshotThumbnailTime">0</configuration>
            </configurations>
        </operation>
        <operation
            id="conditional-config"
            description="Evaluate thumbnail related configurations and set the thumbnail publish mode">
            <configurations>
                <configuration
                    key="configuration-name">publish-with-thumbnail</configuration>
                <!-- Snapshot -->
                <configuration key="condition-1">
                    (${straightToPublishing}) AND (${snapshotThumbnailTime} &gt; 0)
                </configuration>
                <configuration key="value-1">1</configuration>
                <!-- Uploaded -->
                <configuration key="condition-2">
                    (${straightToPublishing}) AND (${withUploadedThumbnail})
                </configuration>
                <configuration key="value-2">2</configuration>
                <!-- Default -->
                <configuration key="condition-3">
                    (${straightToPublishing})
                </configuration>
                <configuration key="value-3">0</configuration>
                <!-- More conditions omitted... -->
                <configuration key="no-match">3</configuration>
            </configurations>
        </operation>
        <operation
            id="series"
            fail-on-error="true"
            description="Applying access control entries from series">
            <configurations>
                <configuration key="apply-acl">true</configuration>
            </configurations>
        </operation>
        <operation
            id="inspect"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Inspecting audio and video streams">
            <configurations>
                <configuration key="overwrite">false</configuration>
                <configuration key="accept-no-media">false</configuration>
            </configurations>
        </operation>
        <operation
            id="encode"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Encoding video">
            <configurations>
                <configuration key="source-flavor">*/source</configuration>
                <configuration key="target-flavor">*/preview</configuration>
                <configuration
                    key="target-tags">engage-download,engage-streaming,rss,atom</configuration>
                <configuration key="encoding-profile">fast.http</configuration>
            </configurations>
        </operation>
        <operation
            id="tag"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Tag captions for publication">
            <configurations>
                <configuration key="source-flavor">captions/source</configuration>
                <configuration key="target-flavor">captions/preview</configuration>
                <configuration key="target-tags">+engage-download</configuration>
                <configuration key="copy">true</configuration>
            </configurations>
        </operation>
        <!-- Default preview -->
        <operation
            id="image"
            if="${publish-with-thumbnail} == 0"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Creating Engage search result thumbnails">
            <configurations>
                <configuration key="source-flavor">*/source</configuration>
                <configuration key="target-flavor">*/search+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">search-cover.http</configuration>
                <configuration key="time">1</configuration>
            </configurations>
        </operation>
        <operation
            id="image"
            if="${publish-with-thumbnail} == 0"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Creating Engage player preview image">
            <configurations>
                <configuration key="source-flavor">*/source</configuration>
                <configuration key="target-flavor">*/player+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">player-preview.http</configuration>
                <configuration key="time">1</configuration>
            </configurations>
        </operation>
        <!-- End Default preview -->
        <!-- Snapshot preview -->
        <operation 
            id="image"
            if="${publish-with-thumbnail} == 1"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Creating Engage search result
            thumbnails (snapshot)">
            <configurations>
                <configuration key="source-flavor">*/source</configuration>
                <configuration key="target-flavor">*/search+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">search-cover.http</configuration>
                <configuration key="time">${snapshotThumbnailTime}</configuration>
            </configurations>
        </operation>
        <operation
            id="image"
            if="${publish-with-thumbnail} == 1"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Creating Engage player preview image (snapshot)">
            <configurations>
                <configuration key="source-flavor">*/source</configuration>
                <configuration key="target-flavor">*/player+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">player-preview.http</configuration>
                <configuration key="time">${snapshotThumbnailTime}</configuration>
            </configurations>
        </operation>
        <!-- End Snapshot preview -->
        <!-- Uploaded preview -->
        <operation
            id="image-convert"
            if="${publish-with-thumbnail} == 2"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Creating Engage search result thumbnails (uploaded)">
            <configurations>
                <configuration key="source-tags">player</configuration>
                <configuration key="source-flavor">*/preview</configuration>
                <configuration key="tags-and-flavors">true</configuration>
                <configuration key="target-flavor">*/search+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">preview-small.image</configuration>
            </configurations>
        </operation>
        <operation
            id="image-convert"
            if="${publish-with-thumbnail} == 2"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Creating Engage player preview image (uploaded)">
            <configurations>
                <configuration key="source-tags">player</configuration>
                <configuration key="source-flavor">*/preview</configuration>
                <configuration key="tags-and-flavors">true</configuration>
                <configuration key="target-flavor">*/player+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">preview-regular.image</configuration>
            </configurations>
        </operation>
        <!-- End Uploaded preview -->
        <operation
            id="segment-video"
            if="${straightToPublishing}"
            fail-on-error="false"
            exception-handler-workflow="partial-error"
            description="Detecting slide transitions in presentation track">
            <configurations>
                <configuration
                    key="source-flavor">presentation/source</configuration>
                <configuration key="target-tags">engage-download</configuration>
            </configurations>
        </operation>
        <operation
            id="segmentpreviews"
            if="${straightToPublishing}"
            fail-on-error="false"
            exception-handler-workflow="partial-error"
            description="Creating presentation segments preview image">
            <configurations>
                <configuration
                    key="source-flavor">presentation/source</configuration>
                <configuration
                    key="target-flavor">presentation/segment+preview</configuration>
                <configuration key="reference-tags">engage-download</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">player-slides.http</configuration>
            </configurations>
        </operation>
        <operation
            id="publish-configure"
            exception-handler-workflow="partial-error"
            description="Publish to preview publication channel">
            <configurations>
                <configuration
                    key="download-source-flavors">*/preview</configuration>
                <configuration key="channel-id">internal</configuration>
                <configuration key="url-pattern">
                    ${org_org_opencastproject_admin_ui_url!'http://localhost:8080'}/admin-ng/index.html#/events/events/${event_id}/tools/editor
                </configuration>
                <configuration key="check-availability">false</configuration>
            </configurations>
        </operation>
        <operation
            id="publish-engage"
            max-attempts="2"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Publishing to Opencast Media Module">
            <configurations>
                <configuration
                    key="download-source-flavors">dublincore/*,security/*</configuration>
                <configuration
                    key="download-source-tags">engage-download</configuration>
                <configuration key="check-availability">false</configuration>
            </configurations>
        </operation>
        <operation
            id="snapshot"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Archiving">
            <configurations>
                <configuration
                    key="source-flavors">*/source,dublincore/*,security/*</configuration>
            </configurations>
        </operation>
        <operation
            id="cleanup"
            fail-on-error="false"
            description="Remove temporary processing artifacts">
            <configurations>
                <!-- On systems with shared workspace or working file repository -->
                <!-- you want to set this option to false. -->
                <configuration key="delete-external">true</configuration>
                <!-- ACLs are required again when working through ActiveMQ messages -->
                <configuration key="preserve-flavors">security/*</configuration>
            </configurations>
        </operation>
        <state-mappings>
            <state-mapping
                state="running">EVENTS.EVENTS.STATE_MAPPING.IMPORTING</state-mapping>
            <state-mapping
                state="failing">EVENTS.EVENTS.STATE_MAPPING.IMPORTING</state-mapping>
        </state-mappings>
    </operations>
</definition>

Note

You can name the file anything you want but you should also reflect it in the workflow id.

Workflow: schedule-and-upload-with-thumbnail-support

This is the customized “schedule-and-upload” workflow. If you are currently using this as your processing workflow, and you would like to use thumbnail upload feature, you would need to install the two following workflows:

  • schedule-and-upload-with-thumbnail-support
  • partial-publish-with-thumbnail-support

Warning

The default workflows from Opencast version 15 have been used as the basis for these workflows. If you have already customised the schedule-and-upload and partial-publish workflows, please ensure that you apply the changes made to the new workflows by comparing the default and customised workflows.

  1. Create a new workflow file in your Opencast under /etc/opencast/workflows/schedule-and-upload-with-thumbnail-support.xml with the following content:
schedule-and-upload-with-thumbnail-support.xml
<?xml version="1.0" encoding="UTF-8"?>
<definition xmlns="http://workflow.opencastproject.org">
    <id>schedule-and-upload-with-thumbnail-support</id>
    <title>Process upon upload and schedule With Thumbnail Support</title>
    <tags>
        <tag>upload</tag>
        <tag>schedule</tag>
    </tags>
    <displayOrder>1000</displayOrder>
    <description>
        The default workflow for processing media.
        If straight to publishing is checked, then the uploaded media will be
        published without cutting.
        It is also capable of processing manual thumbnail upload or time
        selection.
</description>
    <configuration_panel>
        <![CDATA[
        <div id="workflow-configuration">
            <fieldset>
                <input id="straightToPublishing" name="straightToPublishing" type="checkbox" class="configField" value="true" />
                <label for="straightToPublishing">Straight to publishing</label>
            </fieldset>
        </div>
        ]]>
    </configuration_panel>
    <configuration_panel_json>
        [{
            "fieldset": [
            {
                "type": "checkbox",
                "name": "straightToPublishing",
                "label": "Straight to publishing",
                "value": true
            }
            ]
        }]
    </configuration_panel_json>
    <operations>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Apply default workflow properties                                 -->
        <!--                                                                   -->
        <!-- The worklfow properties are simplified for a better               -->
        <!-- user experience, please preconfigure your defaults here.          -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <operation
            id="defaults"
            description="Applying default configuration values">
            <configurations>
                <configuration key="straightToPublishing">true</configuration>
                <configuration key="withUploadedThumbnail">false</configuration>
                <configuration key="snapshotThumbnailTime">0</configuration>
            </configurations>
        </operation>
        <operation
            id="conditional-config"
            description="Evaluate thumbnail related configurations and set the
        thumbnail mode">
            <configurations>
                <configuration key="configuration-name">thumbnail-mode</configuration>
                <!-- Snapshot -->
                <configuration key="condition-1">
                    (${snapshotThumbnailTime} &gt; 0)
                </configuration>
                <configuration key="value-1">1</configuration>
                <!-- Uploaded -->
                <configuration key="condition-2">
                    (${withUploadedThumbnail})
                </configuration>
                <configuration key="value-2">2</configuration>
                <!-- Default -->
                <configuration key="no-match">0</configuration>
            </configurations>
        </operation>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Prepare asset                                                     -->
        <!--                                                                   -->
        <!-- Prepare the recording for asset management, including creation of -->
        <!-- previews, audio waveforms and storing of the recording data in    -->
        <!-- the asset area for further processing.                            -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Make sure all elements are downloaded from external sources and -->
        <!-- inside of Opencast -->
        <operation
            id="include"
            description="Finalize upload and ingest">
            <configurations>
                <configuration key="workflow-id">partial-ingest</configuration>
            </configurations>
        </operation>
        <!-- Archive the source material -->
        <operation
            id="snapshot"
            description="Archive raw recording after ingest">
            <configurations>
                <configuration key="source-tags">archive</configuration>
            </configurations>
        </operation>
        <!-- Create preview artifacts -->
        <operation
            id="include"
            description="Prepare preview versions of the recording">
            <configurations>
                <configuration key="workflow-id">partial-preview</configuration>
            </configurations>
        </operation>
        <!-- Archive generated preview assets -->
        <operation
            id="snapshot"
            description="Archive preview information">
            <configurations>
                <configuration key="source-tags">archive</configuration>
            </configurations>
        </operation>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Tag for review and cutting                                      -->
        <!--                                                                 -->
        <!-- Add comments in order to mark the recording for preview and/or  -->
        <!-- cutting.                                                        -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Mark the recording for cutting -->
        <operation
            id="comment"
            if="NOT ${straightToPublishing}"
            description="Mark the recording for cutting">
            <configurations>
                <configuration key="description">Recording has not been cut
                    yet.</configuration>
                <configuration
                    key="reason">EVENTS.EVENTS.DETAILS.COMMENTS.REASONS.CUTTING</configuration>
                <configuration key="action">create</configuration>
            </configurations>
        </operation>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Publish                                                         -->
        <!--                                                                 -->
        <!-- Encode and publish the recording to the predefined              -->
        <!-- publication channels.                                           -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <operation
            id="include"
            if="${straightToPublishing}"
            description="Publish the recording with thumbnail support">
            <configurations>
                <configuration
                    key="workflow-id">partial-publish-with-thumbnail-support</configuration>
            </configurations>
        </operation>
        <!-- Archive the recording -->
        <operation
            id="snapshot"
            if="${straightToPublishing}"
            description="Archive publishing information">
            <configurations>
                <configuration key="source-tags">archive</configuration>
            </configurations>
        </operation>
        <!-- Clean up work artifacts -->
        <operation
            id="cleanup"
            fail-on-error="false"
            description="Remove temporary processing artifacts">
            <configurations>
                <!-- On systems with shared workspace or working file repository -->
                <!-- you want to set this option to false. -->
                <configuration key="delete-external">true</configuration>
                <!-- ACLs are required again when working through ActiveMQ messages -->
                <configuration key="preserve-flavors">security/*</configuration>
            </configurations>
        </operation>
    </operations>
</definition>

Note

You can name the file anything you want but you should also reflect it in the workflow id.

  1. Create a new workflow file in your Opencast under /etc/opencast/workflows/partial-publish-with-thumbnail-support.xml with the following content:
partial-publish-with-thumbnail-support.xml
<?xml version="1.0" encoding="UTF-8"?>
<definition xmlns="http://workflow.opencastproject.org">
    <id>partial-publish-with-thumbnail-support</id>
    <title>Publish the recording with thumbnail support</title>
    <tags />
    <description />
    <configuration_panel />
    <configuration_panel_json />
    <operations>
        <!-- If not already set, set thumnail-mode to 0 -->
        <operation
            id="defaults"
            description="Applying default configuration values">
            <configurations>
                <configuration key="thumbnail-mode">0</configuration>
            </configurations>
        </operation>
        <!-- Fall back to */source if */prepared does not exist -->
        <operation
            id="analyze-tracks"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Analyze tracks in media package and set control variables">
            <configurations>
                <configuration key="source-flavor">*/prepared</configuration>
            </configurations>
        </operation>
        <operation
            if="NOT (${presentation_prepared_media} OR ${presenter_prepared_media})"
            id="clone"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Preparing media">
            <configurations>
                <configuration key="source-flavor">*/source</configuration>
                <configuration key="target-flavor">*/prepared</configuration>
            </configurations>
        </operation>
        <!-- Continue processing -->
        <operation
            id="select-tracks"
            exception-handler-workflow="partial-error"
            description="Selecting audio/video streams for processing">
            <configurations>
                <configuration key="source-flavor">*/prepared</configuration>
                <configuration key="target-flavor">*/work</configuration>
                <configuration key="target-tags">-archive</configuration>
                <configuration key="audio-muxing">duplicate</configuration>
            </configurations>
        </operation>
        <!-- Keep captions in the loop, as they are ignored by select-tracks
        -->
        <operation
            id="tag"
            description="Tag captions for cutting">
            <configurations>
                <configuration
                    key="source-flavors">captions/prepared</configuration>
                <configuration key="target-flavor">captions/work</configuration>
                <configuration key="target-tags">-archive</configuration>
                <configuration key="copy">true</configuration>
            </configurations>
        </operation>
        <operation
            id="analyze-tracks"
            exception-handler-workflow="partial-error"
            description="Analyzing tracks in media package and setting control variables">
            <configurations>
                <configuration key="source-flavor">*/work</configuration>
            </configurations>
        </operation>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Cut the video according the SMIL file                             -->
        <!--                                                                   -->
        <!-- Perform cutting according to the edit decision list.              -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <operation
            id="clone"
            exception-handler-workflow="partial-error"
            description="Creating working copy of the cutting information">
            <configurations>
                <configuration key="source-flavor">smil/cutting</configuration>
                <configuration key="target-flavor">smil/tmp</configuration>
            </configurations>
        </operation>
        <operation
            id="editor"
            exception-handler-workflow="partial-error"
            description="Cutting the recording according to the edit decision list">
            <configurations>
                <configuration key="source-flavors">*/work</configuration>
                <configuration key="smil-flavors">smil/tmp</configuration>
                <configuration key="target-smil-flavor">smil/tmp</configuration>
                <configuration key="target-flavor-subtype">trimmed</configuration>
                <configuration key="interactive">false</configuration>
            </configurations>
        </operation>
        <!-- Mark captions for publication -->
        <operation
            id="tag"
            description="Mark captions for publication">
            <configurations>
                <configuration
                    key="source-flavors">captions/trimmed</configuration>
                <configuration
                    key="target-flavor">captions/delivery</configuration>
                <configuration key="target-tags">+engage-download</configuration>
            </configurations>
        </operation>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Extract preview images                                            -->
        <!--                                                                   -->
        <!-- From the edited recording, take preview images for the player,    -->
        <!-- search results etc.                                               -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Encode to engage search result thumbnails -->
        <!-- Default search preview -->
        <operation
            id="image"
            if="${thumbnail-mode} == 0"
            exception-handler-workflow="partial-error"
            description="Creating search result default thumbnails">
            <configurations>
                <configuration key="source-flavor">*/trimmed</configuration>
                <configuration key="target-flavor">*/search+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">search-cover.http</configuration>
                <configuration key="time">3</configuration>
            </configurations>
        </operation>
        <!-- Snapshot search preview -->
        <operation
            id="image"
            if="${thumbnail-mode} == 1"
            exception-handler-workflow="partial-error"
            description="Creating search result default thumbnails (snapshot)">
            <configurations>
                <configuration key="source-flavor">*/trimmed</configuration>
                <configuration key="target-flavor">*/search+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">search-cover.http</configuration>
                <configuration key="time">${snapshotThumbnailTime}</configuration>
            </configurations>
        </operation>
        <!-- Uploaded search preview -->
        <operation
            id="image-convert"
            if="${thumbnail-mode} == 2"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Creating search result default thumbnails (uploaded)">
            <configurations>
                <configuration key="source-tags">player</configuration>
                <configuration key="source-flavor">*/preview</configuration>
                <configuration key="tags-and-flavors">true</configuration>
                <configuration key="target-flavor">*/search+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">preview-small.image</configuration>
            </configurations>
        </operation>
        <!-- Encode to engage player preview images -->
        <!-- Default presentation preview -->
        <operation
            id="image"
            if="NOT ${presentation/thumbnail_edited} AND (${thumbnail-mode} == 0)"
            exception-handler-workflow="partial-error"
            description="Creating player preview image for presentation video">
            <configurations>
                <configuration
                    key="source-flavor">presentation/trimmed</configuration>
                <configuration
                    key="target-flavor">presentation/player+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">player-preview.http</configuration>
                <configuration key="time">3</configuration>
            </configurations>
        </operation>
        <!-- Snapshot presentation preview -->
        <operation
            id="image"
            if="NOT ${presentation/thumbnail_edited} AND (${thumbnail-mode} == 1)"
            exception-handler-workflow="partial-error"
            description="Creating player preview image for presentation video (snapshot)">
            <configurations>
                <configuration
                    key="source-flavor">presentation/trimmed</configuration>
                <configuration
                    key="target-flavor">presentation/player+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">player-preview.http</configuration>
                <configuration key="time">${snapshotThumbnailTime}</configuration>
            </configurations>
        </operation>
        <!-- Uploaded presentation preview -->
        <operation
            id="image-convert"
            if="NOT ${presentation/thumbnail_edited} AND (${thumbnail-mode} == 2)"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Creating player preview image for presentation video (uploaded)">
            <configurations>
                <configuration key="source-tags">player</configuration>
                <configuration key="source-flavor">*/preview</configuration>
                <configuration key="tags-and-flavors">true</configuration>
                <configuration
                    key="target-flavor">presentation/player+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">preview-regular.image</configuration>
            </configurations>
        </operation>
        <operation
            id="tag"
            if="${presentation/thumbnail_edited}"
            exception-handler-workflow="partial-error"
            description="Prepare thumbnail for publication">
            <configurations>
                <configuration
                    key="source-flavor">presentation/player+preview</configuration>
                <configuration key="target-tags">+engage-download</configuration>
            </configurations>
        </operation>
        <!-- Encode to feed cover images -->
        <operation
            id="image"
            exception-handler-workflow="partial-error"
            description="Creating feed cover image">
            <configurations>
                <configuration key="source-flavor">*/trimmed</configuration>
                <configuration key="target-flavor">*/feed+preview</configuration>
                <configuration key="target-tags">atom,rss</configuration>
                <configuration
                    key="encoding-profile">feed-cover.http</configuration>
                <configuration key="time">3</configuration>
            </configurations>
        </operation>
        <!-- Create a cover image -->
        <!-- Default presenter preview -->
        <operation
            id="image"
            if="NOT ${presenter/thumbnail_edited} AND (${thumbnail-mode} == 0)"
            exception-handler-workflow="partial-error"
            description="Creating player preview image for presenter video">
            <configurations>
                <configuration
                    key="source-flavor">presenter/trimmed</configuration>
                <configuration
                    key="target-flavor">presenter/player+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">player-preview.http</configuration>
                <configuration key="time">3</configuration>
            </configurations>
        </operation>
        <operation
            id="image"
            if="NOT ${presenter/thumbnail_edited} AND (${thumbnail-mode} == 1)"
            exception-handler-workflow="partial-error"
            description="Creating player preview image for presenter video (snapshot)">
            <configurations>
                <configuration
                    key="source-flavor">presenter/trimmed</configuration>
                <configuration
                    key="target-flavor">presenter/player+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">player-preview.http</configuration>
                <configuration key="time">${snapshotThumbnailTime}</configuration>
            </configurations>
        </operation>
        <operation
            id="image-convert"
            if="NOT ${presenter/thumbnail_edited} AND (${thumbnail-mode} == 2)"
            fail-on-error="true"
            exception-handler-workflow="partial-error"
            description="Creating player preview image for presenter video (uploaded)">
            <configurations>
                <configuration key="source-tags">player</configuration>
                <configuration key="source-flavor">*/preview</configuration>
                <configuration key="tags-and-flavors">true</configuration>
                <configuration
                    key="target-flavor">presenter/player+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">preview-regular.image</configuration>
            </configurations>
        </operation>
        <operation
            id="tag"
            if="${presenter/thumbnail_edited}"
            exception-handler-workflow="partial-error"
            description="Prepare thumbnail for publication">
            <configurations>
                <configuration
                    key="source-flavor">presenter/player+preview</configuration>
                <configuration key="target-tags">+engage-download</configuration>
            </configurations>
        </operation>
        <!-- Generate timeline preview images -->
        <operation
            id="timelinepreviews"
            fail-on-error="false"
            exception-handler-workflow="partial-error"
            description="Creating timeline preview images">
            <configurations>
                <configuration key="source-flavor">*/trimmed</configuration>
                <configuration
                    key="target-flavor">*/timeline+preview</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration key="image-count">100</configuration>
            </configurations>
        </operation>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Apply theming                                                     -->
        <!--                                                                   -->
        <!-- Add trailer and bumper to the recording prior to publication.     -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <operation
            id="include"
            description="Including theming operations">
            <configurations>
                <configuration key="workflow-id">partial-theming</configuration>
            </configurations>
        </operation>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Encode for publication to Engage                                  -->
        <!--                                                                   -->
        <!-- Encode audio and video formats to the distribution formats that   -->
        <!-- are required by the Engage publication channel.                   -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Encode presenter (camera) and presentation (screen) -->
        <!-- to Engage player format -->
        <operation
            id="encode"
            exception-handler-workflow="partial-error"
            description="Encoding videos to mp4 delivery format">
            <configurations>
                <configuration key="source-flavor">*/themed</configuration>
                <configuration key="target-flavor">*/delivery</configuration>
                <configuration
                    key="target-tags">engage-download,engage-streaming</configuration>
                <configuration
                    key="encoding-profile">adaptive-parallel.http</configuration>
            </configurations>
        </operation>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Segment video streams and extract metadata                        -->
        <!--                                                                   -->
        <!-- Apply the video segmentation algorithm to the presentation tracks -->
        <!-- and extract segment preview images and metadata.                  -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Run the videosegmentation -->
        <operation
            id="segment-video"
            fail-on-error="false"
            description="Detecting slide transitions in presentation track">
            <configurations>
                <configuration
                    key="source-flavor">presentation/themed</configuration>
                <configuration key="target-tags">engage-download</configuration>
            </configurations>
        </operation>
        <!-- Generate segment preview images -->
        <operation
            id="segmentpreviews"
            fail-on-error="false"
            description="Creating preview images for presentation segments">
            <configurations>
                <configuration
                    key="source-flavor">presentation/themed</configuration>
                <configuration
                    key="target-flavor">presentation/segment+preview</configuration>
                <configuration
                    key="reference-flavor">presentation/delivery</configuration>
                <configuration key="reference-tags">engage-download</configuration>
                <configuration key="target-tags">engage-download</configuration>
                <configuration
                    key="encoding-profile">player-slides.http</configuration>
            </configurations>
        </operation>
        <!-- Extract text form slide preview images -->
        <operation
            id="extract-text"
            fail-on-error="false"
            description="Extracting text from presentation segments">
            <configurations>
                <configuration
                    key="source-flavor">presentation/themed</configuration>
                <configuration key="target-tags">engage-download</configuration>
            </configurations>
        </operation>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Publish to publication channels                                   -->
        <!--                                                                   -->
        <!-- Send the encoded material along with the metadata to the          -->
        <!-- publication channels.                                             -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!-- Publish to engage player -->
        <operation
            id="publish-engage"
            max-attempts="2"
            exception-handler-workflow="partial-error"
            description="Publishing to Opencast Media Module">
            <configurations>
                <configuration
                    key="download-source-flavors">dublincore/*,security/*</configuration>
                <configuration
                    key="download-source-tags">engage-download,atom,rss</configuration>
                <configuration
                    key="streaming-source-tags">engage-streaming</configuration>
                <configuration key="check-availability">false</configuration>
            </configurations>
        </operation>
        <!-- Here you can place operations to publish to your publication channels -->
    </operations>
</definition>

Note

You can name the file anything you want but you should also reflect it in the workflow id. IT SHOULD ALSO BE REFLECTED IN THE LAST WORKFLOW “schedule-and-upload-with-thumbnail-support”.

Extra Configuration Change:

After installing the new workflows to support the thumbnail upload, admins must change the "Processing Workflow ID" config setting to reflect the new workflow id under:

OpenCast plugin configuration > Settings > Events

After that the Wokflow Parameters must be freshly loaded from the API using "Load Parameters via API" and the straightToPublishing has to be either always active or shown to users to check.

OpenCast plugin configuration > Wokflow Parameters

Usage

In upload form, under "Thumbnail" section, depending on the mode selection in the configuration, users will see the option to.

  • Upload the thumbnail

Screenshot 2024-07-12 at 14 17 28

  • Set Timepoint

Screenshot 2024-07-12 at 14 17 03

  • Select the mode

Screenshot 2024-07-12 at 14 16 00