1

I'm trying to create a thumbnail for the video using plyr - https://github.com/sampotts/plyr

I can get the blob as in the below codepen: https://codepen.io/suryaiiit/pen/LeZwgr

But when I try the same in the VF, it is giving error.

VisualForce Page

<apex:stylesheet value="{!URLFOR($Resource.slds, 'assets/styles/salesforce-lightning-design-system.css')}"/>
<apex:stylesheet value="{!URLFOR($Resource.Plyr, 'plyr.css')}"/>

<div class="container">
    <video id="video" controls="" crossorigin="">
        <!-- Video files -->
        <source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4" type="video/mp4" />
        <source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.webm" type="video/webm" />

        <!-- Fallback for browsers that don't support the <video> element -->
        <a href="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4" download="">Download</a>
    </video>

    <div id="preview"></div>

    <div class="actions">
        <button type="button" class="btn" onclick="getThumb()">getThumb</button>
    </div>
</div>

<script>
window.Player = {
    instance: null,
    Testing: false,
    Options: { }
};

setTimeout(function() {
    var instances = plyr.setup({
        // Output to console
        //debug: true
    });
}, 2000);

function getThumb() {
    console.log('getThumb')
    var video = document.getElementById('video');

    var w = video.videoWidth;//video.videoWidth * scaleFactor;
    var h = video.videoHeight;//video.videoHeight * scaleFactor;
    var canvas = document.createElement('canvas');
    canvas.width = w;
    canvas.height = h;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(video, 0, 0, w, h);

    document.getElementById("preview").appendChild(canvas);

    var data = canvas.toDataURL("image/jpg");

    console.log('canvas data: ', data); 
}

</script>

<apex:includeScript value="{!URLFOR($Resource.Plyr, 'plyr.js')}" loadOnReady="true"/>

I get the below error:

thum:50 Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. at getThumb

2 Answers 2

1

I took your code and used 'plyr' CDN instead of static resource and it worked for me. Below is my working code which did not show the error

thum:50 Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. at getThumb

<apex:page >
    <apex:stylesheet value="{!URLFOR($Resource.SLDS0122, 'assets/styles/salesforce-lightning-design-system.css')}"/>
    <apex:stylesheet value="https://cdnjs.cloudflare.com/ajax/libs/plyr/3.0.3/plyr.css"/>

    <div class="container">
        <video id="video" 
               poster="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg" 
               controls="controls" 
               crossorigin="crossorigin" 
               playsinline="playsinline">
            <!-- Video files -->
            <source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4" type="video/mp4" />
            <source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.webm" type="video/webm" />

            <!-- Text track file -->
            <track kind="captions" 
                   label="English" 
                   default="default"
                   srclang="en" 
                   src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt" />

            <!-- Fallback for browsers that don't support the <video> element -->
            <a href="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4" download="download">Download</a>
        </video>
        <div id="preview"></div>
        <div class="actions">

            <button type="button" class="btn" onclick="getThumb()">getThumb</button>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/plyr/3.0.3/plyr.js" />

    <script>
        window.Player = {
            instance: null,
            Testing: false,
            Options: { }
        };

        setTimeout(function() {
            var instances = plyr.setup({
                // Output to console
                //debug: true
            });
        }, 2000);

        function getThumb() {
            console.log('getThumb')
            var video = document.getElementById('video');

            var w = video.videoWidth;//video.videoWidth * scaleFactor;
            var h = video.videoHeight;//video.videoHeight * scaleFactor;
            var canvas = document.createElement('canvas');
            canvas.width = w;
            canvas.height = h;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(video, 0, 0, w, h);

            document.getElementById("preview").appendChild(canvas);

            var data = canvas.toDataURL("image/jpg");

            console.log('canvas data: ', data); 
        }
    </script>

</apex:page>

Check and let me know if it works.

-1

Seems like CORS related issue - if you know before hand what the image is you can convert it to a data url in advance.

You can use the image (or video) without the crossorigin attribute set first and test if you can get a HEAD request thru to the same resource via AJAX. If that fails, you cannot use the resource. if it succeeds you can add the attribute and re-set the source of the image/video with a timestamp attached which reloads it.

This workaround allows you to show your resource to the user and simply hide some functions if CORS is not supported.

HTML

<img id="testImage" src="path/to/image.png?_t=1234">

JS

var target = $("#testImage")[0];
    currentSrcUrl = target.src.split("_t=").join("_t=1"); // add a leading 1 to the ts
$.ajax({
    url: currentSrcUrl,
    type:'HEAD',
    withCredentials: true
})
.done(function() {
    // things worked out, we can add the CORS attribute and reset the source
    target.crossOrigin = "anonymous";
    target.src = currentSrcUrl;
    console.warn("Download enabled - CORS Headers present or not required");
    /* show make-image-out-of-canvas-functions here */
})
.fail(function() {
    console.warn("Download disabled - CORS Headers missing");
    /* ... or hide make-image-out-of-canvas-functions here */
});

Check out here https://stackoverflow.com/questions/13674835/canvas-tainted-by-cross-origin-data

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .