diff --git a/amd/src/opencastrecordings.js b/amd/src/opencastrecordings.js
new file mode 100644
index 000000000..9288bd52e
--- /dev/null
+++ b/amd/src/opencastrecordings.js
@@ -0,0 +1,173 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+import * as repository from './repository';
+import {exception as displayException} from 'core/notification';
+import {get_strings as getStrings} from 'core/str';
+
+/**
+ * Initiate the YUI langauge strings with appropriate values for the sortable list from Moodle.
+ *
+ * @param   {YUI} Y
+ * @returns {Promise}
+ */
+const initYuiLanguage = Y => {
+    const stringList = [
+        'view_recording_yui_first',
+        'view_recording_yui_prev',
+        'view_recording_yui_next',
+        'view_recording_yui_last',
+        'view_recording_yui_page',
+        'view_recording_yui_go',
+        'view_recording_yui_rows',
+        'view_recording_yui_show_all',
+    ].map(key => {
+        return {
+            key,
+            component: 'bigbluebuttonbn',
+        };
+    });
+
+    return getStrings(stringList)
+        .then(([first, prev, next, last, goToLabel, goToAction, perPage, showAll]) => {
+            Y.Intl.add('datatable-paginator', Y.config.lang, {
+                first,
+                prev,
+                next,
+                last,
+                goToLabel,
+                goToAction,
+                perPage,
+                showAll,
+            });
+        })
+        .catch();
+};
+
+/**
+ * Format the supplied date per the specified locale.
+ *
+ * @param   {string} locale
+ * @param   {array} dateList
+ * @returns {array}
+ */
+const formatDates = (locale, dateList) => dateList.map(row => {
+    const date = new Date(row.date);
+    row.date = date.toLocaleDateString(locale, {
+        weekday: 'long',
+        year: 'numeric',
+        month: 'long',
+        day: 'numeric'
+    });
+
+    return row;
+});
+
+/**
+ * Format response data for the table.
+ *
+ * @param   {string} response JSON-encoded table data
+ * @returns {array}
+ */
+const getFormattedData = response => {
+    const recordingData = response.tabledata;
+    let rowData = JSON.parse(recordingData.data);
+
+    rowData = formatDates(recordingData.locale, rowData);
+
+    return rowData;
+};
+/**
+ *
+ * @param {String} tableId in which we will display the table
+ * @returns {[(*|number), string, boolean]}
+ */
+const getTableInformations = (tableId) => {
+    const tableElement = document.querySelector(tableId);
+    const bbbid = tableElement.dataset.bbbid;
+    const tools = tableElement.dataset.tools;
+    return [bbbid, tools];
+};
+
+/**
+ * Setup the data table for the specified BBB instance.
+ *
+ * @param {String} tableId in which we will display the table
+ * @param   {object} response The response from the data request
+ * @returns {Promise}
+ */
+const setupDatatable = (tableId, response) => {
+    if (!response) {
+        return Promise.resolve();
+    }
+
+    if (!response.status) {
+        // Something failed. Continue to show the plain output.
+        return Promise.resolve();
+    }
+
+    const recordingData = response.tabledata;
+
+    let showRecordings = recordingData.profile_features.indexOf('all') !== -1;
+    showRecordings = showRecordings || recordingData.profile_features.indexOf('showrecordings') !== -1;
+    if (!showRecordings) {
+        // TODO: This should be handled by the web service.
+        // This user is not allowed to view recordings.
+        return Promise.resolve();
+    }
+
+    return new Promise(function (resolve) {
+        // eslint-disable-next-line
+        YUI({
+            lang: recordingData.locale,
+        }).use('intl', 'datatable', 'datatable-sort', 'datatable-paginator', 'datatype-number', Y => {
+            initYuiLanguage(Y)
+                .then(() => {
+                    const tableData = getFormattedData(response);
+
+                    const dataTable = new Y.DataTable({
+                        width: "1195px",
+                        columns: recordingData.columns,
+                        data: tableData,
+                        rowsPerPage: 3,
+                        paginatorLocation: ['header', 'footer']
+                    });
+                    dataTable.set('currentData', dataTable.get('data'));
+                    dataTable.set('currentFilter', '');
+
+                    return dataTable;
+                })
+                .then(resolve)
+                .catch();
+        });
+    })
+    .then(dataTable => {
+        dataTable.render(tableId);
+        return dataTable;
+    });
+};
+
+/**
+ * Initialise opencast recordings code.
+ *
+ * @method init
+ * @param {String} tableId in which we will display the table
+ */
+export const init = (tableId) => {
+    const [bbbid, tools] = getTableInformations(tableId);
+    repository.fetchOpencastRecordings(bbbid, tools)
+        .then(response => setupDatatable(tableId, response))
+        .catch(displayException);
+};
diff --git a/amd/src/repository.js b/amd/src/repository.js
index a947160a9..656308d87 100644
--- a/amd/src/repository.js
+++ b/amd/src/repository.js
@@ -95,3 +95,31 @@ export const meetingInfo = args => fetchMany([
         args,
     }
 ])[0];
+
+/**
+ * Request for Opencast recording
+ *
+ * @param   {Number} bigbluebuttonbnid The instance ID
+ * @param   {String} tools the set of tools to display
+ * @returns {Promise}
+ */
+
+ const getOpencastListTableRequest = (bigbluebuttonbnid, tools)  => {
+    return {
+        methodname: 'mod_bigbluebutton_opencast_recording_list_table',
+        args: {
+            bigbluebuttonbnid,
+            tools
+        }
+    };
+};
+
+/**
+ * Fetch the list of Opencast recordings from the server.
+ *
+ * @param   {Number} bigbluebuttonbnid The instance ID
+ * @param   {String} tools the set of tools to display
+ * @returns {Promise}
+ */
+ export const fetchOpencastRecordings = (bigbluebuttonbnid, tools) =>
+    fetchMany([getOpencastListTableRequest(bigbluebuttonbnid, tools)])[0];
diff --git a/classes/external/get_opencast_recordings.php b/classes/external/get_opencast_recordings.php
new file mode 100644
index 000000000..14cc65c75
--- /dev/null
+++ b/classes/external/get_opencast_recordings.php
@@ -0,0 +1,233 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * BigBlueButtonBN internal API for Opencast recordings
+ *
+ * @package   mod_bigbluebuttonbn
+ * @category  external
+ * @copyright 2018 onwards, Blindside Networks Inc
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace mod_bigbluebuttonbn\external;
+
+use external_api;
+use external_description;
+use external_function_parameters;
+use external_multiple_structure;
+use external_single_structure;
+use external_value;
+use external_warnings;
+use invalid_parameter_exception;
+use mod_bigbluebuttonbn\local\bigbluebutton;
+use mod_bigbluebuttonbn\local\config;
+use mod_bigbluebuttonbn\local\helpers\instance;
+use mod_bigbluebuttonbn\local\helpers\recording;
+use mod_bigbluebuttonbn\local\helpers\opencast;
+use mod_bigbluebuttonbn\plugin;
+
+/**
+ * External service to fetch a list of Opencast recordings from the Opencast server.
+ *
+ * @package   mod_bigbluebuttonbn
+ * @category  external
+ * @copyright 2018 onwards, Blindside Networks Inc
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class get_opencast_recordings extends external_api {
+    /**
+     * Returns description of method parameters
+     *
+     * @return external_function_parameters
+     */
+    public static function execute_parameters(): external_function_parameters {
+        return new external_function_parameters([
+            'bigbluebuttonbnid' => new external_value(PARAM_INT, 'bigbluebuttonbn instance id', VALUE_OPTIONAL),
+            'tools' => new external_value(PARAM_RAW, 'a set of enablec tools', VALUE_OPTIONAL),
+        ]);
+    }
+
+    /**
+     * Get a list of Opencast recordings
+     *
+     * @param int $bigbluebuttonbnid the bigbluebuttonbn instance id
+     * @param string $tools
+     * @return array of warnings and status result
+     * @throws \coding_exception
+     * @throws \dml_exception
+     * @throws \moodle_exception
+     * @throws \restricted_context_exception
+     * @throws invalid_parameter_exception
+     */
+    public static function execute(int $bigbluebuttonbnid = 0, $tools = 'edit,delete'): array {
+        $warnings = [];
+
+        // Validate the bigbluebuttonbnid ID.
+        [
+            'bigbluebuttonbnid' => $bigbluebuttonbnid,
+            'tools' => $tools,
+        ] = self::validate_parameters(self::execute_parameters(), [
+            'bigbluebuttonbnid' => $bigbluebuttonbnid,
+            'tools' => $tools,
+        ]);
+
+        // Fetch the session, features, and profile.
+        [
+            'bbbsession' => $bbbsession,
+            'context' => $context,
+            'enabledfeatures' => $enabledfeatures,
+            'typeprofiles' => $typeprofiles,
+        ] = instance::get_session_from_id($bigbluebuttonbnid);
+
+        if ($bigbluebuttonbnid === 0) {
+            throw new invalid_parameter_exception('Both BigbluebuttonBN and Course IDs are null, we can either
+            have one or the other but not both at the same time');
+        }
+        // Validate that the user has access to this activity.
+        self::validate_context($context);
+
+        $tools = explode(',', $tools);
+
+        // Fetch the list of recordings.
+        $opencastrecordings =
+            opencast::bigbluebutton_get_opencast_recordings_for_table_view($bbbsession);
+
+        $tabledata = [
+            'activity' => bigbluebutton::bigbluebuttonbn_view_get_activity_status($bbbsession),
+            'ping_interval' => (int) config::get('waitformoderator_ping_interval') * 1000,
+            'locale' => plugin::bigbluebuttonbn_get_localcode(),
+            'profile_features' => $typeprofiles[0]['features'],
+            'columns' => [],
+            'data' => '',
+        ];
+
+        $data = [];
+
+        // Build table content.
+        if (isset($opencastrecordings)) {
+            // There are recordings for this meeting.
+            foreach ($opencastrecordings as $opencastrecording) {
+                $rowdata = opencast::bigbluebuttonbn_get_opencast_recording_data_row($bbbsession, $opencastrecording, $tools);
+                if (!empty($rowdata)) {
+                    $data[] = $rowdata;
+                }
+            }
+        }
+
+        $columns = [
+            [
+                'key' => 'playback',
+                'label' => get_string('view_recording_playback', 'bigbluebuttonbn'),
+                'width' => '125px',
+                'type' => 'html',
+                'allowHTML' => true,
+            ],
+            [
+                'key' => 'name',
+                'label' => get_string('view_recording_name', 'bigbluebuttonbn'),
+                'width' => '125px',
+                'type' => 'html',
+                'allowHTML' => true,
+            ],
+            [
+                'key' => 'description',
+                'label' => get_string('view_recording_description', 'bigbluebuttonbn'),
+                'sortable' => true,
+                'width' => '250px',
+                'type' => 'html',
+                'allowHTML' => true,
+            ],
+        ];
+
+        // Initialize table headers.
+        // For Opencast recording table to maintain the consistency, it checks if preview is enabled for the recording table.
+        if (recording::bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
+            $columns[] = [
+                'key' => 'preview',
+                'label' => get_string('view_recording_preview', 'bigbluebuttonbn'),
+                'width' => '250px',
+                'type' => 'html',
+                'allowHTML' => true,
+            ];
+        }
+
+        $columns[] = [
+            'key' => 'date',
+            'label' => get_string('view_recording_date', 'bigbluebuttonbn'),
+            'sortable' => true,
+            'width' => '225px',
+            'type' => 'html',
+            'allowHTML' => true,
+        ];
+        $columns[] = [
+            'key' => 'duration',
+            'label' => get_string('view_recording_duration', 'bigbluebuttonbn'),
+            'width' => '50px',
+            'allowHTML' => false,
+            'sortable' => true,
+        ];
+        if ($bbbsession['managerecordings']) {
+            $columns[] = [
+                'key' => 'actionbar',
+                'label' => get_string('view_recording_actionbar', 'bigbluebuttonbn'),
+                'width' => '120px',
+                'type' => 'html',
+                'allowHTML' => true,
+            ];
+        }
+
+        $tabledata['columns'] = $columns;
+        $tabledata['data'] = json_encode($data);
+
+        $returnval = [
+            'status' => true,
+            'tabledata' => $tabledata,
+            'warnings' => $warnings,
+        ];
+
+        return $returnval;
+    }
+
+    /**
+     * Describe the return structure of the external service.
+     *
+     * @return external_single_structure
+     * @since Moodle 3.0
+     */
+    public static function execute_returns(): external_single_structure {
+        return new external_single_structure([
+            'status' => new external_value(PARAM_BOOL, 'Whether the fetch was successful'),
+            'tabledata' => new external_single_structure([
+                'activity' => new external_value(PARAM_ALPHA),
+                'ping_interval' => new external_value(PARAM_INT),
+                'locale' => new external_value(PARAM_TEXT),
+                'profile_features' => new external_multiple_structure(new external_value(PARAM_TEXT)),
+                'columns' => new external_multiple_structure(new external_single_structure([
+                    'key' => new external_value(PARAM_ALPHA),
+                    'label' => new external_value(PARAM_TEXT),
+                    'width' => new external_value(PARAM_ALPHANUMEXT),
+                    // See https://datatables.net/reference/option/columns.type .
+                    'type' => new external_value(PARAM_ALPHANUMEXT, 'Column type', VALUE_OPTIONAL),
+                    'sortable' => new external_value(PARAM_BOOL, 'Whether this column is sortable', VALUE_OPTIONAL, false),
+                    'allowHTML' => new external_value(PARAM_BOOL, 'Whether this column contains HTML', VALUE_OPTIONAL, false),
+                ])),
+                'data' => new external_value(PARAM_RAW), // For now it will be json encoded.
+            ]),
+            'warnings' => new external_warnings()
+        ]);
+    }
+}
diff --git a/classes/local/config.php b/classes/local/config.php
index f2023976d..86bd69ebc 100644
--- a/classes/local/config.php
+++ b/classes/local/config.php
@@ -85,6 +85,7 @@ public static function defaultvalues() {
             'recordings_preview_editable' => false,
             'recordings_validate_url' => true,
             'recording_default' => true,
+            'oc_recording' => false,
             'recording_editable' => true,
             'recording_icons_enabled' => true,
             'recording_all_from_start_default' => false,
@@ -199,6 +200,7 @@ public static function get_options() {
                'recordings_preview_editable' => self::get('recordings_preview_editable'),
                'recordings_validate_url' => self::get('recordings_validate_url'),
                'recording_default' => self::get('recording_default'),
+               'oc_recording' => self::get('oc_recording'),
                'recording_editable' => self::get('recording_editable'),
                'recording_icons_enabled' => self::get('recording_icons_enabled'),
                'recording_all_from_start_default' => self::get('recording_all_from_start_default'),
diff --git a/classes/local/helpers/meeting.php b/classes/local/helpers/meeting.php
index 6f5b5ec99..5e8ac47d0 100644
--- a/classes/local/helpers/meeting.php
+++ b/classes/local/helpers/meeting.php
@@ -31,6 +31,7 @@
 use mod_bigbluebuttonbn\local\config;
 use mod_bigbluebuttonbn\plugin;
 use stdClass;
+use mod_bigbluebuttonbn\local\helpers\opencast;
 
 defined('MOODLE_INTERNAL') || die();
 
@@ -234,6 +235,16 @@ public static function bigbluebuttonbn_create_meeting_metadata(&$bbbsession) {
         if ((boolean) config::get('meetingevents_enabled')) {
             $metadata['analytics-callback-url'] = $bbbsession['meetingEventsURL'];
         }
+        // If block_opencast is installed and the option to send the Opencast series ID to BBB is enabled,
+        // pass the Opencast series ID of the course as opencast-dc-isPartOf within the BBB metadata.
+        // Additionally, in order to identify and get the BBB recording on opencast, $bbbsession['meetingid'] as opencast-dc-subject metadata will be sent.
+        if ((boolean) config::get('opencast_recording')) {
+            $ocseriesid = opencast::bigbluebuttonbn_check_opencast($bbbsession['course']->id);
+            if ($ocseriesid != false) {
+                $metadata['opencast-dc-isPartOf'] = $ocseriesid;
+                $metadata['opencast-dc-subject'] = $bbbsession['meetingid'];
+            }
+        }
         return $metadata;
     }
 
diff --git a/classes/local/helpers/opencast.php b/classes/local/helpers/opencast.php
new file mode 100644
index 000000000..a52be67da
--- /dev/null
+++ b/classes/local/helpers/opencast.php
@@ -0,0 +1,516 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/**
+ * The mod_bigbluebuttonbn opencast helper
+ *
+ * @package   mod_bigbluebuttonbn
+ * @copyright 2021 onwards, Blindside Networks Inc
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @author    Farbod Zamani  (zamani [at] elan-ev [dt] de)
+ */
+
+namespace mod_bigbluebuttonbn\local\helpers;
+
+use moodle_url;
+use stdClass;
+use core_plugin_manager;
+use html_writer;
+use dml_exception;
+use moodle_exception;
+use oauth_helper;
+use mod_bigbluebuttonbn\local\helpers\recording;
+use ReflectionMethod;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Utility class for Opencast helper
+ *
+ * @package mod_bigbluebuttonbn
+ * @copyright 2021 onwards, Blindside Networks Inc
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+class opencast {
+
+    /**
+     * Helper function which checks if the Opencast plugin (block_opencast) is installed. The function is called from several places throughout mod_bigbluebuttonbn where Opencast functionality can enhance the BBB meeting recording functionality as soon as the Opencast plugin is present.
+     * If called with a course ID as parameter, the function will not only check if the Opencast plugin is installed. It will also ensure that an Opencast series exists for the given course and will return the Opencast series ID instead of a boolean. In this case, the block does not necessarily be placed in the course.
+     *
+     * @param  string    $courseid
+     * @return boolean|string
+     */
+    public static function bigbluebuttonbn_check_opencast($courseid = null) {
+        $blockplugins = core_plugin_manager::instance()->get_plugins_of_type('block');
+        // If block_opencast is installed.
+        if (in_array('opencast', array_keys($blockplugins))) {
+            // Getting an instance of the block_opencast API bridge.
+            $opencast = \block_opencast\local\apibridge::get_instance();
+            // If the block_opencast API bridge is not configured.
+            if (!$opencast) {
+                return false;
+            }
+            // If a courseid is given, we will return the Opencast series ID for the course.
+            if (is_numeric($courseid) && $courseid > 0) {
+                // Get and return the Opencast series ID for the given course. Let Opencast create a new series if there isn't a series yet for this course.
+                // If an exception occurs during this process, return false as the Opencast integration is not usable at the moment which is the same as if the Opencast plugin would not be installed at all.
+                try {
+                    // Use get_stored_seriesid method in order to retreive the series id, but when the method accepts more than 1 parameter which is introduced in v3.11-r1 of block_opencast.
+                    $getstoredseriesidreflection = new ReflectionMethod($opencast, 'get_stored_seriesid');
+                    if (count($getstoredseriesidreflection->getParameters()) > 1) {
+                        // The second parameter ($createifempty = true) of this method helps to create the series when it does not exist.
+                        $series = $opencast->get_stored_seriesid($courseid, true);
+                    } else {
+                        // If get_stored_seriesid accepts only 1 argument, then we use another method called ensure_course_series_exists. Mostly used for older versions of block_opencast plugin.
+                        // To make sure that the ensure_course_series_exists method accepts all the parameters it needs, we use ReflectionMethod and call_user_func_array.
+                        $ensurecourseseriesexistsreflection = new ReflectionMethod($opencast, 'ensure_course_series_exists');
+                        // Filling up an array with null value based on parameters' count of ensure_course_series_exists method.
+                        $args = array_fill(0, count($ensurecourseseriesexistsreflection->getParameters()), null);
+                        // Replace the first element of args array with courseid
+                        $args[0] = $courseid;
+                        $series = call_user_func_array([$opencast, 'ensure_course_series_exists'], $args);
+                    }
+                    if (is_object($series) && $series->identifier) {
+                        $seriesid = $series->identifier;
+                    } else {
+                        $seriesid = $series;
+                    }
+                    return $seriesid;
+                } catch (Exception $e) {
+                    return false;
+                }
+            }
+            // The block_opencast plugin is installed.
+            return true;
+        }
+        // If block_opencast plugin is NOT installed.
+        return false;
+    }
+
+    /**
+     * Helper function to get BBB recordings from the Opencast video available in the course.
+     * It uses block_opencast for getting all videos for the course and match them with meeting id.
+     * It uses tool_opencast for making an api call to get mediapackage of vidoes.
+     *
+     * @param object $bbbsession
+     *
+     *  @return array $bbbocvideos Opencast recordings of the BBB session
+     */
+    public static function bigbluebutton_get_opencast_recordings_for_table_view($bbbsession) {
+        $bbbocvideos = array();
+        // Initializing the api from tool_opencast plugin.
+        $api = new \tool_opencast\local\api();
+        // Getting an instance of apibridge from block_opencast plugin.
+        $opencast = \block_opencast\local\apibridge::get_instance();
+        // Getting the course videos from block_opencast plugin.
+        $ocvideos = $opencast->get_course_videos($bbbsession['course']->id);
+        if ($ocvideos->error == 0) {
+            foreach ($ocvideos->videos as $ocvideo) {
+                // Check subjects of opencast video contains $bbbsession['meetingid'].
+                if (in_array($bbbsession['meetingid'], $ocvideo->subjects)) {
+                    // Converting $ocvideo object to array.
+                    $ocvideoarray = json_decode(json_encode($ocvideo), true);
+                    // Get mediapackage json using api call.
+                    $url = '/search/episode.json?id=' . $ocvideo->identifier;
+                    $search_result = json_decode($api->oc_get($url), true);
+                    if ($api->get_http_code() == 200 && isset($search_result['search-results']['result']['mediapackage'])) {
+                        // Add mediapackage to array if exists.
+                        $ocvideoarray['mediapackage'] = $search_result['search-results']['result']['mediapackage'];
+                    }
+                    $bbbocvideos[] = $ocvideoarray;
+                }
+            }
+        }
+        return $bbbocvideos;
+    }
+
+    /**
+     * Helper function builds a row for the data used by the Opencast recording table.
+     *
+     * @param array $bbbsession
+     * @param array $ocrecording
+     *
+     * @return array
+     */
+    public static function bigbluebuttonbn_get_opencast_recording_data_row($bbbsession, $ocrecording, $tools = ['edit', 'delete']) {
+        global $OUTPUT, $PAGE;
+        if (!self::bigbluebuttonbn_include_opencast_recording_table_row($bbbsession)) {
+            return;
+        }
+        $rowdata = new stdClass();
+        // Set recording playback url.
+        $rowdata->playback = self::bigbluebuttonbn_get_opencast_recording_data_row_playback($ocrecording, $bbbsession);
+        // Set recording name from title if exists, otherwise shows "Opencast Video".
+        $rowdata->name = isset($ocrecording['title']) ? $ocrecording['title'] : get_string('view_recording_list_opencast', 'bigbluebuttonbn');
+        // Set recording description.
+        $rowdata->description = isset($ocrecording['description']) ? $ocrecording['description'] : '';
+        // For Opencast recording table to maintain the consistency, it checks if preview is enabled for the recording table.
+        if (recording::bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
+            // Set recording_preview.
+            $rowdata->preview = self::bigbluebuttonbn_get_opencast_recording_data_row_preview($ocrecording);
+        }
+        // Set formatted date.
+        $rowdata->date = self::bigbluebuttonbn_get_opencast_recording_data_row_date_formatted($ocrecording);
+        // Set formatted duration.
+        $rowdata->duration = self::bigbluebuttonbn_get_opencast_recording_data_row_duration($ocrecording['duration']);
+        // Set actionbar, if user is allowed to manage recordings.
+        if ($bbbsession['managerecordings']) {
+            $rowdata->actionbar = self::bigbluebuttonbn_get_opencast_recording_data_row_actionbar($ocrecording, $bbbsession, $tools);
+        }
+        return $rowdata;
+    }
+
+    /**
+     * Helper function evaluates if Opencast recording row should be included in the table.
+     *
+     * @param array $bbbsession
+     *
+     * @return boolean
+     */
+    public static function bigbluebuttonbn_include_opencast_recording_table_row($bbbsession) {
+        // Administrators and moderators are always allowed.
+        if ($bbbsession['administrator'] || $bbbsession['moderator']) {
+            return true;
+        }
+        // When groups are enabled, exclude those to which the user doesn't have access to.
+        // Check if the record belongs to a Visible Group type.
+        list($course, $cm) = get_course_and_cm_from_cmid($bbbsession['cm']->id);
+        $groupmode = groups_get_activity_groupmode($cm);
+        $displayrow = true;
+        if (($groupmode != VISIBLEGROUPS)) {
+            $groupid = explode('[', $bbbsession['meetingid']);
+            if (isset($groupid[1])) {
+                // It is a group recording and the user is not moderator/administrator. Recording should not be included by default.
+                $displayrow = false;
+                $groupid = explode(']', $groupid[1]);
+                if (isset($groupid[0])) {
+                    foreach ($usergroups as $usergroup) {
+                        if ($usergroup->id == $groupid[0]) {
+                            // Include recording if the user is in the same group.
+                            $displayrow = true;
+                        }
+                    }
+                }
+            }
+        }
+        return $displayrow;
+    }
+
+    /**
+     * Helper function renders the link used for Opencast recording playback in row for the data used by the recording table.
+     * To display the video, it is important for a video in Opencast to be published with engage-player, also it is required to
+     * have filter_opencast plugin installed and configured. 
+     * The link redirects user to oc_view.php to authentificate the user via LTI and show the video in Opencast. 
+     *
+     * @param array $ocrecording
+     * @param array $bbbsession
+     *
+     * @return string
+     */
+    public static function bigbluebuttonbn_get_opencast_recording_data_row_playback($ocrecording, $bbbsession) {
+        global $CFG, $OUTPUT;
+        $text = get_string('view_recording_list_opencast', 'bigbluebuttonbn');
+        $href = '#';
+        // Check if the publication status has engage-player.
+        if (isset($ocrecording['publication_status']) && in_array('engage-player', $ocrecording['publication_status'])) {
+            // If filter_opencast is installed and configured,
+            // also if the LTI form handler JavaScript file in block_opencast is available to use in order to submit the LTI form.
+            if ((boolean) self::bigbluebuttonbn_check_opencast_filter() && file_exists("$CFG->dirroot/blocks/opencast/amd/src/block_lti_form_handler.js")) {
+                $href = $CFG->wwwroot . '/mod/bigbluebuttonbn/oc_player.php?identifier=' . $ocrecording['identifier'] .
+                '&bn=' . $bbbsession['bigbluebuttonbn']->id;
+            }
+        }
+
+        $linkattributes = array(
+            'id' => 'opencast-player-redirect-' . $ocrecording['identifier'],
+            'class' => 'btn btn-sm btn-default',
+            'target' => '_blank'
+        );
+        if ($href == '#' || empty($href)) {
+            unset($linkattributes['target']);
+            $linkattributes['class'] = 'btn btn-sm btn-warning';
+            $linkattributes['title'] = get_string('view_recording_format_error_opencast_unreachable', 'bigbluebuttonbn');
+        }
+        return $OUTPUT->action_link($href, $text, null, $linkattributes) . '&#32;';
+    }
+
+    /**
+     * Helper function builds Opencast recording preview used in row for the data used by the recording table.
+     *
+     * @param array $ocrecording
+     *
+     * @return string
+     */
+    public static function bigbluebuttonbn_get_opencast_recording_data_row_preview($ocrecording) {
+        $options = array('id' => 'preview-' . $ocrecording['identifier']);
+        $recordingpreview = html_writer::start_tag('div', $options);
+        $imageurl = '';
+        // Getting preview image from mediapackage attachments.
+        if (isset($ocrecording['mediapackage']['attachments']['attachment'])) {
+            foreach ($ocrecording['mediapackage']['attachments']['attachment'] as $attachment) {
+                // Looking for image only.
+                if (isset($attachment['mimetype']) && strpos($attachment['mimetype'], 'image') !== FALSE) {
+                    // Looking for the url of the preview image.
+                    if (empty($imageurl) && isset($attachment['type']) && isset($attachment['url'])) {
+                        // There are several type of attachments which are different in size.
+                        // More suitable sizes are of these types, respectively.
+                        $suitabletypes = array('search', 'feed');
+                        foreach ($suitabletypes as $type) {
+                            if (strpos($attachment['type'], $type) !== FALSE) {
+                                $imageurl = $attachment['url'];
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (!empty($imageurl)) {
+                    break;
+                }
+            }
+            if (!empty($imageurl)) {
+                $recordingpreview .= self::bigbluebuttonbn_get_opencast_recording_data_row_preview_images($imageurl);
+            }
+        }
+    
+        $recordingpreview .= html_writer::end_tag('div');
+        return $recordingpreview;
+    }
+
+    /**
+     * Helper function builds element with actual images used in Opencast recording preview row based on a selected playback.
+     *
+     * @param string $imageurl
+     *
+     * @return string
+     */
+    public static function bigbluebuttonbn_get_opencast_recording_data_row_preview_images($imageurl) {
+        global $CFG;
+        $recordingpreview  = html_writer::start_tag('div', array('class' => 'container-fluid'));
+        $recordingpreview .= html_writer::start_tag('div', array('class' => 'row'));
+        $recordingpreview .= html_writer::start_tag('div', array('class' => ''));
+        $recordingpreview .= html_writer::empty_tag(
+            'img',
+            array('src' => trim($imageurl) . '?' . time(), 'class' => 'recording-thumbnail pull-left')
+        );
+        $recordingpreview .= html_writer::end_tag('div');
+        $recordingpreview .= html_writer::end_tag('div');
+        $recordingpreview .= html_writer::start_tag('div', array('class' => 'row'));
+        $recordingpreview .= html_writer::tag(
+            'div',
+            get_string('view_recording_preview_help', 'bigbluebuttonbn'),
+            array('class' => 'text-center text-muted small')
+        );
+        $recordingpreview .= html_writer::end_tag('div');
+        $recordingpreview .= html_writer::end_tag('div');
+        return $recordingpreview;
+    }
+
+    /**
+     * Helper function format Opencast recording date used in row for the data used by the recording table.
+     *
+     * @param array $ocrecording
+     *
+     * @return string
+     */
+    public static function bigbluebuttonbn_get_opencast_recording_data_row_date_formatted($ocrecording) {
+        $starttime_str = !empty($ocrecording['start']) ? $ocrecording['start'] : $ocrecording['created'];
+        return $starttime_str;
+    }
+
+    /**
+     * Helper function converts Opencast recording duration used in row for the data used by the recording table.
+     *
+     * @param array $duration
+     *
+     * @return integer
+     */
+    public static function bigbluebuttonbn_get_opencast_recording_data_row_duration($duration) {
+        if ($duration) {
+            // Convert the duration (in miliseconds) into Hours:Minutes:Seconds format
+            return gmdate('H:i:s', $duration / 1000);
+        }
+        return 0;
+    }
+
+    /**
+     * Helper function builds Opencast recording actionbar used in row for the data used by the recording table.
+     *
+     * @param array $ocrecording
+     * @param array $bbbsession
+     * @param array $tools
+     *
+     * @return string
+     */
+    public static function bigbluebuttonbn_get_opencast_recording_data_row_actionbar($ocrecording, $bbbsession, $tools) {
+        global $OUTPUT;
+        if (empty($ocrecording['identifier']) || empty($bbbsession['course'])) {
+            return '';
+        }
+        $actionbar = '';
+        $linkattributes = array(
+            'target' => '_blank',
+            'class' => 'btn btn-xs btn-danger'
+        );
+        if (in_array('edit', $tools)) {
+            // Creating moodle url, to redirect to Opencast update metadata (Edit) page.
+            $opencastediturl = new moodle_url('/blocks/opencast/updatemetadata.php',
+                    array('video_identifier' => $ocrecording['identifier'], 'courseid' => $bbbsession['course']->id));
+            $linkattributes['id'] = 'opencast-edit-episode-' . $ocrecording['identifier'];
+            // Generating Action Link for Opencast update metadata (Edit).
+            $actionbar .= $OUTPUT->action_link($opencastediturl, get_string('edit'), null, $linkattributes) . '&#32;';
+        }
+        
+        if (in_array('delete', $tools)) {
+            // Creating moodle url, to redirect to Opencast delete event (Delete) page.
+            $opencastdeleteurl = new moodle_url('/blocks/opencast/deleteevent.php',
+                    array('identifier' => $ocrecording['identifier'], 'courseid' => $bbbsession['course']->id));
+            $linkattributes['id'] = 'opencast-delete-episode-' . $ocrecording['identifier'];
+            // Generating Action Link for Opencast delete event (Delete).
+            $actionbar .= $OUTPUT->action_link($opencastdeleteurl, get_string('delete'), null, $linkattributes) . '&#32;';
+        }
+        $head = html_writer::start_tag('div', array(
+            'id' => 'recording-actionbar-' . $ocrecording['identifier'],
+            'data-recordingid' => $ocrecording['identifier'],
+            'data-meetingid' => $bbbsession['meetingid']));
+        $tail = html_writer::end_tag('div');
+        return $head . $actionbar . $tail;
+    }
+
+    /**
+     * Helper function which checks if the Opencast Filter plugin (filter_opencast) is installed and configured.
+     * This function is used to display the BBB recordings on Opencast, which uses LTI to handle the authentication.
+     * 
+     * @return boolean|array
+     */
+    public static function bigbluebuttonbn_check_opencast_filter() {
+        $filterplugins = core_plugin_manager::instance()->get_plugins_of_type('filter');
+        // If filter_opencast is installed.
+        if (in_array('opencast', array_keys($filterplugins))) {
+            // In order to display the videos through LTI consumerkey and consumersecret must be configured in filter_opencast.
+            $consumerkey = get_config('filter_opencast', 'consumerkey');
+            $consumersecret = get_config('filter_opencast', 'consumersecret');
+
+            // Engageurl in filter_opencast plugin is the endpoint from which the Opencast player will be called.
+            $engageurl = get_config('filter_opencast', 'engageurl');
+            if (empty($engageurl)) {
+                // If it is not set in filter_opencast, the main apiurl setting of tool_opencast plugin will be used.
+                $engageurl = get_config('tool_opencast', 'apiurl');
+            }
+
+            if (strpos($engageurl, 'http') !== 0) {
+                $engageurl = 'http://' . $engageurl;
+            }
+
+            // A player url helps to predefine the endpoint to call the Opencast player directly.
+            $playerurl = get_config('filter_opencast', 'playerurl');
+            if (empty($playerurl)) {
+                // If it is not configured, /play/ endpoint will make Opencast to decide based on its internal configuration.
+                $playerurl = '/play/';
+            } else {
+                // If it is configured, then "id" query string is needed in any case.
+                $playerurl .= '?id=';
+            }
+
+            // Make sure the player url is correct.
+            $playerurl = '/' . ltrim($playerurl, '/');
+
+            // Make lti url.
+            $ltiendpoint = rtrim($engageurl, '/') . '/lti';
+
+            if (!empty($consumerkey) && !empty($consumersecret) && !empty($playerurl) && !empty($ltiendpoint)) {
+                // If filter_opencast plugin is configured.
+                return array(
+                    'consumerkey' => $consumerkey,
+                    'consumersecret' => $consumersecret,
+                    'engageurl' => $engageurl,
+                    'playerurl' => $playerurl,
+                    'ltiendpoint' => $ltiendpoint
+                );
+            } else {
+                // If filter_opencast plugin is NOT configured.
+                return false;
+            }
+        }
+        // If filter_opencast plugin is NOT installed.
+        return false;
+    }
+
+    /**
+     * Create necessary lti parameters.
+     * @param array $opencastfilterconfig the array of customized configuration from bigbluebuttonbn_check_opencast_filter function.
+     *
+     * @return array lti parameters
+     * @throws dml_exception
+     * @throws moodle_exception
+     */
+    function bigbluebuttonbn_create_lti_parameters_opencast($opencastfilterconfig) {
+        global $CFG, $COURSE, $USER;
+
+        $endpoint = $opencastfilterconfig['ltiendpoint'];
+        $consumerkey = $opencastfilterconfig['consumerkey'];
+        $consumersecret = $opencastfilterconfig['consumersecret'];
+        $customtool = $opencastfilterconfig['playerurl'];
+
+        $helper = new oauth_helper(array('oauth_consumer_key'    => $consumerkey,
+                                        'oauth_consumer_secret' => $consumersecret));
+
+        // Set all necessary parameters.
+        $params = array();
+        $params['oauth_version'] = '1.0';
+        $params['oauth_nonce'] = $helper->get_nonce();
+        $params['oauth_timestamp'] = $helper->get_timestamp();
+        $params['oauth_consumer_key'] = $consumerkey;
+
+        $params['context_id'] = $COURSE->id;
+        $params['context_label'] = trim($COURSE->shortname);
+        $params['context_title'] = trim($COURSE->fullname);
+        $params['resource_link_id'] = 'o' . random_int(1000, 9999) . '-' . random_int(1000, 9999);
+        $params['resource_link_title'] = 'Opencast';
+        $params['context_type'] = ($COURSE->format == 'site') ? 'Group' : 'CourseSection';
+        $params['launch_presentation_locale'] = current_language();
+        $params['ext_lms'] = 'moodle-2';
+        $params['tool_consumer_info_product_family_code'] = 'moodle';
+        $params['tool_consumer_info_version'] = strval($CFG->version);
+        $params['oauth_callback'] = 'about:blank';
+        $params['lti_version'] = 'LTI-1p0';
+        $params['lti_message_type'] = 'basic-lti-launch-request';
+        $urlparts = parse_url($CFG->wwwroot);
+        $params['tool_consumer_instance_guid'] = $urlparts['host'];
+        $params['custom_tool'] = $customtool;
+
+        // User data.
+        $params['user_id'] = $USER->id;
+        $params['lis_person_name_given'] = $USER->firstname;
+        $params['lis_person_name_family'] = $USER->lastname;
+        $params['lis_person_name_full'] = $USER->firstname . ' ' . $USER->lastname;
+        $params['ext_user_username'] = $USER->username;
+        $params['lis_person_contact_email_primary'] = $USER->email;
+        $params['roles'] = lti_get_ims_role($USER, null, $COURSE->id, false);
+
+        if (!empty($CFG->mod_lti_institution_name)) {
+            $params['tool_consumer_instance_name'] = trim(html_to_text($CFG->mod_lti_institution_name, 0));
+        } else {
+            $params['tool_consumer_instance_name'] = get_site()->shortname;
+        }
+
+        $params['launch_presentation_document_target'] = 'iframe';
+        $params['oauth_signature_method'] = 'HMAC-SHA1';
+        $signedparams = lti_sign_parameters($params, $endpoint, "POST", $consumerkey, $consumersecret);
+        $params['oauth_signature'] = $signedparams['oauth_signature'];
+
+        return $params;
+    }
+}
diff --git a/classes/local/settings/settings.php b/classes/local/settings/settings.php
index e782006ea..d0f2e051b 100644
--- a/classes/local/settings/settings.php
+++ b/classes/local/settings/settings.php
@@ -1076,4 +1076,44 @@ public function bigbluebuttonbn_settings_experimental() {
         }
         $this->admin->add($this->section, $experimentalfeaturessetting);
     }
+
+    /**
+     * Helper function renders Opencast integration settings if block_opencast is installed.
+     *
+     *
+     * @return void
+     */
+    function bigbluebuttonbn_settings_opencast_integration() {
+        // Configuration for 'Opencast integration' feature when Opencast plugins are installed.
+        // Through validator::section_opencast_shown(), it checks if the block_opencast is installed.
+        $opencastrecordingsetting = new admin_settingpage('opencast', get_string('config_opencast', 'bigbluebuttonbn'),
+            'moodle/site:config', !((boolean) validator::section_opencast_shown()) && ($this->moduleenabled));
+        if ($this->admin->fulltree) {
+            $item = new admin_setting_heading('bigbluebuttonbn_config_opencast_recording',
+                '',
+                get_string('config_opencast_description', 'bigbluebuttonbn'));
+            $opencastrecordingsetting->add($item);
+            $item = new admin_setting_configcheckbox('bigbluebuttonbn_opencast_recording',
+                get_string('config_opencast_recording', 'bigbluebuttonbn'),
+                get_string('config_opencast_recording_description', 'bigbluebuttonbn'),
+                1);
+            $this->add_conditional_element(
+                'opencast_recording',
+                $item,
+                $opencastrecordingsetting
+            );
+            $item = new admin_setting_configcheckbox('bigbluebuttonbn_opencast_show_recording',
+                get_string('config_opencast_show_recording', 'bigbluebuttonbn'),
+                get_string('config_opencast_show_recording_description', 'bigbluebuttonbn'),
+                1);
+            $this->add_conditional_element(
+                'opencast_show_recording',
+                $item,
+                $opencastrecordingsetting
+            );
+           
+        }
+        $this->admin->add($this->section, $opencastrecordingsetting);
+    }
+
 }
\ No newline at end of file
diff --git a/classes/local/settings/validator.php b/classes/local/settings/validator.php
index a5fcfe76c..a4b61fb65 100644
--- a/classes/local/settings/validator.php
+++ b/classes/local/settings/validator.php
@@ -26,6 +26,7 @@
 namespace mod_bigbluebuttonbn\local\settings;
 
 use mod_bigbluebuttonbn\local\bigbluebutton;
+use mod_bigbluebuttonbn\local\helpers\opencast;
 
 defined('MOODLE_INTERNAL') || die();
 require_once($CFG->libdir.'/adminlib.php');
@@ -279,4 +280,15 @@ public static function section_lockonjoinconfigurable_shown() {
         return (!isset($CFG->bigbluebuttonbn['lockonjoinconfigurable_default']) ||
             !isset($CFG->bigbluebuttonbn['lockonjoinconfigurable_editable']));
     }
+
+    /**
+     * Validate if opencast section will be shown.
+     * It uses the opencast::bigbluebuttonbn_check_opencast() without courseid, in order to check only if block_opencast is installed.
+     *
+     * @return boolean
+     */
+    public static function section_opencast_shown() {
+        //if the block_opencast is installed.
+        return opencast::bigbluebuttonbn_check_opencast();
+    }
 }
diff --git a/classes/local/view.php b/classes/local/view.php
index 1ea749965..e26b24d1b 100644
--- a/classes/local/view.php
+++ b/classes/local/view.php
@@ -32,6 +32,7 @@
 use mod_bigbluebuttonbn\local\helpers\meeting;
 use mod_bigbluebuttonbn\local\helpers\recording;
 use mod_bigbluebuttonbn\output\recordings_session;
+use mod_bigbluebuttonbn\output\opencast_recordings_session;
 use mod_bigbluebuttonbn\plugin;
 use pix_icon;
 
@@ -159,6 +160,11 @@ public static function view_render(&$bbbsession) {
 
             $output .= $renderer->render($recordingsection);
 
+            if (config::get('opencast_show_recording')) {
+                $opencastrecordingsection = new opencast_recordings_session($bbbsession, $type, $enabledfeatures);
+                $output .= $renderer->render($opencastrecordingsection);
+            }
+
         } else if ($type == bbb_constants::BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY) {
             $recordingsdisabled = get_string('view_message_recordings_disabled', 'bigbluebuttonbn');
             $output .= self::bigbluebuttonbn_render_warning($recordingsdisabled, 'danger');
diff --git a/classes/output/opencast_recordings_session.php b/classes/output/opencast_recordings_session.php
new file mode 100644
index 000000000..b48866029
--- /dev/null
+++ b/classes/output/opencast_recordings_session.php
@@ -0,0 +1,96 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Renderer for Opencast recording section.
+ *
+ * @package   mod_bigbluebuttonbn
+ * @copyright 2010 onwards, Blindside Networks Inc
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @author    Farbod Zamani  (zamani [at] elan-ev [dt] de)
+ */
+
+namespace mod_bigbluebuttonbn\output;
+
+use mod_bigbluebuttonbn\local\bbb_constants;
+use moodle_url;
+use renderable;
+use renderer_base;
+use stdClass;
+use templatable;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Class opencast_recordings_session
+ *
+ * @copyright 2010 onwards, Blindside Networks Inc
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @author    Farbod Zamani  (zamani [at] elan-ev [dt] de)
+ */
+class opencast_recordings_session implements renderable, templatable {
+
+    /**
+     * @var $bbbsession
+     */
+    protected $bbbsession;
+    /**
+     * @var $type
+     */
+    protected $type;
+    /**
+     * @var mixed|null $enabledfeatures
+     */
+    protected $enabledfeatures;
+
+    /**
+     * recording_section constructor.
+     *
+     * @param array $bbbsession
+     * @param string $type
+     * @param array $enabledfeatures
+     */
+    public function __construct($bbbsession, $type, $enabledfeatures = null) {
+
+        $this->bbbsession = $bbbsession;
+        $this->type = $type;
+        $this->enabledfeatures = $enabledfeatures;
+    }
+
+    /**
+     * Export for template
+     *
+     * @param renderer_base $output
+     * @return array|stdClass|void
+     * @throws \coding_exception
+     * @throws \moodle_exception
+     */
+    public function export_for_template(renderer_base $output) {
+
+        $bbbid = $this->bbbsession['bigbluebuttonbn']->id;
+        $hasrecordings = $this->bbbsession['record'];
+        $hasrecordings = $hasrecordings &&
+            (in_array($this->type, [bbb_constants::BIGBLUEBUTTONBN_TYPE_ALL,
+                bbb_constants::BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY]));
+        
+        $context = (object)
+        [
+            'has_recordings' => $hasrecordings,
+            'bbbid' => intval($bbbid)
+        ];
+        return $context;
+    }
+}
\ No newline at end of file
diff --git a/db/services.php b/db/services.php
index 570477b16..f010dcbee 100644
--- a/db/services.php
+++ b/db/services.php
@@ -92,4 +92,12 @@
         'ajax'          => true,
         'capabilities'  => 'mod/bigbluebuttonbn:view',
     ),
+    'mod_bigbluebutton_opencast_recording_list_table' => array(
+        'classname'     => 'mod_bigbluebuttonbn\external\get_opencast_recordings',
+        'methodname'    => 'execute',
+        'description'   => 'Returns a list of Opencast recordings ready to be processed by a datatable.',
+        'type'          => 'read',
+        'ajax'          => true,
+        'capabilities'  => 'mod/bigbluebuttonbn:view',
+    ),
 );
diff --git a/lang/en/bigbluebuttonbn.php b/lang/en/bigbluebuttonbn.php
index 9ac1ad75a..f51e9b3f4 100644
--- a/lang/en/bigbluebuttonbn.php
+++ b/lang/en/bigbluebuttonbn.php
@@ -110,9 +110,21 @@
 $string['config_shared_secret'] = 'BigBlueButton Shared Secret';
 $string['config_shared_secret_description'] = 'The security salt of your BigBlueButton server.  (This default salt is for a BigBlueButton server provided by Blindside Networks that you can use for testing.)';
 
+$string['config_opencast'] = 'Configuration for "Opencast integration" feature';
+$string['config_opencast_description'] = 'These settings control the integration of BBB meeting recordings and Opencast';
+$string['config_opencast_recording'] = 'Send Opencast series ID to BBB';
+$string['config_opencast_recording_description'] = 'If this setting is enabled, Moodle will send the Opencast series ID of the course to BBB alongside the BBB metadata whenever a new BBB meeting is initiated. If there is not an Opencast series ID for the course yet, a new series will be created on-the-fly. This way, Opencast can be used to process BBB recordings and to publish them in the course\'s series.';
+$string['config_opencast_show_recording'] = 'Show Opencast recordings';
+$string['config_opencast_show_recording_description'] = 'If enabled the recording table will also include the Opencast recordings.';
 $string['config_recording'] = 'Configuration for "Record meeting" feature';
 $string['config_recording_description'] = 'These settings are feature specific';
 $string['config_recording_default'] = 'Recording feature enabled by default';
+$string['config_opencast'] = 'Configuration for "Opencast integration" feature';
+$string['config_opencast_description'] = 'These settings control the integration of BBB meeting recordings and Opencast';
+$string['config_oc_recording'] = 'Send Opencast series ID to BBB';
+$string['config_oc_recording_description'] = 'If this setting is enabled, Moodle will send the Opencast series ID of the course to BBB alongside the BBB metadata whenever a new BBB meeting is initiated. If there is not an Opencast series ID for the course yet, a new series will be created on-the-fly. This way, Opencast can be used to process BBB recordings and to publish them in the course\'s series.';
+$string['config_oc_show_recording'] = 'Show Opencast recordings';
+$string['config_oc_show_recording_description'] = 'If enabled the recording table will also include the Opencast recordings.';
 $string['config_recording_default_description'] = 'If enabled the sessions created in BigBlueButton will have recording capabilities.';
 $string['config_recording_editable'] = 'Recording feature can be edited';
 $string['config_recording_editable_description'] = 'If checked the interface includes an option for enable and disable the recording feature.';
@@ -365,7 +377,6 @@
 $string['mod_form_field_lockonjoinconfigurable'] = 'Allow ignore locking settings';
 $string['mod_form_locksettings'] = 'Lock settings';
 
-
 $string['starts_at'] = 'Starts';
 $string['started_at'] = 'Started';
 $string['ends_at'] = 'Ends';
@@ -381,6 +392,7 @@
 $string['view_error_max_concurrent'] = 'Number of concurrent meetings allowed has been reached.';
 $string['view_error_userlimit_reached'] = 'The number of users allowed in a meeting has been reached.';
 $string['view_error_url_missing_parameters'] = 'There are parameters missing in this URL';
+$string['view_error_missing_filter_opencast_config'] = 'Unable to get valid Opencast configuration in order to display the recording.';
 $string['view_error_import_no_courses'] = 'No courses to look up for recordings';
 $string['view_error_import_no_recordings'] = 'No recordings in this course for importing';
 $string['view_error_invalid_session'] = 'The session is expired. Go back to the activity main page.';
@@ -415,6 +427,7 @@
 $string['view_recording_list_description'] = 'Description';
 $string['view_recording_list_duration'] = 'Duration';
 $string['view_recording_list_recording'] = 'Recording';
+$string['view_recording_list_opencast'] = 'Opencast Video';
 $string['view_recording_button_import'] = 'Import recording links';
 $string['view_recording_button_return'] = 'Go back';
 $string['view_recording_format_notes'] = 'Notes';
@@ -424,9 +437,12 @@
 $string['view_recording_format_statistics'] = 'Statistics';
 $string['view_recording_format_video'] = 'Video';
 $string['view_recording_format_errror_unreachable'] = 'The URL for this recording format is unreachable.';
+$string['view_recording_format_error_opencast_unreachable'] = 'The Opencast recording cannot be dispalyed.';
 $string['view_section_title_presentation'] = 'Presentation file';
 $string['view_section_title_recordings'] = 'Recordings';
+$string['view_section_title_opencast_recordings'] = 'Opencast Recordings';
 $string['view_message_norecordings'] = 'There are no recording to show.';
+$string['view_message_opencast_norecordings'] = 'There are no Opencast recording to show.';
 $string['view_message_finished'] = 'This activity is over.';
 $string['view_message_notavailableyet'] = 'This session is not yet available.';
 $string['view_recording_select_course'] = 'Select a course first in the drop down menu';
diff --git a/oc_player.php b/oc_player.php
new file mode 100644
index 000000000..e8df6e17d
--- /dev/null
+++ b/oc_player.php
@@ -0,0 +1,88 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * View for Opencast recordings.
+ *
+ * @package   mod_bigbluebuttonbn
+ * @copyright 2010 onwards, Blindside Networks Inc
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @author    2021 Farbod Zamani Boroujeni - ELAN e.V.
+ */
+
+use mod_bigbluebuttonbn\local\helpers\opencast;
+use mod_bigbluebuttonbn\local\view;
+use mod_bigbluebuttonbn\plugin;
+use context_module;
+use moodle_url;
+
+require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
+require_once(dirname(__FILE__).'/locallib.php');
+
+global $PAGE, $OUTPUT, $CFG;
+
+require_once($CFG->dirroot . '/mod/lti/locallib.php');
+require_once($CFG->dirroot . '/lib/oauthlib.php');
+
+$identifier = required_param('identifier', PARAM_TEXT);
+$bn = optional_param('bn', 0, PARAM_INT);
+
+$bbbviewinstance = view::bigbluebuttonbn_view_validator(null, $bn);
+if (!$bbbviewinstance) {
+    print_error(get_string('view_error_url_missing_parameters', 'bigbluebuttonbn'));
+}
+
+// Get configs from filter_opencast
+$opencastfilterconfig = opencast::bigbluebuttonbn_check_opencast_filter();
+if (!$opencastfilterconfig) {
+    print_error(get_string('view_error_missing_filter_opencast_config', 'bigbluebuttonbn'));
+}
+
+$cm = $bbbviewinstance['cm'];
+$course = $bbbviewinstance['course'];
+$bigbluebuttonbn = $bbbviewinstance['bigbluebuttonbn'];
+$context = context_module::instance($cm->id);
+
+require_login($course, true, $cm);
+
+// Capability check.
+require_capability('mod/bigbluebuttonbn:view', $context);
+
+$baseurl = new moodle_url('/mod/bigbluebuttonbn/oc_player.php', array('identifier' => $identifier, 'bn' => $bn));
+$PAGE->set_url($baseurl);
+$PAGE->set_context($context);
+$PAGE->set_pagelayout('incourse');
+$PAGE->set_title(format_string($bigbluebuttonbn->name));
+$PAGE->set_heading($course->fullname);
+
+// Add $identifier to the end of playerurl.
+$opencastfilterconfig['playerurl'] .= $identifier;
+
+// Create LTI parameters.
+$params = opencast::bigbluebuttonbn_create_lti_parameters_opencast($opencastfilterconfig);
+
+// Using block_opencast renderer in order to use render_lti_form function.
+$opencastrenderer = $PAGE->get_renderer('block_opencast');
+
+echo $OUTPUT->header();
+echo $OUTPUT->heading(format_string($bigbluebuttonbn->name));
+
+// Render the LTI form from block_opencast renderer function.
+echo $opencastrenderer->render_lti_form($opencastfilterconfig['ltiendpoint'], $params);
+
+// Use block_opencast LTI form handler javascript to submit the lti form.
+$PAGE->requires->js_call_amd('block_opencast/block_lti_form_handler', 'init');
+echo $OUTPUT->footer();
diff --git a/settings.php b/settings.php
index 3b7a9c701..87c023074 100644
--- a/settings.php
+++ b/settings.php
@@ -42,6 +42,8 @@
 $bbbsettings->bigbluebuttonbn_settings_importrecordings();
 // Renders settings for showing recordings.
 $bbbsettings->bigbluebuttonbn_settings_showrecordings();
+// Renders settings for Opencast integration.
+$bbbsettings->bigbluebuttonbn_settings_opencast_integration();
 
 // Renders settings for meetings.
 $bbbsettings->bigbluebuttonbn_settings_waitmoderator();
diff --git a/templates/opencast_recordings_session.mustache b/templates/opencast_recordings_session.mustache
new file mode 100644
index 000000000..b1c192399
--- /dev/null
+++ b/templates/opencast_recordings_session.mustache
@@ -0,0 +1,33 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template mod_bigbluebuttonbn/opencast_recordings_session
+
+    This template renders the mobile page.
+
+    Example context (json):
+    {
+        'bbbid' : 3
+        'has_records': true,
+    }
+}}
+
+<div class="mod_bigbluebuttonbn_opencast_recordings_section mt-3">
+    {{< mod_bigbluebuttonbn/opencast_recordings_table}}
+        {{$title}}{{#str}}view_section_title_opencast_recordings, mod_bigbluebuttonbn{{/str}}{{/title}}
+    {{/mod_bigbluebuttonbn/opencast_recordings_table}}
+</div>
diff --git a/templates/opencast_recordings_table.mustache b/templates/opencast_recordings_table.mustache
new file mode 100644
index 000000000..2c865253a
--- /dev/null
+++ b/templates/opencast_recordings_table.mustache
@@ -0,0 +1,50 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template mod_bigbluebuttonbn/opencast_recordings_table
+
+    This template renders the mobile page.
+
+    Example context (json):
+    {
+        'bbbid' : 3
+        'has_records': true,
+        'search_input' : {... search input data ...}
+    }
+}}
+<div class="mod_bigbluebuttonbn_recordings_table">
+    {{#has_recordings}}
+        <div>
+            <h4>{{$title}}{{/title}}</h4>
+        </div>
+        <div>
+            <div id="bigbluebuttonbn-opencast-recording-table-{{uniqid}}"
+                 data-bbbid="{{bbbid}}" data-tools="{{$tools}}edit,delete{{/tools}}"
+                 {{$otherattributes}}{{/otherattributes}}
+            ></div>
+        </div>
+        {{#js}}
+            require(['mod_bigbluebuttonbn/opencastrecordings'], function(opencastrecordings) {
+                opencastrecordings.init('#bigbluebuttonbn-opencast-recording-table-{{uniqid}}');
+            });
+            require(['core/inplace_editable']);
+        {{/js}}
+    {{/has_recordings}}
+    {{^has_recordings}}
+        <div id="bigbluebuttonbn_recordings_table">{{#str}}view_message_opencast_norecordings, mod_bigbluebuttonbn{{/str}}</div>
+    {{/has_recordings}}
+</div>
diff --git a/version.php b/version.php
index 5ac4d5462..2ec6c0fe1 100644
--- a/version.php
+++ b/version.php
@@ -26,7 +26,7 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version = 2020101001;
+$plugin->version = 2021052101;
 $plugin->requires = 2020061500;
 $plugin->cron = 0;
 $plugin->component = 'mod_bigbluebuttonbn';