首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >来自用户输入的动态视频-它是如何工作的?

来自用户输入的动态视频-它是如何工作的?
EN

Stack Overflow用户
提问于 2017-02-06 23:33:47
回答 1查看 401关注 0票数 0

有办法通过代码生成生成视频帧的内容吗?

例如:

我想制作一个程序,它以一些string变量作为输入,然后给出一个相同文本的输出视频,但现在对文本本身有特殊的影响。

在看到Facebook在他们的网站上做的一些项目后,我想到了这个想法。他们有一个与用户相关的图片、评论、朋友、事件、喜欢等等的数据库。所有这些信息,他们做的视频,例如朋友节,视频是完全相关的用户,想发布它。

这些东西是怎么工作的?

有什么软件我可以用吗?有人能给我一个开始的地方吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-09 19:03:31

我想要做一个程序,以一些字符串变量作为输入,然后提供一个输出视频相同的文本,但现在具有特殊效果的文本本身。

您可以使用画布呈现文本,并使用新的媒体记录器API记录结果。

当然,这种效果可以通过多种方式产生,文本内容本身可以针对数据库使用,也可以与机器学习相结合来构造/获取与文本相关的数据。不过,这是一个很广的范围,比这里适用的范围更广。

无论如何,视频本身的生成如下所示。这是一个简单的例子,你可以输入一些文本,它会得到动画和录制为视频。当您单击“停止”时,实际的视频将显示出来(您可以允许用户下载)。您可以扩展与其他效果,故事板的功能,以便您可以记录场景,并开发它来制作一个完整的电影。

请注意,所有的动画发生在画布上的实时。典型的视频以每秒30帧的速度记录,而不是每秒60帧,这是画布的典型帧速率。这也是在平滑方面要考虑的问题。但是,您可以通过瞄准30个FPS来利用这一点来给您的代码更多的时间来处理。API应该通过不给出一个帧速率作为参数来支持步骤记录,但是到目前为止,我还没有能够完成这个工作。

目前对API的支持是有限制的,因为并不是所有的浏览器都支持它。

示例

代码语言:javascript
复制
// un-refined code for demo use only
// set up globals, get key elements
var div = document.querySelector("div");
var btn = document.querySelector("button");
var txt = document.querySelector("input");
var c = document.querySelector("canvas");

// make 2d context without alpha channel
var ctx = c.getContext("2d", {alpha: false});
var isRecording = false;

// stream vars
var rec, stream, tref;

// if clicked, lets go
btn.onclick = setup;

function setup() {
  
  // toggle button text/status for demo
  if (isRecording) {
    this.disabled = true;
    this.innerHTML = "Making video...";
    stop();
    return
  }
  else {
    isRecording = true;
    this.innerHTML = "Click to stop & show video";
  }
  
  // Setup canvas for text rendering
  var ct1 = document.createElement("canvas");
  var ct2 = document.createElement("canvas");
  var ctxText1 = ct1.getContext("2d");
  var ctxText2 = ct2.getContext("2d");
  var w, h;
  
  w = ct1.width = ct2.width = c.width;
  h = ct1.height = ct2.height = c.height;
  
  setupCtx(ctxText1, "#333", "#FF9F05");
  setupCtx(ctxText2, "#FF9F05", "#000");
  
  function setupCtx(ctxText, bg, fg) {
    ctxText.textAlign = "center";
    ctxText.textBaseline = "middle";
    ctxText.font = "92px sans-serif";
    ctxText.fillStyle = bg;
    ctxText.fillRect(0, 0, w, h);
    ctxText.fillStyle = fg;
    ctxText.translate(w/2, h/2);
    ctxText.rotate(-0.5);
    ctxText.fillText(txt.value.toUpperCase(), 0, 0);
  }
  
  // populate grid (see Square object below which handles the tiles)
  var cols = 18,rows = 11,
      cellWidth = (c.width / cols)|0,
      cellHeight = (c.height / rows)|0,
      grid = [],
      len = cols * rows, y = 0, x,
      index, hasActive = true;

  for (; y < rows; y++) {
    for (x = 0; x < cols; x++) {
      grid.push(new Square(ctx, x * cellWidth, y * cellHeight, cellWidth, cellHeight, ct1, ct2, 0.01));
    }
  }

  x = 0;

  // start recording canvas to video
  record();
  
  //animation loop (refactor at will)
  function loop() {
    
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.globalAlpha = 1;
    ctx.clearRect(0, 0, w, h);

    // trigger cells
    for (y = 0; y < rows; y++) {
        var gx = (x | 0) - y;
        if (gx >= 0 && gx < cols) {
            index = y * cols + gx;
            grid[index].trigger();
        }
    }

    x += 0.25;

    // update all
    for (var i = 0; i < grid.length; i++) grid[i].update();
    tref = requestAnimationFrame(loop);
  }

  // setup media recorder to record canvas @ 30 FPS (note: canvas = 60 FPS by def.)
  function record() {
    stream = c.captureStream(30);
    rec = new MediaRecorder(stream);
    rec.addEventListener('dataavailable', done);
    rec.start();
    requestAnimationFrame(loop);
  }
}

// stop recorder and trigger dataavailable event
function stop() {
  rec.stop();
  cancelAnimationFrame(tref);  // stop loop as well
}

// finish up, show new shiny video instead of canvas
function done(e) {
  var blob = new Blob([e.data], {"type": "video/webm"});
  var video = document.createElement("video");
 
  document.body.removeChild(c);
  document.body.appendChild(video);
  
  // play, Don
  video.autoplay = video.loop = video.controls = true;
  video.src = URL.createObjectURL(blob);
  video.onplay = function() {
    div.innerHTML = "Playing resulting video below:";
  };
}

// stolen from a previous example I made (CC3.0-attr btw as always)
// this is included for the sole purpose of some animation.
function Square(ctx, x, y, w, h, image, image2, speed) {
  this.ctx = ctx;
  this.x = x;
  this.y = y;
  this.height = h;
  this.width = w;
  this.image = image;
  this.image2 = image2;
  this.first = true;
  this.alpha = 0;          // current alpha for this instance
  this.speed = speed;      // increment for alpha per frame
  this.triggered = false;  // is running
  this.done = false;       // has finished
}

Square.prototype = {
    trigger: function () { // start this rectangle
        this.triggered = true
    },
    update: function () {
        if (this.triggered && !this.done) { // only if active
            this.alpha += this.speed; // update alpha
            if (this.alpha <= 0 || this.alpha >= 1) 
                this.speed = -this.speed;
        }
        var t = Math.sin(Math.PI * this.alpha);
        if (t <= 0) this.first = !this.first;

        this.ctx.fillStyle = this.color; // render this instance
        this.ctx.globalAlpha = Math.max(0, Math.min(1, t));

        var cx = this.x + this.width * 0.5, // center position
            cy = this.y + this.width * 0.5;

        this.ctx.setTransform(t*0.5+0.5, 0, 0, t*0.5+0.5, cx, cy); // scale and translate
        this.ctx.rotate(-Math.PI * (1 - t)); // rotate, 90° <- alpha
        this.ctx.translate(-cx, -cy); // translate back
        this.ctx.drawImage(this.first ? this.image : this.image2, this.x, this.y, this.width, this.height, this.x, this.y, this.width, this.height);
    }
};
代码语言:javascript
复制
body {background: #555;color:#ddd;font:16px sans-serif}
代码语言:javascript
复制
<div>
  <label>Enter text to animate: <input value="U R AWESOME"></label> 
  <button>Click to start animation + recording</button>
</div>
<canvas width=640 height=400></canvas>

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42079205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档