Zoeken…


Opmerkingen

Dit onderwerp behandelt de verschillende mediatypen en hoe deze kunnen worden gebruikt met het canvas in 2D-interface.

Mediatypen hebben generieke en formaatspecifieke categorieën

Mediatypen

  • animaties
  • Videos
  • Afbeeldingen
  • HD-beelden
  • Vector afbeelding
  • Geanimeerde afbeeldingen

Media formaten

  • Jpg / Jpeg
  • png
  • gif
  • SVG
  • M-JPEG
  • Webm
  • WebP

Afbeeldingen

Er zijn veel verschillende afbeeldingsindelingen die door browsers worden ondersteund, hoewel geen enkele browser ze allemaal ondersteunt. Als u bepaalde afbeeldingsindelingen hebt, wilt u Wiki Browsers gebruiken en ondersteunde afbeeldingsindelingen bieden een goed overzicht.

De beste ondersteuning is voor de 3 hoofdformaten, "jpeg", "png" en "gif", waarbij alle belangrijke browsers ondersteuning bieden.

JPEG

JPEG-afbeeldingen zijn het meest geschikt voor foto's en foto-achtige afbeeldingen. Ze lenen zichzelf niet goed voor grafieken, diagrammen en tekst. JPEG-afbeeldingen ondersteunen geen transparantie.

Canvas kan JPEG-afbeeldingen uitvoeren via canvas.toDataURL en canvas.toBlob en biedt een kwaliteitsinstelling. Omdat JPEG geen transparantie ondersteunt, worden transparante pixels gemengd met zwart voor de uiteindelijke output JPG. De resulterende afbeelding is geen perfecte kopie van het canvas.

JPEG op wikipedia

PNG

PNG-afbeeldingen zijn afbeeldingen van de hoogste kwaliteit en kunnen ook een alfakanaal voor transparante pixels bevatten. De afbeeldingsgegevens zijn gecomprimeerd maar produceren geen artefacten zoals JPG-afbeeldingen.

Vanwege de verliesloze compressie en de ondersteuning van het alfakanaal worden PNG's gebruikt voor games, ui-componentafbeeldingen, grafieken, diagrammen, tekst. Wanneer ze worden gebruikt voor foto's en fotoachtige afbeeldingen, kan hun bestandsgrootte veel groter zijn dan JPEG's. .

Het PNG-formaat biedt ook animatie-ondersteuning, hoewel browserondersteuning beperkt is en toegang tot de animatie voor gebruik op het canvas alleen kan worden gedaan via Javascript-API's en bibliotheken

Het canvas kan worden gebruikt om PNG-afbeeldingen te coderen via canvas.toDataURL en canvas.toBlob hoewel het uitvoerformaat beperkt is tot gecomprimeerde 32Bit RGBA. De PNG levert een pixel perfecte kopie van het canvas.

PNG op wikipedia

GIF

GIF's worden gebruikt voor korte animaties, maar kunnen ook worden gebruikt om grafieken, diagrammen en tekstachtige afbeeldingen van hoge kwaliteit te bieden. GIF's hebben een zeer beperkte kleurondersteuning met maximaal 256 kleuren per frame. Met Cleaver-beeldverwerking kunnen gif-afbeeldingen verrassend goede resultaten opleveren, vooral wanneer geanimeerd. GIF's bieden ook transparantie, hoewel dit beperkt is tot aan of uit

AS met PNG zijn GIF-animaties niet direct toegankelijk voor gebruik op het canvas en u hebt een Javascript-API of bibliotheek nodig om toegang te krijgen. GIF kan niet worden opgeslagen via het canvas en vereist hiervoor een API of bibliotheek.

GIF op wikipedia

Een afbeelding laden en weergeven

Om een afbeelding te laden en op het canvas te plaatsen

var image = new Image();  // see note on creating an image
image.src = "imageURL";
image.onload = function(){
    ctx.drawImage(this,0,0);
}

Een afbeelding maken

Er zijn verschillende manieren om een afbeelding te maken

  • new Image()
  • document.createElement("img")
  • <img src = 'imageUrl' id='myImage'> Als onderdeel van de HTML-inhoud en opgehaald met document.getElementById('myImage')

De afbeelding is een HTMLImageElement

Image.src eigenschap

Het beeld src kan elke geldige URL van de afbeelding of gecodeerde dataurl zijn. Raadpleeg de opmerkingen van dit onderwerp voor meer informatie over afbeeldingsindelingen en ondersteuning.

  • image.src = "http://my.domain.com/images/myImage.jpg"
  • image.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=" *

* De dataURL is een 1 bij 1 pixel gif-afbeelding met zwart

Opmerkingen bij het laden en fouten

De afbeelding wordt geladen wanneer de eigenschap src is ingesteld. Het laden is synchroon, maar de gebeurtenis onload wordt niet aangeroepen totdat de functie of code is verlaten / geretourneerd.

Als u een afbeelding van de pagina krijgt (bijvoorbeeld document.getElementById("myImage") ) en de src is ingesteld, is deze mogelijk al dan niet geladen. U kunt de status van de afbeelding controleren met HTMLImageElement.complete wat true als deze compleet is. Dit betekent niet dat de afbeelding is geladen, maar dat het ook is gebeurd

  • loaded
  • er is een fout opgetreden
  • src eigenschap is niet ingesteld en is gelijk aan de lege String ""

Als de afbeelding afkomstig is van een onbetrouwbare bron en om verschillende redenen niet toegankelijk is, genereert deze een foutgebeurtenis. Wanneer dit gebeurt, is de afbeelding kapot. Als u vervolgens probeert het op het canvas te tekenen, geeft dit de volgende foutmelding

Uncaught DOMException: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The HTMLImageElement provided is in the 'broken' state.

Door de gebeurtenis image.onerror = myImgErrorHandler geven, kunt u passende maatregelen nemen om fouten te voorkomen.

Een svg-afbeelding tekenen

Om een vector SVG-afbeelding te tekenen, verschilt de bewerking niet van een rasterafbeelding:
U moet eerst uw SVG-afbeelding in een HTMLImage-element laden en vervolgens de methode drawImage() gebruiken.

var image = new Image();
image.onload = function(){
    ctx.drawImage(this, 0,0);
}
image.src = "someFile.SVG";

SVG-afbeeldingen hebben een aantal voordelen ten opzichte van rasterfoto's, omdat u geen kwaliteit verliest, ongeacht de schaal die u op uw canvas tekent. Maar let op, het kan ook een beetje langzamer zijn dan het tekenen van een rasterafbeelding.

SVG-afbeeldingen hebben echter meer beperkingen dan rasterafbeeldingen.

  • Om veiligheidsredenen kan geen externe inhoud worden geladen vanuit een SVG-afbeelding waarnaar wordt verwezen in een HTMLImageElement ( <img> )
    Geen externe stylesheet, geen externe afbeelding waarnaar wordt verwezen in SVGImage ( <image/> ) elementen, geen extern filter of element gekoppeld door het xlink:href attribuut ( <use xlink:href="anImage.SVG#anElement"/> ) of de funcIRI ( url() ) kenmerkmethode enz.
    Stijlbladen die in het hoofddocument zijn toegevoegd, hebben ook geen effect op het SVG-document als er in een HTMLImage-element naar wordt verwezen.
    Ten slotte wordt er geen script uitgevoerd in de SVG-afbeelding.
    Tijdelijke oplossing: u moet alle externe elementen in de SVG zelf toevoegen voordat u naar het HTMLImage-element verwijst. (voor afbeeldingen of lettertypen moet u een dataURI-versie van uw externe bronnen toevoegen).

  • Voor het root-element ( <svg> ) moeten de breedte- en hoogtekenmerken op een absolute waarde zijn ingesteld.
    Als u relatieve lengte (bijv. % ) Zou gebruiken, zal de browser niet weten wat relatief is. Sommige browsers (Blink) zullen proberen een gok te doen, maar de meeste zullen gewoon uw afbeelding negeren en zullen niets tekenen zonder een waarschuwing.

  • Sommige browsers kleuren het canvas wanneer er een SVG-afbeelding op is getekend.
    In het bijzonder, Internet-Explorer <Edge in ieder geval, en Safari 9 wanneer een <foreignObject> aanwezig is in de SVG-afbeelding.

Eenvoudig laden en afspelen van een video op het canvas.

Het canvas kan worden gebruikt om video van verschillende bronnen weer te geven. Dit voorbeeld laat zien hoe u een video als bestandsresource laadt, deze weergeeft en een eenvoudige klik op het scherm toevoegt / pauzeert.

Deze zelf-beantwoorde stackoverflow-vraag Hoe geef ik een video weer met behulp van de HTML5 canvas-tag toont de volgende voorbeeldcode in actie.

Gewoon een afbeelding

Een video is slechts een afbeelding voor zover het canvas betreft. Je kunt het tekenen zoals elke afbeelding. Het verschil is dat de video kan worden afgespeeld en geluid heeft.

Download canvas en basisinstellingen

// It is assumed you know how to add a canvas and correctly size it.
var canvas = document.getElementById("myCanvas"); // get the canvas from the page
var ctx = canvas.getContext("2d");
var videoContainer; // object to hold video and associated info

De video maken en laden

var video = document.createElement("video"); // create a video element
video.src = "urlOffVideo.webm"; 
// the video will now begin to load.
// As some additional info is needed we will place the video in a
// containing object for convenience
video.autoPlay = false; // ensure that the video does not auto play
video.loop = true; // set the video to loop.
videoContainer = {  // we will add properties as needed
     video : video,
     ready : false,   
};

In tegenstelling tot afbeeldingselementen hoeven video's niet volledig te worden geladen om op het canvas te worden weergegeven. Video's bieden ook tal van extra gebeurtenissen die kunnen worden gebruikt om de status van de video te controleren.

In dit geval willen we weten wanneer de video klaar is om af te spelen. oncanplay betekent dat er genoeg van de video is geladen om een deel ervan af te spelen, maar er is misschien niet genoeg om tot het einde af te spelen.

video.oncanplay = readyToPlayVideo; // set the event to the play function that 
                                  // can be found below

Als alternatief kun je oncanplaythrough die wordt oncanplaythrough wanneer voldoende video is geladen zodat deze tot het einde kan worden afgespeeld.

video.oncanplaythrough = readyToPlayVideo; // set the event to the play function that
                                         // can be found below

Gebruik alleen een van de canPlay-evenementen, niet beide.

Het can play-evenement (gelijk aan het laden van de afbeelding)

function readyToPlayVideo(event){ // this is a referance to the video
    // the video may not match the canvas size so find a scale to fit
    videoContainer.scale = Math.min(
                         canvas.width / this.videoWidth, 
                         canvas.height / this.videoHeight); 
    videoContainer.ready = true;
    // the video can be played so hand it off to the display function
    requestAnimationFrame(undateCanvas);
}

Tonen

De video speelt zichzelf niet op het canvas. Je moet het voor elk nieuw frame tekenen. Omdat het moeilijk is om de exacte framesnelheid te weten en wanneer deze zich voordoen, is het het beste om de video weer te geven alsof deze op 60 fps draait. Als de framesnelheid lager is, geeft u hetzelfde frame twee keer weer. Als de framesnelheid hoger is, kan er niets worden gedaan om de extra frames te zien, dus we negeren ze gewoon.

Het video-element is gewoon een afbeeldingselement en kan worden getekend zoals elke afbeelding, je kunt de video schalen, roteren, pannen, spiegelen, vervagen, knippen en alleen delen weergeven, twee keer de tweede keer tekenen met een globale samengestelde modus om FX toe te voegen zoals lichter, scherm, enz ..

function updateCanvas(){
    ctx.clearRect(0,0,canvas.width,canvas.height); // Though not always needed 
                                                     // you may get bad pixels from 
                                                     // previous videos so clear to be
                                                     // safe
    // only draw if loaded and ready
    if(videoContainer !== undefined && videoContainer.ready){ 
        // find the top left of the video on the canvas
        var scale = videoContainer.scale;
        var vidH = videoContainer.video.videoHeight;
        var vidW = videoContainer.video.videoWidth;
        var top = canvas.height / 2 - (vidH /2 ) * scale;
        var left = canvas.width / 2 - (vidW /2 ) * scale;
        // now just draw the video the correct size
        ctx.drawImage(videoContainer.video, left, top, vidW * scale, vidH * scale);
        if(videoContainer.video.paused){ // if not playing show the paused screen 
            drawPayIcon();
        }
    }
    // all done for display 
    // request the next frame in 1/60th of a second
    requestAnimationFrame(updateCanvas);
}

Basis speelpauze controle

Nu hebben we de video geladen en weergegeven alles wat we nodig hebben is de afspeelbesturing. We zullen het maken als een klik schakelen tussen spelen op het scherm. Wanneer de video wordt afgespeeld en de gebruiker klikt, wordt de video gepauzeerd. In de pauzestand wordt de klik hervat. We zullen een functie toevoegen om de video donkerder te maken en een afspeelpictogram (driehoek) te tekenen

function drawPayIcon(){
     ctx.fillStyle = "black";  // darken display
     ctx.globalAlpha = 0.5;
     ctx.fillRect(0,0,canvas.width,canvas.height);
     ctx.fillStyle = "#DDD"; // colour of play icon
     ctx.globalAlpha = 0.75; // partly transparent
     ctx.beginPath(); // create the path for the icon
     var size = (canvas.height / 2) * 0.5;  // the size of the icon
     ctx.moveTo(canvas.width/2 + size/2, canvas.height / 2); // start at the pointy end
     ctx.lineTo(canvas.width/2 - size/2, canvas.height / 2 + size);
     ctx.lineTo(canvas.width/2 - size/2, canvas.height / 2 - size);
     ctx.closePath();
     ctx.fill();
     ctx.globalAlpha = 1; // restore alpha
}    

Nu is het spel pauzeren gebeurtenis

function playPauseClick(){
     if(videoContainer !== undefined && videoContainer.ready){
          if(videoContainer.video.paused){                                 
                videoContainer.video.play();
          }else{
                videoContainer.video.pause();
          }
     }
}
// register the event
canvas.addEventListener("click",playPauseClick);

Samenvatting

Een video afspelen is heel eenvoudig met behulp van het canvas, realtime effect toevoegen is ook eenvoudig. Er zijn echter enkele beperkingen aan formaten, hoe je kunt spelen en zoeken. MDN HTMLMediaElement is de plek om de volledige verwijzing naar het video-object te krijgen.

Nadat de afbeelding op het canvas is getekend, kunt u ctx.getImageData om toegang te krijgen tot de pixels die het bevat. Of u kunt canvas.toDataURL om een foto te maken en te downloaden. (Alleen als de video van een vertrouwde bron is en het canvas niet aantast).

Opmerking: als de video geluid heeft, wordt het geluid ook afgespeeld.

Veel video-opnames.

Leg canvas vast en sla op als webM-video

Een WebM-video maken van canvasframes en spelen op canvas, of uploaden of downloaden.

Voorbeeld vastleggen en canvas spelen

name = "CanvasCapture"; // Placed into the Mux and Write Application Name fields of the WebM header
quality = 0.7; // good quality 1 Best < 0.7 ok to poor
fps = 30; // I have tried all sorts of frame rates and all seem to work
          // Do some test to workout what your machine can handle as there
          // is a lot of variation between machines.
var video = new Groover.Video(fps,quality,name)
function capture(){
    if(video.timecode < 5000){ // 5 seconds
         setTimeout(capture,video.frameDelay);             
    }else{
         var videoElement = document.createElement("video");
         videoElement.src = URL.createObjectURL(video.toBlob());
         document.body.appendChild(videoElement);
         video = undefined; // DeReference as it is memory hungry.
         return;
    }
    // first frame sets the video size
    video.addFrame(canvas); // Add current canvas frame
}
capture(); // start capture

In plaats van een enorme inspanning te leveren om alleen te worden afgewezen, is dit een snelle invoeging om te zien of acceptabel. Zal volledige details geven indien geaccepteerd. Ook bevatten extra opname-opties voor betere HD-opnamesnelheden (verwijderd uit deze versie, kan HD 1080 vastleggen met 50 fps op goede machines.)

Dit is geïnspireerd door Wammy, maar is een complete herschrijving met codering terwijl je werkt, waardoor het geheugen dat nodig is tijdens het vastleggen aanzienlijk wordt verminderd. Kan meer dan 30 seconden betere gegevens vastleggen en algoritmen verwerken.

Note frames worden gecodeerd in WebP beelden. Alleen Chrome ondersteunt webP canvas-codering. Voor andere browsers (Firefox en Edge) moet u een externe webP-encoder gebruiken, zoals Libwebp. Javascript Codering van WebP-afbeeldingen via Javascript is langzaam. (inclusief toevoeging van onbewerkte webpaginaafbeeldingen indien geaccepteerd).

De webM-encoder geïnspireerd door Whammy: A Real Time Javascript WebM

var Groover = (function(){
    // ensure webp is supported 
    function canEncode(){
        var canvas = document.createElement("canvas");
        canvas.width = 8;
        canvas.height = 8;
        return canvas.toDataURL("image/webp",0.1).indexOf("image/webp") > -1;
    }
    if(!canEncode()){
        return undefined;
    }    
    var webmData = null;
    var clusterTimecode = 0;
    var clusterCounter = 0;
    var CLUSTER_MAX_DURATION = 30000;
    var frameNumber = 0;
    var width;
    var height;
    var frameDelay;
    var quality;
    var name;
    const videoMimeType = "video/webm"; // the only one.
    const frameMimeType = 'image/webp'; // can be no other
    const S = String.fromCharCode;
    const dataTypes = {
        object : function(data){ return toBlob(data);},
        number : function(data){ return stream.num(data);},
        string : function(data){ return stream.str(data);},
        array  : function(data){ return data;}, 
        double2Str : function(num){
            var c = new Uint8Array((new Float64Array([num])).buffer);
            return S(c[7]) + S(c[6]) + S(c[5]) + S(c[4]) + S(c[3]) + S(c[2]) + S(c[1]) + S(c[0]);
        }
    };    
   
    const stream = {
        num : function(num){ // writes int
            var parts = [];
            while(num > 0){ parts.push(num & 0xff); num = num >> 8; }
            return new Uint8Array(parts.reverse());
        },
        str : function(str){ // writes string
            var i, len, arr;
            len = str.length;
            arr = new Uint8Array(len);
            for(i = 0; i < len; i++){arr[i] = str.charCodeAt(i);}
            return arr;
        },
        compInt : function(num){ // could not find full details so bit of a guess
            if(num < 128){       // number is prefixed with a bit (1000 is on byte 0100 two, 0010 three and so on)
                num += 0x80;
                return new Uint8Array([num]);
            }else
            if(num < 0x4000){
                num += 0x4000;
                return new Uint8Array([num>>8, num])
            }else
            if(num < 0x200000){
                num += 0x200000;
                return new Uint8Array([num>>16, num>>8, num])
            }else
            if(num < 0x10000000){
                num += 0x10000000;
                return new Uint8Array([num>>24, num>>16, num>>8, num])
            }            
        }
    }
    const ids = { // header names and values
        videoData          : 0x1a45dfa3, 
        Version            : 0x4286,
        ReadVersion        : 0x42f7,
        MaxIDLength        : 0x42f2,
        MaxSizeLength      : 0x42f3,
        DocType            : 0x4282,
        DocTypeVersion     : 0x4287,
        DocTypeReadVersion : 0x4285,
        Segment            : 0x18538067,
        Info               : 0x1549a966,
        TimecodeScale      : 0x2ad7b1,
        MuxingApp          : 0x4d80,
        WritingApp         : 0x5741,
        Duration           : 0x4489,
        Tracks             : 0x1654ae6b,
        TrackEntry         : 0xae,
        TrackNumber        : 0xd7,
        TrackUID           : 0x63c5,
        FlagLacing         : 0x9c,
        Language           : 0x22b59c,
        CodecID            : 0x86,
        CodecName          : 0x258688,
        TrackType          : 0x83,
        Video              : 0xe0,
        PixelWidth         : 0xb0,
        PixelHeight        : 0xba,
        Cluster            : 0x1f43b675,
        Timecode           : 0xe7,
        Frame              : 0xa3,
        Keyframe           : 0x9d012a,
        FrameBlock         : 0x81,
    };
    const keyframeD64Header = '\x9d\x01\x2a'; //VP8 keyframe header 0x9d012a
    const videoDataPos = 1; // data pos of frame data header
    const defaultDelay = dataTypes.double2Str(1000/25);
    const header = [  // structure of webM header/chunks what ever they are called.
        ids.videoData,[
            ids.Version, 1,
            ids.ReadVersion, 1,
            ids.MaxIDLength, 4,
            ids.MaxSizeLength, 8,
            ids.DocType, 'webm',
            ids.DocTypeVersion, 2,
            ids.DocTypeReadVersion, 2
        ],
        ids.Segment, [
            ids.Info, [
                ids.TimecodeScale, 1000000,
                ids.MuxingApp, 'Groover',
                ids.WritingApp, 'Groover',
                ids.Duration, 0
            ],
            ids.Tracks,[
                ids.TrackEntry,[
                    ids.TrackNumber, 1,
                    ids.TrackUID, 1,
                    ids.FlagLacing, 0,     // always o
                    ids.Language, 'und',   // undefined I think this means
                    ids.CodecID, 'V_VP8',  // These I think must not change
                    ids.CodecName, 'VP8',  // These I think must not change
                    ids.TrackType, 1,
                    ids.Video, [
                        ids.PixelWidth, 0,
                        ids.PixelHeight, 0
                    ]
                ]
            ]
        ]
    ];    
    function getHeader(){
        header[3][2][3] = name;
        header[3][2][5] = name;
        header[3][2][7] =  dataTypes.double2Str(frameDelay);
        header[3][3][1][15][1] =  width;
        header[3][3][1][15][3] =  height;
        function create(dat){
            var i,kv,data;
            data = [];
            for(i = 0; i < dat.length; i += 2){
                kv = {i : dat[i]};
                if(Array.isArray(dat[i + 1])){
                    kv.d = create(dat[i + 1]);
                }else{
                    kv.d = dat[i + 1];
                }
                data.push(kv);
            }
            return data;
        }
        return create(header);
    }
    function addCluster(){
        webmData[videoDataPos].d.push({ i: ids.Cluster,d: [{ i: ids.Timecode, d: Math.round(clusterTimecode)}]}); // Fixed bug with Round
        clusterCounter = 0;
    }
    function addFrame(frame){
        var VP8, kfS,riff;
        riff = getWebPChunks(atob(frame.toDataURL(frameMimeType, quality).slice(23)));
        VP8 = riff.RIFF[0].WEBP[0];
        kfS = VP8.indexOf(keyframeD64Header) + 3;
        frame = {
            width: ((VP8.charCodeAt(kfS + 1) << 8) | VP8.charCodeAt(kfS)) & 0x3FFF,
            height: ((VP8.charCodeAt(kfS + 3) << 8) | VP8.charCodeAt(kfS + 2)) & 0x3FFF,
            data: VP8,
            riff: riff
        };
        if(clusterCounter > CLUSTER_MAX_DURATION){
            addCluster();            
        }
        webmData[videoDataPos].d[webmData[videoDataPos].d.length-1].d.push({
            i: ids.Frame, 
            d: S(ids.FrameBlock) + S( Math.round(clusterCounter) >> 8) +  S( Math.round(clusterCounter) & 0xff) + S(128) + frame.data.slice(4),
        });
        clusterCounter += frameDelay;        
        clusterTimecode += frameDelay;
        webmData[videoDataPos].d[0].d[3].d = dataTypes.double2Str(clusterTimecode);
    }
    function startEncoding(){
        frameNumber = clusterCounter = clusterTimecode = 0;
        webmData  = getHeader();
        addCluster();
    }    
    function toBlob(vidData){
        var data,i,vData, len;
        vData = [];
        for(i = 0; i < vidData.length; i++){
            data = dataTypes[typeof vidData[i].d](vidData[i].d);
            len  = data.size || data.byteLength || data.length;
            vData.push(stream.num(vidData[i].i));
            vData.push(stream.compInt(len));
            vData.push(data)
        }
        return new Blob(vData, {type: videoMimeType});
    }
    function getWebPChunks(str){
        var offset, chunks, id, len, data;
        offset = 0;
        chunks = {};
        while (offset < str.length) {
            id = str.substr(offset, 4);
            // value will have top bit on (bit 32) so not simply a bitwise operation
            // Warning little endian (Will not work on big endian systems)
            len = new Uint32Array(
                new Uint8Array([
                    str.charCodeAt(offset + 7),
                    str.charCodeAt(offset + 6),
                    str.charCodeAt(offset + 5),
                    str.charCodeAt(offset + 4)
                ]).buffer)[0];
            id = str.substr(offset, 4);
            chunks[id] = chunks[id] === undefined ? [] : chunks[id];
            if (id === 'RIFF' || id === 'LIST') {
                chunks[id].push(getWebPChunks(str.substr(offset + 8, len)));
                offset += 8 + len;
            } else if (id === 'WEBP') {
                chunks[id].push(str.substr(offset + 8));
                break;
            } else {
                chunks[id].push(str.substr(offset + 4));
                break;
            }
        }
        return chunks;
    }
    function Encoder(fps, _quality = 0.8, _name = "Groover"){ 
        this.fps = fps;
        this.quality = quality = _quality;
        this.frameDelay = frameDelay = 1000 / fps;
        this.frame = 0;
        this.width = width = null;
        this.timecode = 0;
        this.name = name = _name;
    }
    Encoder.prototype = {
        addFrame : function(frame){
            if('canvas' in frame){
                frame = frame.canvas;    
            }
            if(width === null){
                this.width = width = frame.width,
                this.height = height = frame.height
                startEncoding();
            }else
            if(width !== frame.width || height !== frame.height){
                throw RangeError("Frame size error. Frames must be the same size.");
            }            
            addFrame(frame);   
            this.frame += 1;
            this.timecode = clusterTimecode;
        },        
        toBlob : function(){
            return toBlob(webmData);
        }
    }
    return {
        Video: Encoder,
    }
})()


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow