Skip to main content
OCLC Support

Embed external video stream

If you have records in CONTENTdm that are URL references to an outside streaming service, you can use JavaScript to read the stream URL and embed the video or audio player directly in the CONTENTdm item page. This example will work for YouTube, Vimeo, and Kaltura embed links. This example can be modified to work with any external service that provides a method for embedding some kind of viewer or player.

This implementation assumes that you have stored the streaming URL from the third-party service as a “URL Item” in CONTENTdm. The code looks for the URL item link and replaces it with an iframe or div containing the embedded viewer.

(function () {

    var currentInstance = null;


    function VimeoAPI(url) {
        return new Promise(function (resolve) {
            if (!url) {
                return resolve(false);
            }
            // create iframe for youtube
            var html = '<iframe src="' + url + '" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
            resolve(html);
        });
    }    

    function YoutubeAPI(url) {
        return new Promise(function (resolve) {
            if (!url) {
                return resolve(false);
            }
            url = url.replace('watch?v=', 'embed/');
            // create iframe for youtube
            var html = '<iframe type="text/html" width="640" height="320" src="' + url + '" frameborder="0" allowfullscreen=""></iframe>';
            resolve(html);
        });
    }    

    function KalturaAPI(url) {
        return new Promise(function (resolve) {
            if (!url) {
                return resolve(false);
            }
            // create iframe for kaltura
            var html = '<div class="videoWrapper"><iframe src="' + url + '" width="560" height="395" allowfullscreen webkitallowfullscreen mozAllowFullScreen frameborder="0"></iframe></div>';
            resolve(html);
        });
    }


    function YoutuAPI(url) {
        if (!url) {
            return resolve(false);
        }
        url = url.replace('youtu.be/', 'youtube.com/watch?v=');
        return YoutubeAPI(url);
    }

    var APIS = {
        'player.vimeo.com': VimeoAPI,
        'youtu.be': YoutuAPI,
        'www.youtube.com': YoutubeAPI,
        'cdnapisec.kaltura.com': KalturaAPI
    };

    function loadFrame(link) {
        return Promise.resolve(link)
            .then(function (link) {
                var url = new URL(link);
                // find proper api from api list
                const loader = APIS[url.hostname];
                return loader && loader(link);
            })
            .catch(console.warn);
    }

    function CustomVideoView(container) {
        if (!container) {
            return false;
        }
        const anchor = container.querySelector('a');
        if (!anchor || !/player.vimeo.com|youtube.com|youtu.be|cdnapisec.kaltura.com/i.test(anchor.href)) {
            return false;
        }

        var links = [anchor.href];
        // parse metadata
        var rows = document.querySelectorAll('tr[class*=metadatarow]');
        Array.from(rows).forEach(row => {
            // find a description field
            if (row.firstChild.textContent === 'Description') {
                links = links.concat(row.lastChild.textContent.split(','));
            }
        });

        // create container for iFrames
        var frameContainer = document.createElement('div');

        var mount = function () {
            var reqs = links.map(function (link) {
                return loadFrame(link);
            });

            Promise.all(reqs)
                .then(function (reps) {
                    // hide original viewer
                    container.className += ' hide';
                    // add each frames to one root
                    reps.forEach(function (embeddedHTML) {
                        embeddedHTML && (frameContainer.innerHTML += embeddedHTML);
                    });
                    // insert it
                    container.parentNode.insertBefore(frameContainer, container);
                });

        };

        var unmount = function () {
            frameContainer.parentNode && frameContainer.parentNode.removeChild(frameContainer);
        };

        mount();

        return {
            unmount: unmount
        };

    }

    document.addEventListener('cdm-item-page:ready', function () {
        // unmount or remove current video player from DOM if it is exists
        currentInstance && currentInstance.unmount();
        // creates a new instance if it is url item and it is from vimeo.com
        currentInstance = CustomVideoView(document.querySelector('div[class*=itemUrl]'));
    });

    document.addEventListener('cdm-item-page:update', function () {
        currentInstance && currentInstance.unmount();
        // updates an instance if it is url item and it is from vimeo.com
        currentInstance = CustomVideoView(document.querySelector('div[class*=itemUrl]'));
    });

    document.addEventListener('cdm-item-page:leave', function () {
        // unmount or remove current video player from DOM if it is exists
        currentInstance && currentInstance.unmount();
    });

})();
  • Was this article helpful?