短視頻SDK提供了自定義特效能力,您可以基于通用特效配置文件,通過自定義OpenGL ES Shader(OpenGL ES 3.0語法),實現想要的濾鏡與轉場效果。有關OpenGL ES的知識點和解釋并不屬于本篇文檔的范疇,我們默認您已經對OpenGL ES及其Shader Language有所了解。
簡介
一個濾鏡或轉場的特效資源包文件夾,包含了一個名為config.json的通用特效配置文件以及一些圖片素材。在短視頻SDK中編輯視頻和錄制視頻時,支持使用轉場和濾鏡特效,即調用相關編輯和錄制接口時,傳入所配置的特效資源包文件夾目錄,來應用一個特效效果。
配置通用特效配置文件
通用特效配置文件采用JSON格式,描述了完整的渲染過程。整體結構分為兩個層級,第一層級描述了特效的基本信息,第二層級用節點樹描述了特效的實現細節。
特效基本信息-第一層級
特效的基本信息包含以下字段:
字段 | 說明 |
name | 特效名稱。 |
module | 模塊標識,該字段必須是 |
version | 版本號,當前版本為1。 |
type | 特效類型,1表示濾鏡,2表示轉場。 |
nodeTree | 節點樹,用于描述特效的實現細節,詳細內容請參見節點樹-第二層級。 |
以特效Intense濾鏡的配置文件為例,示例如下:
{
"name": "Intense",
"module": "ALIVC_GECF",
"version": 1,
"type": 1,
"nodeTree": [
{
"nodeId": 0,
"name": "Intense",
"fragment": "/** ...... */",
"textures": [
{
"name": "inputImageTexture",
"srcType": "INPUT_NODE",
"nodeId": 0
},
{
"name": "inputImageTexture2",
"srcType": "IMAGE",
"path": "color.png"
}
]
}
]
}
節點樹-第二層級
節點樹nodeTree
用于描述一個渲染流程,包含了一個或多個節點。
在短視頻SDK中,渲染流程如圖所示:
據上圖所示,渲染過程被抽象為一系列節點組成的樹狀結構。
輸入節點INPUT_NODE代表原始輸入源。在錄制場景下,輸入節點是攝像頭采集的圖像數據流。在編輯場景下,輸入節點是當前播放視頻流。在設計上,輸入節點可以是多個。例如轉場過程中,需要對前后兩個視頻做效果變換。此時,前一個視頻是INPUT_NODE0,后一個是INPUT_NODE1。
中間的節點樹部分即對應配置文件中的
nodeTree
字段。一個節點樹可以包含一個或多個渲染節點。可以看到,整個渲染配置文件的關鍵就是有關節點的配置。輸出節點OUTPUT_NODE代表渲染后的視頻流。在預覽模式下,輸出節點輸出到屏幕。在合成模式下,輸出節點輸出到編碼器編碼。
節點
節點字段描述了整個渲染流程中,某一次繪制過程中的相關配置,這里的配置包含了自定義特效所必須的著色器代碼以及相關參數描述。 節點包含以下字段:
字段 | 說明 |
nodeId | 節點id,用于標識當前節點。 |
name | 節點名稱。 |
vertex | 頂點著色器代碼。 該字段作用與vertexPath字段相同,聲明其中任意一個即可。 該字段可以不寫,如果不填寫,SDK會提供默認實現如下:
|
vertexPath | 頂點著色器代碼所在文件路徑。 該字段作用與vertex字段相同,聲明其中任意一個即可。 |
attributes | attributes列表,該字段用于聲明頂點著色中attribute參數名name和類型type。 type取值為:POSITION,頂點坐標;TEXTURECOORD,紋理坐標。 該字段可以不填寫,如果不填寫,SDK會提供默認實現如下:
|
fragment | 片段著色器代碼。 該字段作用與fragmentPath字段相同,聲明其中任意一個即可。 |
fragmentPath | 片段著色器代碼所在文件路徑。 該字段作用與fragment字段相同,聲明其中任意一個即可。 |
textures | 紋理列表。用于描述片段著色器中
|
params | 參數列表。用于描述片段著色器中
|
params參數類型(type) 支持的類型
類型 | 參數取值示例 |
INT | [1] |
FLOAT | [-2.0] |
VEC2I | [3, 2] |
VEC3I | [1, 2, 3] |
VEC4I | [4, 3, 2, 1] |
VEC2F | [-1.0, 1.0] |
VEC3F | [0.5, 0.5, 0.5] |
VEC4F | [1.0, -1.0, 1.0, -1.0] |
MAT3F | [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] |
MAT4F | [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0] |
以特效Translate轉場的配置文件為例,示例如下:
{
"name": "Translate",
"module": "ALIVC_GECF",
"version": 1,
"type": 2,
"nodeTree": [
{
"nodeId": 0,
"name": "Translate",
"vertex": "/** ...... */",
"attributes": [
{
"name": "a_position",
"type": "POSITION"
},
{
"name": "a_texcoord",
"type": "TEXTURECOORD"
}
],
"fragment": "/** ...... */",
"textures": [
{
"name": "RACE_Tex0",
"srcType": "INPUT_NODE",
"nodeId": 0
},
{
"name": "RACE_Tex1",
"srcType": "INPUT_NODE",
"nodeId": 1
}
],
"params": [
{
"name": "direction",
"type": "INT",
"value": [
0
],
"maxValue": [
3
],
"minValue": [
0
]
}
]
}
]
}
內建變量
SDK中內置了一些變量,您可以在shader中直接聲明,目前有以下內建變量:
uniform highp float BUILTIN_PROGRESS; // 轉場進度:0~1
uniform highp float BUILTIN_WIDTH; // 圖像寬
uniform highp float BUILTIN_HEIGHT; // 圖像高
在短視頻SDK中使用特效
使用特效通常需要先創建特效對象,再應用特效,最后按需更新特效參數。
初始化后的特效對象內可以獲取到描述特效配置的AliyunEffectConfig
對象,該對象內部結構與特效配置文件的結構相對應。 如果某一個自定義特效配置文件里包含有params字段
,對應在代碼中可以通過AliyunEffectConfig
->nodeTree
->params
獲取到AliyunParam
對象。AliyunParam
對象中的value
字段就是當前參數的值。更新特效參數需要以下兩步:
通過
AliyunValue
對象提供的update設值方法更新參數值。調用特效更新方法更新參數。具體特效更新方法請參見如下操作步驟中的第三步更新特效參數。
Android操作步驟
濾鏡
調用
EffectFilter(String path)
方法創建特效對象,path
參數為特效文件夾路徑。調用
int addAnimationFilter(EffectFilter filter);
方法應用濾鏡特效。調用
int updateAnimationFilter(EffectFilter filter);
方法更新濾鏡特效參數。
轉場
調用
TransitionBase(String path)
創建特效對象,path
參數為特效文件夾路徑。調用
int setTransition(int index, TransitionBase transition);
方法應用轉場特效。調用
int updateTransition(int clipIndex, TransitionBase transitionBase);
方法更新轉場特效參數。
iOS操作步驟
濾鏡
調用
AliyunEffectFilter
的- (instancetype)initWithFile:(NSString *)path;
方法創建特效對象,path
參數為特效文件夾路徑。調用
- (int)applyAnimationFilter:(AliyunEffectFilter *)filter;
方法應用濾鏡特效。調用
- (int)updateAnimationFilter:(AliyunEffectFilter *)filter;
方法更新濾鏡特效參數。
轉場
調用
AliyunTransitionEffect
的-(instancetype)initWithPath:(NSString *)path;
方法創建特效對象,path
參數為特效文件夾路徑。調用
- (int)applyTransition:(AliyunTransitionEffect *)transition atIndex:(int)clipIdx;
方法應用轉場特效。調用
-(int)updateTransition:(AliyunTransitionEffect *)transition atIndex:(int)clipIdx;
方法更新轉場特效參數。