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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.