2015-11-20 16 views
5

Sto provando a disegnare un video su una tela. Per ottenere questo, acquisisco gli eventi onMouseDown e onMouseUp in Javascript per ottenere le coordinate x e y di ciascun evento (che ho bisogno di impostare la posizione, la larghezza e l'altezza del video all'interno dell'area di disegno).Disegna video su tela HTML5

Pertanto, ogni volta che disegno un video sulla tela, il precedente creato deve essere fermato e il nuovo deve essere riprodotto. due problemi:

1) il video non viene riprodotto (la funzione disegna solo il primo fotogramma), ma il suo audio non

2) Come posso ottenere in precedenza disegnato video di smettere?

Demo: http://jsfiddle.net/e3c3kore/

<body> 
    <canvas id="canvas" width="800" height="600"></canvas> 
</body> 



var canvas, context, xStart, yStart, xEnd, yEnd; 

canvas = document.getElementById("canvas"); 
context = canvas.getContext("2d"); 
canvas.addEventListener("mousedown", mouseDown); 
canvas.addEventListener("mouseup", mouseUp); 

function mouseDown(e) { 
    xStart = e.offsetX; 
    yStart = e.offsetY; 
} 

function mouseUp(e) { 
    xEnd = e.offsetX; 
    yEnd = e.offsetY; 
    if (xStart != xEnd && yStart != yEnd) { 
    var video = document.createElement("video"); 
         video.src = "http://techslides.com/demos/sample-videos/small.mp4"; 
         video.addEventListener('loadeddata', function() { 
          video.play(); 
          context.drawImage(video, xStart, yStart, xEnd-xStart, yEnd-yStart); 
         }); 
    } 
} 

Demo: http://jsfiddle.net/e3c3kore/

risposta

2

1) Il metodo drawImage() è stato essere chiamato solo una volta. Deve essere chiamato una volta per frame.

2) Chiamare il metodo pause() per interrompere il video.

Ad esempio, il codice seguente avvia un ciclo del timer (per disegnare i fotogrammi) al passaggio del mouse e interrompe qualsiasi video precedente sul mouse.

var canvas, context, video, xStart, yStart, xEnd, yEnd; 

canvas = document.getElementById("canvas"); 
context = canvas.getContext("2d"); 
canvas.addEventListener("mousedown", mouseDown); 
canvas.addEventListener("mouseup", mouseUp); 

function mouseDown(e) { 
    if (video) { 
     video.pause(); 
     video = null; 
     context.clearRect(0, 0, canvas.width, canvas.height); 
    } 
    xStart = e.offsetX; 
    yStart = e.offsetY; 
} 

function mouseUp(e) { 
    xEnd = e.offsetX; 
    yEnd = e.offsetY; 
    if (xStart != xEnd && yStart != yEnd) { 
     video = document.createElement("video"); 
     video.src = "http://techslides.com/demos/sample-videos/small.mp4"; 
     video.addEventListener('loadeddata', function() { 
      console.log("loadeddata"); 
      video.play(); 
      setTimeout(videoLoop, 1000/30); 
     }); 
    } 
} 

function videoLoop() { 
    if (video && !video.paused && !video.ended) { 
     context.drawImage(video, xStart, yStart, xEnd - xStart, yEnd - yStart); 
     setTimeout(videoLoop, 1000/30); 
    } 
} 
+0

Esattamente quello che stavo cercando. Grazie! – user3673449

2

È necessario impostare una fusione continua. Stai solo visualizzando il primo fotogramma del video. La tela è stupida e non conosce i video. Hai appena scaricato pixel dal video sulla tela. È necessario aggiornare la tela continuamente.

Il modo migliore è utilizzare requestAnimationFrame per assicurarsi che tutto sia sincronizzato con il rendering del browser.

Nell'esempio seguente, il rendering viene avviato quando viene caricato il video. Assicurati di terminare gli aggiornamenti precedenti se carichi un secondo video.

var canvas = document.getElementById("canV"); 
 
var ctx = canvas.getContext("2d"); 
 

 
var video = document.createElement("video"); 
 
video.src = "http://techslides.com/demos/sample-videos/small.mp4"; 
 
video.addEventListener('loadeddata', function() { 
 
    video.play(); // start playing 
 
    update(); //Start rendering 
 
}); 
 

 

 

 

 
function update(){ 
 
    ctx.drawImage(video,0,0,256,256); 
 
    requestAnimationFrame(update); // wait for the browser to be ready to present another animation fram.  
 
}
#canV { 
 
    width:256px; 
 
    height:256px; 
 
}
<canvas id="canV" width=256 height=256></canvas>

+0

un modo ancora migliore è aspettare che il 'currentTime' del video sia cambiato, dal momento che rAF può sparare ad un frame rate più alto del video, che è approssimativamente calcolato dal browser in modo tale: o usare il' video.timeupdate 'evento, o all'avvio del loop, controlla se' video.currentTime! == lastPaintedFrameTime'. ma comunque, rAF è più adatto di 'setTimeout' per questo ... – Kaiido

+0

Se si sta usando il mouse per trascinare il video e si sta eseguendo il rendering alla frequenza dei fotogrammi del video si otterranno alcuni effetti strani quando il mouse viene aggiornato a 60 volte al secondo. Né è necessario che "video.timeupdate" sia coerente con la frequenza dei fotogrammi del video e lascerà cadere fotogrammi a favore degli eventi DOM (come "requestAnimationFrame"). Né è "timeupdate" sincronizzato per l'aggiornamento della schermata, il che può risultare in una cimatura. E infine 'currentTime' non è sempre un passo discreto. avere 'currentTime' diverso dall'ultimo non significa che ci sia un nuovo frame disponibile per il rendering. – Blindman67

+0

Manca la posizione della posizione del mouse in OP ... mi dispiace, ma la cosa migliore sarebbe impostare una bandiera quando il mouse si muove, no? A proposito di timeupdate che lasciano i frame per gli eventi DOM non ne sono sicuro, hai riferimenti?e rAF eliminerà i frame anche se il browser è occupato. Ma per il momento attuale, anche se sono d'accordo sul fatto che i diversi tempi attuali non significano che è stato dipinto un nuovo fotogramma, due identici uno significa che lo stesso fotogramma verrà dipinto. http://stackoverflow.com/questions/28420724/how-to-determine-the-intended-frame-rate-on-an-html-video-element – Kaiido

-1

Da ultimi giorni sto lavorando allo stesso progetto chiamato come chroma keying effetto che consistono f miscelazione di due videos.so dopo aver cercato a lungo su internet ho trovato un'API chiamata RecordRTC questa API può dare una soluzione .

+0

Potresti ampliare questa risposta? Leggi qui per assicurarti di dare risposte di buona qualità http://stackoverflow.com/help/how-to-answer –