2015-11-20 8 views
5

मैं कैनवास पर एक वीडियो खींचने की कोशिश कर रहा हूं। इसे प्राप्त करने के लिए मैं प्रत्येक घटना के एक्स और वाई निर्देशांक प्राप्त करने के लिए जावास्क्रिप्ट में ऑनसाउसडाउन और ऑन-हाउसअप ईवेंट को कैप्चर करता हूं (मुझे कैनवास के अंदर वीडियो की स्थिति, चौड़ाई और ऊंचाई सेट करने की आवश्यकता है)।कैनवास पर वीडियो ड्रा करें HTML5

इसलिए, हर बार जब मैं कैनवास पर एक वीडियो खींचता हूं, तो पिछले निर्माण को रोकना चाहिए और नया को खेला जाना चाहिए। दो समस्याओं:

1) वीडियो खेलने नहीं करता है (समारोह केवल पहली फ्रेम) खींचता है, लेकिन उसकी ऑडियो

2) कैसे मैं पहले वीडियो तैयार कर सकते हैं करता है को रोकने के लिए?

डेमो: 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); 
         }); 
    } 
} 

डेमो: http://jsfiddle.net/e3c3kore/

उत्तर

2

1) drawImage() विधि केवल एक बार कहा जा रहा था। इसे प्रति फ्रेम एक बार बुलाया जाना चाहिए।

2) वीडियो रोकने के लिए रोकें() विधि कॉल करें।

उदाहरण के लिए, अनुवर्ती कोड माउस पर एक टाइमर लूप (फ्रेम खींचने के लिए) शुरू करता है और माउस पर किसी भी पिछले वीडियो को रोकता है।

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

बिल्कुल वही जो मैं खोज रहा था। धन्यवाद! – user3673449

2

आप एक सतत प्रतिपादन स्थापित करने के लिए की जरूरत है। आप केवल वीडियो के पहले फ्रेम को प्रस्तुत कर रहे हैं। कैनवास गूंगा है और वीडियो के बारे में नहीं जानता है। आपने वीडियो से कैनवास पर पिक्सल को अभी डंप किया है। आपको लगातार कैनवास अपडेट करना होगा।

requestAnimationFrame का उपयोग करने का सबसे अच्छा तरीका यह सुनिश्चित करता है कि सब कुछ ब्राउज़र के प्रतिपादन के साथ समन्वयित हो।

नीचे दिए गए उदाहरण में वीडियो लोड होने पर प्रतिपादन शुरू हो गया है। यदि आप दूसरा वीडियो लोड करते हैं तो पिछले अपडेट को समाप्त करना सुनिश्चित करें।

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

वीडियो के 'वर्तमान समय' के लिए इंतजार करना एक बेहतर तरीका है, क्योंकि आरएएफ वीडियो की तुलना में उच्च फ्रेम दर पर आग लगा सकता है, जिसे लगभग ब्राउज़र द्वारा गणना की जाती है: या तो 'video.timeupdate का उपयोग करें 'ईवेंट, या अपने लूप से शुरू करने पर, जांचें कि' video.currentTime! == lastPaintedFrameTime'। लेकिन वैसे भी, आरएएफ इस के लिए 'सेटटाइमआउट' से सबसे उपयुक्त है ... – Kaiido

+0

यदि आप वीडियो को खींचने के लिए माउस का उपयोग कर रहे हैं और आप वीडियो फ्रेम दर पर प्रतिपादन कर रहे हैं तो आपको कुछ अजीब प्रभाव मिलेगा क्योंकि माउस 60 पर अपडेट किया गया है प्रति सेकंड बार। न ही 'video.timeupdate' वीडियो फ्रेम दर के अनुरूप होना आवश्यक है और डीओएम घटनाओं (जैसे' requestAnimationFrame') के पक्ष में फ्रेम छोड़ देगा और न ही स्क्रीन रीफ्रेश करने के लिए सिंक किया गया टाइमअपडेट 'है, जिसके परिणामस्वरूप कतरन हो सकता है। और आखिरकार 'वर्तमान समय' हमेशा अलग कदम नहीं है। पिछले समय से 'currentTime' अलग होने का मतलब यह नहीं है कि प्रस्तुत करने के लिए एक नया फ्रेम उपलब्ध है। – Blindman67

+0

ओपी में माउस स्थिति की चीज़ को याद किया ... इसके बारे में खेद है, लेकिन फिर माउस चलने पर ध्वज सेट करना सबसे अच्छा होगा, नहीं? डोम घटनाओं के लिए समय-समय पर ड्रॉप फ्रेम के बारे में मुझे यकीन नहीं है, क्या आपके पास संदर्भ हैं?और ब्राउज़र व्यस्त होने पर भी आरएएफ फ्रेम को छोड़ देगा। लेकिन वर्तमान समय के लिए, भले ही मैं सहमत हूं कि अलग-अलग वर्तमान समय का मतलब यह नहीं है कि एक नया फ्रेम चित्रित किया गया था, दो समान एक का मतलब है कि एक ही फ्रेम चित्रित किया जाएगा। http://stackoverflow.com/questions/28420724/how-to-determine-the-intended-frame-rate-on-an-html-video-element – Kaiido

-1

पिछले कुछ दिनों जो इंटरनेट पर एक लंबे खोज करने के बाद दो videos.so की च मिश्रण से मिलकर बनता है मैं एक ही परियोजना क्रोमा कुंजीयन प्रभाव के रूप में कहा जाता है पर काम कर रहा हूँ से मैं एक API RecordRTC कहा जाता है इस एपीआई आप एक समाधान दे सकते हैं पाया ।

+0

क्या आप इस उत्तर पर विस्तार कर सकते हैं? यह सुनिश्चित करने के लिए यहां पढ़ें कि आप अच्छे गुणवत्ता वाले उत्तर दे रहे हैं http://stackoverflow.com/help/how-to-answer –

संबंधित मुद्दे