十分鐘上線-FC&IMM構建serverless文件轉換/預覽服務
前言
自從人類進入資訊時代以來,辦公文件是每個人日常頻繁使用的工具,ppt、word、xls、wps、pdf 等為我們工作和生活帶來了很多的便利,尤其進入雲端計算和移動網際網路時代,人們可以利用各種終端來預覽 ppt、word、pdf 等相關文件進行工作和學習,這種情況下,文件之間的格式轉換,各種終端的適配預覽顯得尤為重要,在本文中,我們通過一個ppt 轉換成 vector 並且進行預覽的例子,來看看阿里雲函式計算和智慧媒體管理相結合,快速實現一個彈性高可用的文件轉換/預覽服務。
函式計算
阿里雲函式計算是一個事件驅動的serverless計算服務。通過函式計算,您無需管理伺服器等基礎設施,只需編寫程式碼並上傳。函式計算會為您準備好計算資源,以彈性、可靠的方式執行您的程式碼,具體表現為:
- 無需採購和管理伺服器等基礎設施
- 按需付費
- 專注業務邏輯的開發,能極大提高開發效率
- 穩定高可用,毫秒級別彈性伸縮,快速實現底層擴容以應對峰值壓力
- 提供日誌查詢、效能監控、報警等功能快速排查故障
智慧媒體管理
阿里雲智慧媒體管理(Intelligent Media Management,簡稱 IMM),是阿里雲提供的針對媒體資料的高階、智慧管理服務。它具有與平臺無關的 RESTful API 介面,為阿里雲上的非結構化儲存資料(例如,OSS 中的視訊、圖片、文件等資料)提供快捷的資料處理通道,比如 OFFICE 格式轉換,圖片、視訊的編輯處理,以及人工智慧的價值資料提取和檢索(例如,標籤識別、人臉分組)。IMM 提供場景化構建的一站式資料應用解決方案,適合媒資管理、智慧網盤、社交應用、相簿圖床等開發者使用。
在本文中,我們主要討論 ofollow,noindex" target="_blank">智慧媒體管理產品文件轉換/預覽功能
彈性高可用的文件轉換/預覽服務快速構建
在本案例中,我們對一個ppt文件轉換成vector格式,然後直接使用“智慧媒體管理”服務提供的預覽渲染引擎, 對轉換成功後的檔案進行預覽。本文只針對ppt 轉換成 vector,智慧媒體支援十分豐富的文件轉換,具體參考: https://help.aliyun.com/document_detail/63761.html
在案例中,我們使用的阿里雲資源在同一個region-杭州
1. 開通函式計算、 智慧媒體管理 和 物件儲存
2. 登入),建立一個project,假設為 imm-demo
3. 登入物件儲存控制檯, 建立一個bucket,假設為 fc-imm-demo
, 由於要瀏覽器進行預覽,這裡設定跨域訪問配置 *.imm.aliyun.com
4. 登入函式計算控制檯, 建立相應的service 和 function, 具體參考使用控制檯編寫函式
- 配置service的role 具有訪問imm和oss讀的許可權
配置oss讀許可權主要是為了生成安全預覽文件的url地址,在本文中直接授予service 的role 具有 AliyunIMMFullAccess
和 AliyunOSSReadOnlyAccess
, 當然為了安全,您可以把oss讀許可權的粒度具體到某個 bucket 和某個資料夾。
如果您不想使用函式計算中 service 中的 role 參與生成預覽url, 您可以直接建立單獨的子賬號,在函式呼叫ram相關服務獲取sts,過程可以參考: https://yq.aliyun.com/articles/589902
-
編寫函式, 函式計算 python/nodejs runtime 內建了 imm 的 sdk,直接編寫程式碼如下:
python 版本
#-*- coding: utf8 -*- import json, time from collections import OrderedDict from aliyunsdkcore.client import AcsClient from aliyunsdkimm.request.v20170906 import CreateOfficeConversionTaskRequest from aliyunsdkimm.request.v20170906 import GetOfficeConversionTaskRequest from aliyunsdkcore.auth.credentials import StsTokenCredential try: from urllib import quote except: from urllib.parse import quote PREVIEWURL = 'https://preview.imm.aliyun.com/index.html'; PREVIEWTGTPATH = 'fc-demo-preview-output-py'; immProject = "imm-demo"; srcUri = "oss://fc-imm-demo-sz/test-data/office/test.pptx"; # https://help.aliyun.com/document_detail/63761.html tgtType = "vector" def getBucketByUri(uri): if uri.startswith("oss://"): return uri[6:].split("/")[0] raise Exception("SrcUri is invalid") def getFileNameByUri(uri): return uri.split("/")[-1] def handler(event, context): creds = context.credentials sts_token_credential = StsTokenCredential(creds.access_key_id, creds.access_key_secret, creds.security_token) clt = AcsClient(region_id=context.region, credential=sts_token_credential) bucket = getBucketByUri(srcUri) fileName = getFileNameByUri(srcUri) tgtUri = "oss://{0}/{1}/{2}".format(bucket, PREVIEWTGTPATH, fileName) createReq = CreateOfficeConversionTaskRequest.CreateOfficeConversionTaskRequest() createReq.set_Project(immProject) createReq.set_SrcUri(srcUri) createReq.set_TgtUri(tgtUri) createReq.set_TgtType(tgtType) response = clt.do_action_with_exception(createReq) print(response) res = json.loads(response) taskId = res["TaskId"] getReq = GetOfficeConversionTaskRequest.GetOfficeConversionTaskRequest() getReq.set_Project(immProject) getReq.set_TaskId(taskId) period = 1 timeout = 30 start = time.time() while True: response = clt.do_action_with_exception(getReq) #print(response) status = json.loads(response)["Status"] if status == "Finished":#任務完成 print("Task finished.") break if status == "Failed":#任務失敗 print("Task failed.") break if time.time() - start > timeout:#任務超時 print("Task timeout.") break time.sleep(period) # get preview url params = OrderedDict() params["url"] = "http://" + context.region + ".aliyuncs.com/" + PREVIEWTGTPATH + "/"+ fileName params["accessKeyId"] = creds.access_key_id params["accessKeySecret"] = creds.access_key_secret params["stsToken"] = quote(creds.security_token) params["region"] = "oss-" + context.region params["bucket"] = bucket paramsLi = [ k + "=" + vfor k, v in params.items()] paramsStr = "&" .join(paramsLi) preview = PREVIEWURL + "?" + paramsStr print(preview) return preview
nodejs 版本
const { RPCClient } = require('@alicloud/pop-core'); function getBucketByUri(uri) { if(uri.startsWith("oss://")){ return uri.substr(6).split("/")[0]; } throw new Exception("SrcUri is invalid"); } function getFileNameByUri(uri) { var arr = uri.split("/"); return arr[arr.length - 1]; } function parse(params){ return Object.keys(params).map(function (key){ return `${key}=${params[key]}`; }).join("&"); } exports.handler = function(event, context, callback) { // 預覽引擎的訪問地址 const previewUrl = 'https://preview.imm.aliyun.com/index.html'; // 轉換結果存放路徑 const previewTgtPath = 'fc-demo-preview-js'; var immProject = "imm-demo"; var immSrcUri = "oss://fc-imm-demo/test-data/office/test.pptx"; // 獲取AK資訊 var akInfo = { accessKeyId: context.credentials.accessKeyId, accessKeySecret: context.credentials.accessKeySecret, securityToken: context.credentials.securityToken }; var bucket = getBucketByUri(immSrcUri) var client = new RPCClient({ endpoint: `https://imm.${context.region}.aliyuncs.com`, accessKeyId: akInfo.accessKeyId, accessKeySecret: akInfo.accessKeySecret, securityToken: akInfo.securityToken, apiVersion: '2017-09-06' }); var fileName = getFileNameByUri(immSrcUri); // https://help.aliyun.com/document_detail/63761.html var immParams = { Project: immProject, SrcUri: immSrcUri, TgtType: "vector", TgtUri: `oss://${bucket}/${previewTgtPath}/${fileName}` }; var ossRegion = `oss-${context.region}` //get vectorpreview url var params = {}; // 預覽文件地址 params.url = `http://${bucket}.${ossRegion}.aliyuncs.com/${previewTgtPath}/${fileName}`; params.accessKeyId = akInfo.accessKeyId; // 訪問預覽文件的accessKeySecret params.accessKeySecret = akInfo.accessKeySecret; // 訪問預覽文件的SecurityToken params.stsToken = encodeURIComponent(akInfo.securityToken); // 預覽文件的region params.region = ossRegion; // 預覽文件的bucket params.bucket = bucket; // 拼接預覽URL var url = `${previewUrl}?${parse(params)}`; client.request("createOfficeConversionTask", immParams).then(function() { console.log(url); callback(null, url); }); };
5. 點選執行函式,函式的返回值為預覽的url,用瀏覽器開啟生成的url,就可以預覽轉換格式後的ppt了
總結
從本文的示例中,我們可以看出,基於oss儲存,使用函式計算和智慧媒體管理,短短的幾行程式碼就可以快速實現一個彈性高可用的文件轉換/預覽服務,在本文中,演示的函式的觸發是通過手動觸發,函式計算整合豐富的事件源,通過事件源可以觸發函式,比如對於上傳到oss的某個文件,自動觸發文件格式轉換, 結合http trigger 來設定 event 來達到對主動對某個文件格式轉換並直接預覽,從而實現實現一個彈性高可用的文件轉換/預覽服務,類似 函式計算實現Serverless圖片處理服務