像HTML一样编写视频:灵活的时间与空间单位

405 阅读3分钟

之前介绍过米拉视频改造的FFCreator,让我们可以像HTML一样编写视频,接下来我会分享一些语法和实践。

先来看一个例子:

<miraml>
  <canvas width="1280" height="720">
    <image x="50vw" y="50vh" width="100vw" height="100vh" src="pic1.jpg">
      <image x="50vw" y="50vh" width="50vw" src="pic1.jpg"></image>
      <image start="1" x="50vw" y="50vh" src="pic2.jpg"></image>
      <image start="2" x="80rpx" y="80rpx" height="100rpx" width="100rpx" src="pic2.jpg"></image>
      <image start="3" duration="2" x="80" y="80" height="100" width="100" src="pic2.jpg"></image>
    </image>
  </canvas>
</miraml>

ps. 所有的示例都是可以直接复制到MiraPlayer的沙盒里直接预览播放的

也支持在掘金/codepen的沙盒里玩(唯一的不爽是编写miraml没有代码高亮):


接下来说重点:

一、空间(长度)单位与自适应

每个跟画面显示相关的节点(Node),比如图片、视频、贴纸、文字等等,都支持空间布局的属性: x, y, width, height,目前所有的布局都是绝对布局,也就是锚点(anchor)相对坐标原点(画布左上角)的距离。(跟画面显示无关的,比如:音频,就是没有这些空间布局属性)

WX20220825-102213@2x.png

👁️👁️ 锚点(anchor)是元素布局位置点,格式是[x, y],值都是0~1之间,即代表锚点相对与元素长、宽的百分比。默认值是[0.5, 0.5],即中心点。

锚点在MiraML中的描述格式写为 <node anchor="[0,1]"></node>
默认为<node anchor="[0.5,0.5]"></node>

WX20220825-102115@2x.png

单位支持以下几种格式:

  1. px,即绝对像素。不写单位,也会当做px处理,比如:600代表600px (但强烈不推荐)
  2. rpx,即相对像素,无论画布(canvas)是什么比例(横屏/竖屏)和尺寸(720p/1080p),画布宽度都是360rpx。比如,180rpx就是画面一半的宽度,这样布局就不会因为最后烧录的时候改变生成视频的尺寸而改变
  3. vw/vh,同CSS里的概念,100vw = 100%画布宽度,100vh = 100%画布高度。方便最终视频比例改变的时候,实现依然能自适应的居中、对齐等效果

如果用沙盒玩的朋友需要注意:因为非常不推荐绝对像素(px)作为单位,所以如果不写单位的情况,沙盒中会被强制转化为rpx单位。

ps. 以后可能会支持更多的单位,布局和对齐方式,有需求的小伙伴可以加入我们微信群讨论

二、时间单位与自适应

每个节点(Node),无论声音还是画面,都支持时间相关的属性: start, duration, end ,分别代表以下含义:

  1. start: 相对父节点开始时间的开始时间,默认: 0
  2. end: 相对父节点开始时间的结束时间,默认: 100%
  3. duration: 持续时长,默认: 100%

WX20220823-171823@2x.png

⚠️ endduration只需要其中1个就可以了,因为duration = end - start, 如果这2个属性同时存在且矛盾,优先取end值(舍弃duration)。

单位支持以下几种格式:

  1. 不写单位,即秒(s),是绝对时间,比如:5 代表5秒
  2. %,百分比,相对父节点时长的百分比,比如:父节点时长10秒,50%就是5秒。
  3. 百分比+绝对时长,构建更灵活的相对时长,比如:
<parent duration="10">
  <!-- child将会在parent开始1秒后进场,在parent结束3秒前(第7秒)离场 -->
  <child start="1" end="100%-3"></child>
</parent>

这样模板就能针对不同时长的素材,达到灵活适应的效果。

👁️👁️ 相对父节点的时间,仅仅用于时长的计算,父节点的开始和结束,不会影响到子节点!也就是说子节点完全可以在父节点开始前就进场,也可以在父节点结束后才离场

<parent duration="10">
  <!-- child将会在parent开始1秒前进场,在parent结束1秒后离场 -->
  <child start="-1" duration="100%+2"></child>
</parent>

如果套用空间布局的概率来理解"时间布局"的话,有点类似 overflow: visible

👁️👁️ startend都可以为负值,但必须end - start > 0
👁️👁️ duration必须大于0,否则无效

参考:

开源项目: FFCreator

如果遇到问题也可以扫码入群:

contact_me_qr.png