من خلال تحميل الصور ذات الأحجام المناسبة، يمكن للمستخدمين معاينة التأثير المشابه لعرض الشرائح عن طريق تحديد التأثير والموسيقى الخاصة بالرسوم المتحركة، ثم النقر أخيرًا للتأكيد لإنشاء مقطع فيديو، والذي يمكن تشغيله على العناوين الرئيسية أو Douyin.
الحلول الممكنة لإنشاء مقاطع الفيديوتحويل ترميز الفيديو الأمامي النقي (مثل WebM Encoder Whammy)
قم بتمرير كل إطار من الصورة إلى الواجهة الخلفية للتنفيذ، وتستدعي الواجهة الخلفية FFmpeg لتحويل ترميز الفيديو.
يمكن تحقيق إنشاء الصور من خلال واجهة اللوحة الأصلية toDataURL، وفي النهاية إرجاع بيانات الصورة في نموذج base64.
function generatorPng() { var Canvas = document.createElement('canvas'); Let icavas = '#canvas' // معرف Canvas لعرض الرسوم المتحركة if (wrapWidth == 2) { icavas = '#verticalCanvas' } var CanvasNode = document .querySelector(icavas) Canvas.width = CanvasNode.width; Canvas.height = CanvasNode.height; Canvas.getContext('2d'); ctx.drawImage(canvasNode, 0, 0); var imgData = Canvas.toDataURL(image/png);كيفية التقاط لقطات شاشة للرسوم المتحركة على القماش
استخدم setInterval لتنفيذ طريقة إنشاء الصور بانتظام، ويمكنك أيضًا استخدام requestAnimationFrame.
setInterval(function() { imgsTemp.push(generatePng())}, 1000/60)كيفية الحصول على كل إطار من الصورة في الخلفية
الحل 1: يقوم المتصفح بدون رأس بتشغيل ملف js للرسوم المتحركة للواجهة الأمامية، ثم يلتقط لقطة شاشة لملف js
الفكرة المبدئية:
تتم طباعة لقطات الشاشة باستخدام console.log، لقطات الشاشة القماشية بتنسيق base64، وهي رسوم متحركة مدتها 15 ثانية، وهناك أكثر من 100 لقطة شاشة، مما تسبب بشكل مباشر في تعطل الخادم (مرفوض)؛
خطة التشغيل التجريبي:
يتم تخزين لقطة الشاشة في متغير js، بعد تشغيل الرسوم المتحركة، تتم إضافة شعار إلى الصفحة، ثم تحصل الواجهة الخلفية على المتغير.
صفحات const = { imageZoomOut: import ('./image_zoom_inout.js')، // Zoom imageArt: import ('./image_art.js')، // مسح imageGrid: import ('./image_grid.js')، / /Grid imageRotate: import ('./image_rotate.js')، // فتح وإغلاق imageFlash: import ('./image_flash.js')، // فلاش الصورة والنص imageVerticalArt: import ('./image_vertical_art.js')، // المسح العمودي imageVerticalGrid: import ('./image_vertical_grid.js')، // الشبكة العمودية imageVerticalRotate: import ('. /image_vertical_rotate.js ')، // فتح وإغلاق imageVerticalFlash عموديًا: import ('./image_vertical_flash.js')، // فلاش الصورة العمودية والنص imageVerticalZoomOut: import ('./image_vertical_zoom_inout.js')، // تكبير عمودي imageVertical: import ('./image_vertical.js')، // الإصدار العمودي عام}؛var isShow = falsevar imgsBase64 = []var imgsTemp = []var CutInter = nullvar imgsTimeLong = 0function getQuerys(tag) { Let queryStr = window.location.search.slice(1); Let queryArr = queryStr.split('&'); Let query = []; ; i++) { Let queryItem = queryArr[i].split('='); Let qitem = decodeURIComponent(queryItem[1]) if (queryItem[0] == tag) { query.push(qitem); } else { spec[queryItem[0]] = qitem } } return { list: query, spec: spec };}var getQuery = getQuerys('images')var EffectTag = getQuery.spec. tidvar WrapWidth = getQuery.spec.templateTypelet num = 0let imgArr = []وظيفة createImg() { var Images = getQuery.list Let newImg = [] Let vh = WrapWidth == 1 ? 360 : 640 Let vw = WrapWidth == 1 ? 640 : 360 if (effectTag.indexOf('Flash') > -1) { image.map(function (العنصر، الفهرس) { إذا (11 === الفهرس || 13 === الفهرس || 16 === الفهرس) { فار تيمب = new Image(vw, vh) temp.setAttribute('crossOrigin', 'anonymous'); temp.src = item; newImg.push(temp) } else { newImg.push(item) } }) imgArr = newImg renderAnimate( EffectTag) } else { image.map(function(item) { var temp = new Image(vw, vh) temp.setAttribute('crossOrigin', 'anonymous'); temp.src = item; temp.onload = function() { num++ if (num == image. length) { renderAnimate(effectTag) } } newImg.push(temp) }) imgArr = newImg }}وظيفة غير متزامنة renderAnimate(page) { // انتظر creatImg() اسمح لي = هذا const pageA = انتظار الصفحات[صفحة]؛ false pageA[page].render(null, { Canvas: InternalCanvas, Images: imgArr }, function() { // بعد تشغيل الرسوم المتحركة isShow = صحيح؛ imgsTemp.push(generatePng()) imgsBase64.push(imgsTemp) Let now = new Date().getTime() window.imgsTimeLong = now - oldDate ClearInterval(cutInter) document.getElementById('cutImg').innerHTML = ' تم'//تحديد الصفحة}) CutInter = setInterval(function() { imgsTemp.push(generatePng()) if (imgsTemp.length >= 50) { imgsBase64.push(imgsTemp) imgsTemp = [] } }, 130)} function getImgs() { return imgsBase64} function generatorPng() { var Canvas = document.createElement('canvas'); Let icavas = '#canvas' if (wrapWidth == 2) { icavas = '#verticalCanvas' } var CanvasNode = document.querySelector(icavas) Canvas.width = CanvasNode.width; ctx.drawImage(canvasNode, 0, 0); Canvas.toDataURL(image/png); return imgData;}window.imgsBase64 = imgsBase64 // متغير تخزين لقطة الشاشة creatImg()
عيوب خطة التشغيل التجريبي:
var temp = new Image(vw, vh)temp.setAttribute('crossOrigin', 'anonymous');الحل النهائي: تشغيل الرسوم المتحركة على جانب NODE
استخدم عقدة قماش لكتابة كل لقطة شاشة إطار إلى المجلد المحدد باستخدام fs.writeFile
const { createCanvas,loadImage} = require(canvas); صفحات const = { imageZoomOut: require('./image_zoom_inout.js'), // Zoom imageArt: require('./image_art.js'), // مسح imageGrid : يتطلب ('./image_grid.js')، // شبكة imageRotate: تتطلب ('./image_rotate.js')، // فتح وإغلاق imageFlash: require('./image_flash.js')، // فلاش الصورة والنص imageVerticalArt: require('./image_vertical_art.js')، // المسح العمودي imageVerticalGrid: require('./image_vertical_grid . js')، // شبكة عمودية imageVerticalRotate: require('./image_vertical_rotate.js')، // شبكة عمودية imageVerticalFlash: يتطلب ('./image_vertical_flash.js')، // صورة عمودية وفلاش نص imageVerticalZoomOut: يتطلب ('./image_vertical_zoom_inout.js')، // تكبير عمودي imageVertical: يتطلب ('./image_vertical.js')، // عام للإصدار العمودي};const fs = require(fs);const querystring = require('querystring');let args =process.argv &&process.argv[2]let parse = querystring.parse(args)let vh = parse.templateType == 1 ? 720 : 1280 // ارتفاع القماش Let vw = parse.templateType == 1 ? 1280 : 720 // عرض القماش Let imgSrcArray = parse.images // مجموعة الصور Let EffectTag = parse.tid // تأثير الرسوم المتحركة Let saveImgPath =process.argv &&process.argv[3]letloadArr = []imgSrcArray.forEach(element => { if (//.(jpg|jpeg|png|JPG|PNG)$/.test(element)) { LoadArr.push(loadImage(element)) } else {loadArr.push(element) }});const Canvas = createCanvas(vw, vh);const ctx = Canvas.getContext(2d);Promise.all(loadArr) .then((images) => { // تهيئة الرسوم المتحركة console.log('بدء الرسوم المتحركة') Let oldDate = تاريخ جديد ().getTime () صفحات [effectTag].render (null، { قماش: قماش، صور: صور }، وظيفة () { ClearInterval (interval) Let now = new Date().getTime() console.log(now - oldDate, 'انتهاء الرسوم المتحركة') }) const الفاصل الزمني = setInterval( (function() { Let x = 0; return () => { x += 1; ctx. Canvas.toDataURL('image/jpeg', function(err, png) { if (err) { console.log(err); return; } Let data = png.replace(/^data:image///w+;base64,/, ''); Let buf = new Buffer(data, 'base64'); `, buf, {}, (err) => { console.log(x, err); 1000 / 60 }) .catch(e => { console.log(e); });
قم بتنفيذ الأمر التالي ضمن iterm
عقدة testCanvas.js 'tid=imageArt&templateType=1&images=../assets/imgs/8.png&images=../assets/imgs/6.png&images=../assets/imgs/7.png&images=../assets/imgs/6.png&images =../الحمار ets/imgs/8.png&images=../assets/imgs/7.png&images=../assets/imgs/4.png&images=../assets/imgs/6.png&images=../assets/imgs/8. png&images=../assets/imgs/7.png' './صور/'
وصف المعلمة:
1) tid هو اسم الرسوم المتحركة
2) نوع القالب هو الحجم: 1:1280*720;
3) الصور هي عنوان الصورة
4) المتغير './images/' هو العنوان الذي تم حفظ لقطة الشاشة فيه،
عيوب التشغيل في بيئة NODEكرر الرسم التالي كل 13 ثانية:
for (var A = 0; 50 > A; A++) p.beginPath(), p.globalAlpha = 1 - A / 49, p.save(), p.arc(180,320,P + 2 * A, 0, 2 * Math.PI)، p.clip()، p.drawImage(x[c], 0, 0, y.width, y.height)، p.restore(), p. ClosePath(); for (var S = 0; 50 > S; S++) p.beginPath(), p.globalAlpha = 1 - S / 49, p.save( ), p.rect(0, 0, d + P + 2 * S, g + b + 2 * S), p.clip(), p.drawImage(x[c], 0, 0, y.width, y.height), p.restore(), p. ClosePath();
نظرًا لنموذج حلقة الحدث الخاص بـ Node.js، فإن استخدام Node.js يجب أن يضمن إمكانية تشغيل دورة Node.js في جميع الأوقات. إذا ظهرت دالة تستغرق وقتًا طويلاً، فسوف تتعطل حلقة الحدث ولا يمكن معالجتها تنفيذ مهام أخرى في الوقت المناسب، ونتيجة لذلك، لا تزال بعض الرسوم المتحركة بطيئة
إمكانية التحسين في وقت لاحقحاول استخدام لغة Go لالتقاط لقطات الشاشة؛
إعادة كتابة الرسوم المتحركة على القماش؛
إضافي معدل البت للفيديومعدل بت الفيديو هو عدد بتات البيانات المرسلة لكل وحدة زمنية أثناء نقل البيانات بشكل عام، الوحدة التي نستخدمها هي كيلوبت في الثانية، وهي آلاف البتات في الثانية. الفهم البسيط هو معدل أخذ العينات، فكلما زاد معدل أخذ العينات لكل وحدة زمنية، زادت الدقة، وكان الملف المعالج أقرب إلى الملف الأصلي. على سبيل المثال، بالنسبة للصوت، كلما ارتفع معدل البت، قلت نسبة الضغط، وقل فقدان جودة الصوت، وأصبحت جودة الصوت أقرب إلى مصدر الصوت.
إطارات FPS في الثانية (إطارات في الثانية))
FPS هو تعريف في مجال الرسومات، يشير إلى عدد الإطارات التي يتم إرسالها في الثانية، وبشكل عام، يشير إلى عدد إطارات الرسوم المتحركة أو الفيديو. يعد FPS مقياسًا لكمية المعلومات المستخدمة لحفظ وعرض الفيديو الديناميكي. كلما زاد عدد الإطارات في الثانية، كلما كان الإجراء المعروض أكثر سلاسة. بشكل عام، الحد الأدنى لتجنب الحركات المتشنجة هو 30. على سبيل المثال، يتم تشغيل فيلم بسرعة 24 إطارًا في الثانية، مما يعني أنه يتم عرض 24 إطارًا ثابتًا بشكل مستمر على الشاشة في ثانية واحدة.
ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.