随着资讯技术普及与推陈布新,基础设施及服务(IaaS)、平台即服务(PaaS)、软件即服务(SaaS)等等...让不同的使用者可以依照自身的条件与需求选择服务,接着要探访的项目近几年越来越多开发者熟知的无服务器服务,使用者不在需要思考服务器运算环境需要什麽样的规格、作业系统、负载均衡..等等问题,而在阿里云提供什麽样的无服务器架构服务呢?
阿里云FC是一个透过事件触发驱动的全托管运算服务,只要将程序码逻辑布署上去,当有条件触发时才会去执行运算,而未执行触发FC时不会运行,对於成本降低有相当大的帮助
流程示意图:
接着我们要利用FC建立一个自动转档的应用,将上传至指定OSS资料夹内的影片转码成hls协议的影音格式并存入另一个OSS资料夹内
架构示意图:
在产品导览页找到函数计算服务
点选服务及函数建立服务
建立服务完成後点选新增函数
下方有提供多样的模板可以套用,因为要使用OSS触发驱动这里选择事件函数
建立函数名称,这里要测试的程序使用的是python3运行,上传程序码 (这里上传包含ffmpeg程序档)
目录结构:
ffmpeg
index.py
index.py完整范例程序码:
# -*- coding: utf-8 -*-
import logging
import oss2
import os
import time
import json
import subprocess
from os import walk
logging.getLogger("oss2.api").setLevel(logging.ERROR)
logging.getLogger("oss2.auth").setLevel(logging.ERROR)
OUTPUT_DST = os.environ["OUTPUT_DST"]
DST_TARGET = os.environ["DST_TARGET"]
def get_fileNameExt(filename):
(fileDir, tempfilename) = os.path.split(filename)
(shortname, extension) = os.path.splitext(tempfilename)
return shortname, extension
def get_beijing_time_str(utc_time_stamp):
local_time = time.localtime(utc_time_stamp + 8*3600)
data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
data_secs = (utc_time_stamp - int(utc_time_stamp)) * 1000
beijing_time_str = "%s.%03d" % (data_head, data_secs)
return beijing_time_str
def handler(event, context):
utc_now = time.time()
evt = json.loads(event)
evt = evt["events"]
oss_bucket_name = evt[0]["oss"]["bucket"]["name"]
object_key = evt[0]["oss"]["object"]["key"]
size = evt[0]["oss"]["object"]["size"]
shortname, extension = get_fileNameExt(object_key)
M_size = round(size / 1024.0 / 1024.0, 2)
json_log = {
"request_id": context.request_id,
"video_name": object_key,
"video_format": extension[1:],
"size": M_size,
"start_time": get_beijing_time_str(utc_now),
"processed_video_location": OUTPUT_DST,
}
print(json.dumps(json_log))
creds = context.credentials
auth = oss2.StsAuth(creds.accessKeyId, creds.accessKeySecret, creds.securityToken)
oss_client = oss2.Bucket(auth, 'oss-%s-internal.aliyuncs.com' % context.region, oss_bucket_name)
input_path = oss_client.sign_url('GET', object_key, 6 * 3600)
transcoded_filepath = '/tmp/' + shortname + DST_TARGET
if os.path.exists(transcoded_filepath):
os.remove(transcoded_filepath)
# cmd = ["/code/ffmpeg", "-y", "-i", input_path, "-vf", "scale=640:480", "-b:v", "800k", "-bufsize", "800k", transcoded_filepath]
# cmd = ["/code/ffmpeg", "-y", "-i", input_path, "-b:v", "1M", "-g", "60", "-hls_time", "2", "-hls_list_size", "0", "-hls_segment_size", "500000", transcoded_filepath]
cmd = ["/code/ffmpeg", "-y", "-i", input_path, "-profile:v", "baseline", "-level", "3.0", "-start_number", "0", "-hls_time", "10", "-hls_list_size", "0", transcoded_filepath]
try:
result = subprocess.run(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
except subprocess.CalledProcessError as exc:
err_ret = {
'request_id': context.request_id,
'returncode': exc.returncode,
'cmd': exc.cmd,
'output': exc.output.decode(),
'event': evt,
}
if exc.stderr:
err_ret['stderr'] = exc.stderr.decode()
if exc.stdout:
err_ret['stdout'] = exc.stdout.decode()
print(json.dumps(err_ret))
# if transcode fail, send event to mns queue or insert in do db
# ...
raise Exception(context.request_id + " transcode failure")
return
filenames = next(walk('/tmp'), (None, None, []))[2]
for f in filenames:
if f.find(shortname) != -1:
oss_client.put_object_from_file(
os.path.join(OUTPUT_DST, f), ('/tmp/'+ f) )
## oss_client.put_object_from_file(
## os.path.join(OUTPUT_DST, shortname + DST_TARGET), transcoded_filepath)
# if transcode succ, send event to mns queue or insert in do db
# ...
if os.path.exists(transcoded_filepath):
os.remove(transcoded_filepath)
return "ok"
ffmpeg包为预设的设定,如找不到想测试可以联络笔者(嘘)
建立好函数後,会到程序执行页面,测试执行发现报错
这里发现忘记先建立OSS触发条件;权限,建立触发器:
在OSS Bucket下建立资料夹/vedio/inputs、/vedio/outputs
准备完成後,测试上传影音档案,查看/vedio/inputs上传成功
接着打开/vedio/outputs验证mp4转码与m3u8成功,测试也能正常播放 (本影片仅测试使用)
本篇的小应用就到这里结束,对於经常需要使用影音串流的使用者可以透过FC快速完成转码工作并透过无服务器特性不浪费使用资源,而运用FC能够让开发者集思广益建立更多发挥创意的应用!
<<: [Day 21]从零开始学习 JS 的连续-30 Days---阵列操作介绍 (上篇)
>>: DAY21 - 网页可以操作电脑里的档案?!本地端档案覆写 - The File System Access API
MVP架构: Model — 管理资料来源。例如:SharedPreferences、Room、呼叫...
来到2048的最後一天!看看这麽多的删除线!虽然可能我们不一定能清光我们购物网站上的愿望清单,但是今...
-化名(Pseudonymization) 假名(Pseudonymized)数据可以通过添加信息...
今日文章目录 > - 三角型使用情境 > - 用CSS画三角型 > - 参考资料...
在开始React之旅前,必须先了解一下什麽是SPA。 相较於过去使用的多页式(MPA)网页开发,大多...