2015-07-19 4 views
9

मेरे पास एनिमेशन का एक सेट है जिसे मैं कैनवास (fabric.js) या WebGL (three.js) में बना सकता हूं। मुझे उन्हें एक स्क्रिप्ट के माध्यम से स्वचालित रूप से, सर्वर-साइड रिकॉर्ड करने और वीडियो फ़ाइल आउटपुट करने की आवश्यकता है।एक वीडियो में एचटीएमएल कैनवास/वेबजीएल एनीमेशन सर्वर-साइड रिकॉर्ड करने का सबसे अच्छा तरीका?

एनिमेशन में शामिल हैं:

  1. चित्र
  2. (ऑडियो के साथ)
  3. अन्य एनिमेशन/प्रभाव

मैं इस पर पिछले कुछ महीनों के दौरान एक बहुत शोध किया है वीडियो ।

परिणाम
1. उपयोगकर्ता PhantomJS + FFMPEG
नेतृत्वहीन ब्राउज़र (PhantomJS) और FFmpeg के साथ रिकॉर्ड पर भागो एचटीएमएल कैनवास एनिमेशन। यहां मुद्दा है फ़ैंटॉमजेएस न तो वेबजीएल और न ही वीडियो तत्व का समर्थन करता है।http://phantomjs.org/supported-web-standards.html

2. उपयोग WebSockets यहाँ फिर DataURL
का उपयोग कर सर्वर से वापस डेटा भेजने के लिए, हम ब्राउज़र पर एनिमेशन (जो हम नहीं है क्योंकि हम सर्वर पर सब कुछ करना है कर सकते हैं) चलाने की आवश्यकता होगी ।

3. Use node-canvas
यह जो Node.js. पर HTML कैनवास प्रतिपादन की अनुमति देता है टीजे Holowaychuk द्वारा एक पुस्तकालय है लेकिन इसकी अपनी सीमाएं हैं और मैंने वास्तव में इस क्षेत्र की खोज नहीं की है। (यदि कोई इस लाइब्रेरी पर अधिक प्रकाश डाल सकता है)

अगर किसी ने इसे पहले किया है या मुझे कहीं उपयोगी बना सकता है।
हमें बस इतना करना है कि एनिमेशन बनाने के लिए कुछ डेटा का उपयोग करें और उसे वीडियो में रिकॉर्ड करें, सर्वर की तरफ सबकुछ।

+0

'नोड-कैनवास' 2 डी-संदर्भों के लिए प्रतीत होता है। मुझे 'नोड-वेबग्ल' पैकेज मिला लेकिन इसकी निर्भरताओं को स्थापित करने में असफल रहा। हालांकि एक टिप्पणी के रूप में मुझे लिखना है: यदि आप अपने लिए वीडियो आउटपुट करने के लिए एक वेबग्ल संदर्भ (और इसे एक प्रतिपादन इंजन के रूप में उपयोग करना) रिकॉर्ड करना चाहते हैं, तो 1-बाय -1, आप इसे 'xhr' के साथ सर्वर-साइड कर सकते हैं एक स्थानीय सर्वर लेकिन यदि आप इंटरनेट पर प्रत्येक कनेक्टेड उपयोगकर्ता को वीडियो आउटपुट करना चाहते हैं, तो बस यह मान लें कि यह आपके सर्वरएसएसएस को प्रति विज़िटर एक सीपीयू-जीपीयू जोड़े रखने के लिए कहता है। मैं 'सर्वर-साइड 3 डी प्रतिपादन' के लिए Google की जांच कर रहा हूं: 2015 तकनीक के साथ अब कुछ भी गंभीर नहीं है। – Atrahasis

+0

इसके अलावा: आप जो वर्णन करते हैं वह वेबलॉग को अपने लिए एक प्रतिपादन इंजन के रूप में उपयोग करने का तरीका है, यही कारण है कि मैंने इसके बारे में लिखा है। यदि आप केवल वेबसाइट पर ऐसा करने का तरीका ढूंढते हैं तो आपका प्रश्न http://stackoverflow.com/questions/64291/api-for-server-side-3d-rendering का डुप्लिकेट है। लेकिन वहां सभी उत्तरों के अलावा, कोई भी कुछ भी नहीं लाता है ^^ – Atrahasis

+0

@Atrahasis क्या होगा यदि हम केवल कैनवास रिकॉर्ड करना चाहते हैं और नहीं वेबग्ल। इसके लिए नोड-कैनवास का उपयोग किया जा सकता है? क्या यह वीडियो और एनिमेशन का समर्थन करता है? – Abhinav

उत्तर

1

मैं नोड कैनवास WebGL संदर्भ का समर्थन करता है नहीं लगता है, तो आप एक पुस्तकालय 2 डी ड्राइंग के चारों ओर बनाया का उपयोग करना होगा, और यह निश्चित रूप से किसी भी वीडियो कोडेक के लिए समर्थन नहीं करेंगे।

आप नोड कैनवास का उपयोग कर काम करने के लिए अपने एनीमेशन प्राप्त कर सकते हैं, तो आप अपनी सामग्री के लिए एक दर उचित, कुछ इस तरह से एनिमेटेड फ्रेम हड़पने कर सकते हैं:

प्रकटीकरण: मैं सफलतापूर्वक है बाह्य रूप से जेनरेट की गई छवियों के अनुक्रम को एन्कोड करने के लिए FFmpeg का उपयोग किया, लेकिन नीचे इंटरटरवल() विधि का प्रयास नहीं किया है। एनीमेशन ओवरहेड के अलावा, मैं नहीं जानता कि कैसे 30 एफपीएस पर पीएनजी फाइलों के लिए कैनवास निर्यात करना होगा।

// assuming "canvas" is asynchronously drawn on some interval 

function saveCanvas(canvas, destFile) { 
    return new Promise((resolve, reject) => { 
    const ext  = path.extname(destFile), 
      encoder = '.png' === ext ? 'pngStream' 
            : 'jpegStream'; 
    let writable = fs.createWriteStream(destFile), 
     readable = canvas[encoder](); 

    writable 
     .on('finish', resolve) 
     .on('error', err => { 
     let msg = `cannot write "${destFile}": ${err.message}`; 
     reject(new Error(msg)); 
     }); 
    readable 
     .on('end', () => writable.end()) 
     .on('error', err => { 
     let msg = `cannot encode "${destFile}": ${err.message}`; 
     reject(new Error(msg)); 
     }); 
    readable.pipe(writable); 
    }); 
} 

const FPS = 30; 

let frame = 0, 
    tasks = [], 
    interval = setInterval(() => tasks.push(
    saveCanvas(canvas, `frame_${frame++}.png`)), 1000/FPS); 

// when animation is done, stop timer 
// and wait for images to be written 
clearInterval(interval); 

Promise.all(tasks).then(encodeVideo); 

function encodeVideo() { 
    // too much code to show here, but basically run FFmpeg 
    // externally with "-i" option containing "frame_%d.png" 
    // and "-r" = FPS. If you want to encode to VP9 + WEBM, 
    // definitely see: http://wiki.webmproject.org/ffmpeg/vp9-encoding-guide 
} 

और फिर एक वीडियो में छवियों का एक अनुक्रम एन्कोड करने के लिए FFmpeg का उपयोग करें।
encodeVideo() के पीछे कोड के लिए, आप this example पर देख सकते हैं।

संपादित: वहाँ canvas.pngStream() जबकि एनीमेशन पाश लगातार पर ड्रॉ कि एक कैनवास गलत फ्रेम लेखन के साथ एक मुद्दा हो सकता - हो सकता है कैनवास की एक प्रति फ्रेम प्रति बनाने की आवश्यकता है? यह निश्चित रूप से महत्वपूर्ण स्मृति दबाव पैदा करेगा।

2

आप WebGL पृष्ठों को ब्राउज़रविंडो विकल्प "शो" के साथ सेट करने के लिए इलेक्ट्रॉन का उपयोग कर सकते हैं और/या हेडलेस चलाने के लिए xvfb-run का उपयोग कर सकते हैं।

0

मुझे लगता है कि क्रोमियम हेडलेस मोड पहले से ही वेबजीएल का समर्थन कर सकता है और एक और संभावना है। वीडियो प्रतिपादन भाग अभी तक आना बाकी है: https://bugs.chromium.org/p/chromium/issues/detail?id=781117

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