天天看點

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

上一章: OTT端技術賦能之前端收單能力建設 | 《優酷OTT網際網路大屏前端技術實踐》第四章>>> 下一章: 不一樣的煙火:記OTT端半屏互動能力建設 | 《優酷OTT網際網路大屏前端技術實踐》第六章>>>

點選免費下載下傳

《優酷OTT網際網路大屏前端技術實踐》>>>

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章
作者| 阿裡巴巴文娛技術 罄天

一、背景

圖檔作為網頁中的重要組成元素,廣泛存在于各種站點中,有些站點中的圖檔内容已經遠遠超過了其他網頁内容總和。如何高效的、快速的制作業務圖檔就被廣泛的提出來。阿裡有很多自動化圖檔生産平台,如海棠,魯班等。

談到自動化制圖,主要有兩種模式:

一是自動化模式:依賴于服務化能力包裝,将核心制圖能力進行抽取,任何三方通過直接調用服務能力即可完成圖檔的合成,此種模式完全自動化,無需任何人工幹預即可制作出符合指定條件的業務圖檔;

二是半自動化模式:主要依賴于業務共性的提取與升華,将繁瑣的重複的業務流程通過統一的範式來解決,或多或少的需要人工幹預。人工幹預一方面需要人力投入,另一方面意味着可以發揮人的主觀創造性。成品圖除了滿足指定的共性外,也可以保證輸出個性,這種個性與共性并存的方式不失為一種好的折中。

二、OTT自動化制圖

1、OTT自動化制圖的起源

以前,優酷OTT側有自動化制圖的雛形,主要依據前端提供制圖的工具平台,并将OTT主要合作廠商坑位圖配置資訊進行固化,然後營運在工具平台上做相應的坑位圖合成。此模式在一定程度上滿足了營運的合圖需求。

在2019年,OTT側開始嘗試自動化制圖。深入自動化制圖的目的也很明顯,主要基于以下痛點:

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章
1)内容源與成品沉澱

我們觀察到,阿裡集團開始大面積的做自動化制圖的嘗試,有影響力的包括魯班系統。從OTT的業務場景出發,這些平台存在一些不足:比如,所生産物料的最終落地形式是一次性的,忽略了物料的源和産物最核心的内容價值。從管道次元來講,OTT側坑位圖具有高度的同質性,不僅包括内容源如節目,而且從産物的角度也如此。例如《愛我就别想太多》,某電視廠商對資源位有明确的要求,而且優酷等平台方也需要這一内容源,内容源的價值就應該被放大。另外,優酷需要将同一個成品圖,投放到不同管道上,如果能從産物角度做沉澱,成品圖才能發揮最大價值。

2)場景單一

制圖工具解決的問題非常有限,主要是節目圖的制作。前文提到,從内容源到成品圖都缺少相應沉澱,這使得自動化制圖服務的場景單一,和目前平台能力相比有明顯差距。

現階段OTT自動化制圖涵蓋了節目圖、輪播、專題、動圖等常見的制圖場景,并結合自動化與半自動化雙軌模式。半自動化場景下可以充分發揮營運創造性,基于原材料做創新性嘗試;在自動化場景下,直接對接專題輪播系統,使得依賴于特定模闆的制圖無需人工參與。更近一步,在大資料推薦上也有相應場景,比如依賴于用戶端唯一辨別實作個性化的專題類推薦,這使得自動化制圖一改之前"自動化"包裝的外表。

3)分發效率

平台建立之初,從素材源到成品的完整鍊路都在本地環境完成,依賴于工具平台下載下傳的成品圖對接給營運、第三方進行投放。嚴重依賴于營運的人力投入,分發效率低,其原因是從内容源到成品庫,到最終的分發鍊路缺乏一緻性,是以使得整個系統沒有“活”起來。

是以從平台建立開始,我們就在探索一條"活"的完整鍊路。通過鍊路的更新,不僅能完成内容源、成品庫的沉澱,也包括最終分發鍊路的更新,進而擺脫傳統工具平台面臨的點狀而非面狀鍊路。

4)TOB廠商

"巧婦難為無米之炊",在自動化制圖場景下,所謂的“米”就是模闆,模闆的格式包括但不限于PSD、SKETCH等,也包括如SVG,比如海棠。“米”是最核心的内容,如果不能從特定的場景中提取内容共性,那麼自動化制圖領域下的效率提升就非常有限,是以共性才是最應該被重視的特征。

并且,這種共性不僅存在于單個内容提供商,也存在于提供商之間。

2、OTT自動化制圖的模式

自動化制圖的優勢非常明顯:

第一是鍊路的更新:通過自動化制圖的流程,可将原來"線下讨論-UED設計-效果确認-開發使用圖檔"的一次性長鍊路,轉化為"UED設計模闆-營運制圖-自動/半自動分發"的非一次性完整流程,縮短溝通成本。

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

第二,内容共享紅利:基于系統設計的高品質毛料庫,産品庫可進一步沉澱,打通多方,減少任何三方重複設計的可能性,将内容價值從原來的一方擴充到整個合作方生态,形成完整的内容回流鍊路;

第三,分發鍊路的建設:基于系統設計的成品圖無需任何人工對接,可直接輸出到管道三方或者對接任何系統。現有可行的嘗試,如專題系統自動化,大資料的個性化推薦場景等,完成從内容生産到内容自動分發的一體化能力建設。

制圖效率環節:在半自動化制圖場景,站外投放時間可從原來周級縮短為小時級,計件的時間成本減低50%~60%。而在自動化制圖場景,無需任何人工幹預的方式,使得自動化制圖能真正發揮價值。

二、OTT自建自動化制圖平台

可能會有人問,阿裡已經有魯班系統等自動化制圖平台,為什麼優酷OTT要自建?

1、為什麼考慮自建?

與魯班系統服務的(側重商品化屬性)場景不同, OTT場景更側重媒資屬性。圖檔主體次元的偏差,使得很多原本在商品制圖場景下的規則被打破。比如一個簡單的元素縮放操作,正常是按照等比加移動的方式解決。但是在以人物為中心的場景,這可能并不合理。因為在以人為主體的場景中,所有模闆的指定需要考慮“人物”,而非人物所在元素圖檔的縮放,簡單的說就是人臉,否則可能面臨着人物縮放不滿足模闆要求的場景。是以,我們需要更進一步引入算法或人工打标的新思路。而且,除了元素縮放的特有場景,其實這種差別還很多。比如特定場景的模糊效果、動圖繪制、自動化能力輸出等等,這種基于特定業務特性的需求海棠确實難以做到定制。

2、商品圖使用海棠

除了生産媒資海報圖以外,OTT業務也需要生産商品圖。比如天貓魔盒:

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

在沒有自建系統之前,所有天貓魔盒的圖檔生産全部依賴于海棠。設計師從海棠背景傳入模闆,然後基于此模闆在海棠上做相應的坑位圖。但自建系統後也慢慢嘗試切回到自有系統,主要原因有兩個:

第一,内容回流: OTT業務本身是一閉環系統,媒資圖和商品圖缺一不可。這使得内容隔離漸漸不被接受。内容回流到自有系統後可以做統一管理、分發,享受現有系統提供的能力;

第二,定制化能力:設計師的需求往往依據業務的疊代漸漸變化,漸進增強成為一個常态。是以,當自己的述求不被滿足或者不會被滿足後可能會漸漸的喪失信心,進而轉向新的平台。而自建系統正好提供了這樣一個契機。下圖提供了一個基于多模闆拼接的述求。任何模闆可以随意拖進工作區,然後對模闆元素加工并設定模闆特性,比如模闆間距等。

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

三、OTT自動化制圖的流程

關于自動化制圖我們是如何實作的?整體流程可以簡化為下圖:

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

1、模闆解析與資料格式化

自動化制圖的前提是内容的共性,共性點更近一步的提取,就是模闆,模闆格式包括但不限于PSD、SKETCH、SVG等。任意一張成品圖都可以看做是基于某一種模闆生産出來的,這張成品圖由不同圖層構成,這和Photoshop中的圖層是同一個道理。比如以下示例圖就包含了角标、文案賣點、主題、主角、蒙版,背景圖等諸多圖層。通過對不同圖層的自由組合、編輯,得到最終的成品圖。

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

上面講到模闆是由不同的圖層所描述的,更形象的,模闆就是解析後得到的格式化資料,描述了模闆中的元素資訊,如位置、尺寸、數量等等。而成品圖可以看做是基于這些約定(也可以看做是圖紙)生産出來的最終元素。

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

上圖就是對PSD的解析後擷取到的模闆縮略圖。當然,正如前文所講,解析後圖檔的存在形式也不再是圖檔本身,而是格式化的資料,一般是對應的JSON。該JSON包含了模闆指定的所有元素資訊:

const templateInfo = {
      "modelBase": {
        // 包括模闆本身的資訊,如尺寸等
      },
      "psdLayerInfoList": null,
      "person": [
        // 模闆包含的主體個數,主體可以是人或者其他元素
        // 也包括主體的人臉資訊等
      ],
      "bgPic": {
        //背景圖
      },
      "themeGradientMask": [{
        //主題漸變
      }],
      "showNameH": [{
      }],
      "showNameV": [{
      }],
      "mMask": [{}],
      "mAppLogo": [{
      }],
      "mFontAppName": [{}]
 }           

2、前端依據模闆繪制流程

服務端做了統一的資料格式化後,給到前端的是格式化的資料,資料指定了模闆包含的所有元素資訊,前端基于該元素資訊進行繪制。

1)分層繪制

HTML5頁面中圖層的概念大家應該已經很熟悉了。講到HTML5的網頁分層就需要深入了解Chrome渲染原理中的RenderObject,、RenderLayer、Graphiclayer等幾棵樹。

除了網頁會分層以外,Canvas中繪制的元素也可以分層,分層繪制有很多優勢。比如在遊戲場景中,很多背景類的圖層需要重繪的可能性遠比動态元素,如障礙物低得多。是以,在每一幀的繪制行為中,可以繞過相應背景圖的繪制,直接繪制目前場景變化的圖層即可,這與Chrome網頁分層要解決的問題是一樣的。

class SmallMultiLayerCanvas {
  constructor(id) {
    this.id = id;
    this.canvas = document.getElementById(id);
    this.ctx2d = this.canvas.getContext('2d');
    this.layers = [];
  }
  static extend = function (defaults, options) {
    var extended = {}, prop;
    for (prop in defaults) {
      if (Object.prototype.hasOwnProperty.call(defaults, prop))
        extended[prop] = defaults[prop];
    }
    for (prop in options) {
      if (Object.prototype.hasOwnProperty.call(options, prop))
        extended[prop] = options[prop];
    }
    return extended;
  };
 // 添加圖層
  addLayer(obj) {
    const layer = SmallCanvas.extend({
      id: Math.random().toString(36).substr(2, 5),
      show: true,
      render: function (canvas, ctx) { }
    }, obj);
    if (this.getLayer(layer.id) !== false) {
      return false;
    }
    this.layers.push(layer);
    return this;
  };
  //渲染所有圖層
  render() {
    var canvas = this.canvas;
    var ctx = this.ctx2d;
    this.layers.forEach(function (item, index, array) {
      if (item.show)
        item.render(canvas, ctx);
    });
  };
  //擷取一個圖層
  getLayer(id) {
    var length = this.layers.length;
    for (var i = 0; i < length; i++) {
      if (this.layers[i].id === id)
        return this.layers[i];
    }
    return false;
  };
  // 移除一個圖層
  removeLayer(id) {
    var length = this.layers.length;
    for (var i = 0; i < length; i++) {
      if (this.layers[i].id === id) {
        removed = this.layers[i];
        this.layers.splice(i, 1);
        return removed;
      }
    }
    return false;
  };
}           

以上是一個簡單的分層繪制的類,通過該類可以随意新增、移除、擷取、渲染任意的圖層。這也是很多複雜的多圖層繪制架構的最核心思想,比如fabric.js或者konvajs。有了這樣的圖層管理架構,就可以根據服務端下發的格式化資料來繪制模闆中指定的任意元素,以模闆為圖紙,生産出符合設計規定的核心産品。例如:

<canvas id="theCanvas" width="512" height="512"></canvas>           

在該Canvas上,我們繪制出幾個指定的圖形看看效果如何:

const myCanvas = new SmallMultiLayerCanvas("theCanvas");
myCanvas.addLayer({
  id: 'background',
  render: function (canvas, ctx) {
    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
  }
})
  .addLayer({
    id: 'squares',
    render: function (canvas, ctx) {
      ctx.fillStyle = "#E5E059";
      ctx.fillRect(50, 50, 150, 150);
      ctx.fillStyle = "#BDD358";
      ctx.fillRect(350, 75, 150, 150);
      ctx.fillStyle = "#E5625E";
      ctx.fillRect(50, 250, 100, 250);
    }
  })
  .addLayer({
    id: 'circles',
    render: function (canvas, ctx) {
      ctx.fillStyle = "#558B6E";
      ctx.beginPath();
      ctx.arc(75, 75, 80, 0, 2 * Math.PI);
      ctx.fill();
      ctx.beginPath();
      ctx.fillStyle = "#88A09E";
      ctx.arc(275, 275, 150, 0, 2 * Math.PI);
      ctx.fill();
      ctx.beginPath();
      ctx.fillStyle = "#704C5E";
      ctx.arc(450, 450, 50, 0, 2 * Math.PI);
      ctx.fill();
    }
  })
  .addLayer({
    id: 'triangles',
    render: function (canvas, ctx) {
      ctx.fillStyle = "#DAF7A6";
      ctx.beginPath();
      ctx.moveTo(120, 400);
      ctx.lineTo(250, 300);
      ctx.lineTo(300, 500);
      ctx.closePath();
      ctx.fill();

      ctx.fillStyle = "#FFC300";
      ctx.beginPath();
      ctx.moveTo(400, 100);
      ctx.lineTo(350, 300);
      ctx.lineTo(230, 200);
      ctx.closePath();
      ctx.fill();

      ctx.fillStyle = "#C70039";
      ctx.beginPath();
      ctx.moveTo(100, 100);
      ctx.lineTo(100, 300);
      ctx.lineTo(300, 300);
      ctx.closePath();
      ctx.fill();
    }
  });
myCanvas.render();
           

上面的代碼通過鍊式調用在Canvas中添加了4個對象,id分别為background、squares、circles、triangles。而且每一個對象都有相應的render方法,該方法指定了元素本身在Canvas的上下文是如何繪制的。基于以上代碼可以看到在Canvas中繪制的效果:

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章
2)單量與批量模式實時渲染

本小節将講述首輪繪制後如何基于使用者輸入做相應的更新。其實所有的半自動化繪圖場景,營運不可能隻根據某一個模闆進行繪制,換句話說,多模闆同時繪制的場景必須加以考量。

比如,大多數場景下,營運需要同時基于模闆來繪制海信、康佳、歌華、LG的所有坑位圖然後導出或者投放,進而擺脫每次隻能單獨繪制導出單模闆的低效模式。是以基于多模闆實時繪制渲染的方式就亟待解決。基于此,在半自動化繪制場景中,天生支援多模闆實時渲染繪制的模式,正如下面的動圖所示:

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

上圖展示的是多模闆實時修改的場景,也就是所謂的關聯模式。但在未開啟關聯模式的場景下,所有的修改隻針對單模闆生效。是以在滿足成品圖共性的同時又保證了模闆的個性。

3、資料統一存儲在服務端

前面講過,工具化平台的設計思路沒法做到鍊路的完整串聯,進而完成内容的回流,這在平台化的思路下是行不通的。平台化解決問題的思路是:從内容生産到内容消費的完整鍊路串聯。

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

基于此,從輸入到輸出,到最終的分發都需要流動起來,這一切的前提都基于資料的存儲,從輸入源到輸出結果。基于存儲的結果,完成了從自動化生産,個性化等自由推薦。

四、OTT蜂鳥制圖場景的主要輸出與輸入

下圖展示了制圖平台在業務上所做的嘗試,也總結了在支撐業務的同時,如何在技術上做範式的探索。

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

從1.0到2.0,是整個系統架構的更新。系統現有支援能力在OTT場景下已經逐漸完善起來。

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

1、技術側主要輸出

1)服務化的能力
我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

服務化的能力是上面所述的解決問題範式的具體形式,而制圖平台服務化的能力已經涵蓋了包括:通用模闆解析能力,圖檔合成服務化能力,素材服務化能力,統一分發能力等等。

a) 通用模闆解析能力,不僅适用于制圖場景的資料格式化,在智能化領域也有涉及;

b) 圖檔合成服務化能力,不僅可用于制圖場景,對于動畫合成場景也有滲透;

c) 至于素材的服務化,分發能力的聯合在業務賦能的同時,也能謀求業務發展方向的新思路。

2)半自動化合圖嘗試

服務化能力将制圖的觸角做了極大的延展,但在半自動化的制圖場景,依然需要探究新的制圖範式。基于此,我們産出了自有的Canvas合圖嘗試,這與魯班、海棠的模式有極大的差異。這條路沒有太多的參考,很多問題需要自己去挖坑和填坑。

2、無人工自動化制圖

自動化制圖具有極大的吸引力,無需營運任何手動制圖幹預,直接在系統中選擇相應的内容集合即可。是以,這種業務賦能嘗試也被極大的重視起來。在OTT業務範圍内比較成功的案例就是專題系統:

我在優酷OTT端做自動化制圖 | 《優酷OTT網際網路大屏前端技術實踐》第五章

通過指定内容集合(scgid)以及相應的封面圖生成規則就可生成相應的專題推薦内容,極大的節省了人力成本。

繼續閱讀