Parsing AEP Files
AfterEffects Project files are the proprietary file format used by Adobe AfterEffects.
It's a binary format based on the RIFX container format.
The structure resembles that of a Lottie JSON exported from AE.
RIFF
A RIFF is composed of "chunks" with the following format
Field | Size | Description |
---|---|---|
Header | 4 | ASCII name describing the type of the chunk |
Size | 4 | uint32 size of the data section |
Data | Size | Data within the chunk |
RIFX
is an extension of the RIFF
format, the difference being RIFX
uses big-endian notation for integers.
A RIFF file will be structured in the same way as a chunk:
Field | Size | Description |
---|---|---|
Header | 4 | RIFF or RIFX |
Size | 4 | uint32 size of the chunk |
Format | 4 | Format Identifier |
Chunks | * | Rest of the chunks |
AEP-Specific Parsing
It should always be RIFX
format (big endian). The format identifier
for AEP is Egg!
.
When parsing the RIFF structure, keep in mind the following chunks will contain other chunks:
And that LIST
btdk
contains data in a different format, and
it should not be parsed as a RIFF LIST
.
At the end of the RIFF data, the AEP file has some XML-encoded metadata.
Basic Types
In the chunk data descriptions, the types described below will be used to show how to interpret the raw binary data.
Type | Size | Description |
---|---|---|
id |
4 | ASCII-encoded chunk identifier |
uint16 |
2 | Unsigned integer |
uint32 |
4 | Unsigned integer |
sint16 |
2 | Twos-complement signed integer |
float32 |
4 | IEEE float |
float64 |
8 | IEEE float |
string |
* | Text, usually utf-8 encoded |
string0 |
* | NUL terminated string, note that you might find junk data after the NUL (This can be caused by renaming something to a shorter name) |
bytes |
* | Unformatted / unknown data |
Time
Time values are stored as uint16
. they are scaled by a factor you can find in cdta
.
To get the actual value in frames you need to do the following:
time_frames = time_value / cdta.time_scale
Additionally, layers specify a start time, which shifts all the time values by a fixed amount.
If you are within a layer the expression looks like this:
time_frames = (time_value + ldta.start_time) / (cdta.time_scale)
Flags
Flags is byte data, that will be specified using two integers: byte and bit index.
You'll get the value of the flag you'll need to do the following:
flag = (flags[byte] & (1 << bit)) != 0
The index of the byte here is in file order so a byte
of 0 is the most significant byte.
AfterEffects Logic
This section assumes the file has already been parsed into RIFF chunks.
Objects described here will have a nested list showing which chunks are used to represent them, you can click on the link pointing to the chunk details to get the data layout within that chunk.
File Structure
LIST
EfdG
: Effect definitionsLIST
ExEn
Utf8
: Language used in expressions (eg:javascript-1.0
)
LIST
Fold
: Root folderLIST
Item
: Folder item (repeated, see below)
Folder Item
idta
will cointain the ID of the item (referenced by layers)
and the item type.
The following sections descript each type of item in detail
Folders
idta
type 1
. These contain additional items inside them.
Compositions
idta
has type of 4
. You need to know which composition to extract as
a lottie corresponds to a specific comp (with other compositions showing
as assets for precomps).
Structure:
Each layer will show as a LIST
Layr
in the LIST
Item
.
The composition will also have other type of layer LIST
s:
LIST
DLay
: Default viewLIST
CLay
: Custom viewsLIST
SLay
: Side viewsLIST
SecL
: Composition markers layer
If the comp uses essential graphics, it will have the appropriate LIST
s as well.
Assets
idta
type 7
. These can have different kinds of contents.
Look for sspc
to get the size for visual assets.
The type of asset is defined in the first 4 bytes of opti
.
Solids
For some the Item
has an Utf8
but it seems to always be empty
need to find the name from opti
.
Files
The Uft8
in Item
only has a value if the user has set an explicit value for the name.
The file path is in alas
, parse it as JSON and get fullpath
.
the first 4 bytes of opti
will change based on the file format.
Layers
LIST
Layr
: Layerldta
: Common layer data, including layer type.Utf8
: Namecmta
: (optional) CommentLIST
tdgp
: Property group
When parsing layer transforms, keep in mind the default position is the center of the comp. For shape layers, the default anchor is [0, 0]; for precomp layers the default anchor is the center of the comp (same as position).
Asset Layer
Layer type 0
.
(Also known as AVLayer in AE) They have a non-zero Source ID in ldta
.
Precomp, image, and similar layers will point to an appropriate asset.
Several layer types point to a solid asset, you need to check the layer attributes to distinguish between them:
- Solid layers
- Null layers
- Adjustment layers
Light Layer
Layer type 1
.
For light settings look for the match name ADBE Light Options Group
.
Camera Layer
Layer type 2
.
For camera settings look for the match name ADBE Camera Options Group
.
Text Layer
Layer type 3
.
For text contents look for the match name ADBE Text Properties
.
Shape Layer
Layer type 4
.
For shapes look for the match name ADBE Root Vectors Group
.
Property Groups
Most objects are described as a property groups.
These have the following structure:
LIST
tdgp
: Property group
Then follows a list of properties, all introduced by their
match name (tdmn
).
After a match name, you'll find the data for the property, which might be an actual propert (see the section below), other groups, or layer effects.
This structure is used both for objects (that have a fixed set of properties) and groups/collections whose contents might vary.
For objects with fixed properties you will not find duplicate match names but you might find duplicates within collections.
Properties
Properties, like objects are introduced by their match name, the chunks following that depends on the type of property.
The core of a property is defined in LIST
tdbs
with the following structure:
LIST
tdbs
: Property definition
For simple properties, with vector or scalar values, you get the structure above.
For more complex properties, you get an outer object that contains that data as well as a list of values. You'll get the value for the keyframes (or the static value) from that list.
Color properties are laid out as ARGB floats in [0, 255].
Note that the keyframe structure in ldat
changes based on the info found in tdb4
.
Shape
Gradient Colors
LIST
GCst
LIST
tdbs
: Property definitionLIST
GCky
: Keyframe valuesUtf8
Gradient XML (repeated)
Orientation
Marker
Text Document
Layer
Follows the usual LIST
tdbs
, check tdb4
for the "Integer" property type.
Mask Index
Follows the usual LIST
tdbs
, check tdb4
for the "Integer" property type.
Mask
Layer Overrides
LIST OvG2
CprC
:uint32
?
Layer Source Alternate
blsv
:uint32
Layer index?blsi
:uint32
Chunk naming
Most of property related chunks seem to contain the prefix td
in their name:
tdgp
: property grouptdsb
: property group flagstdsn
: property group nametdmn
: property match nametdbs
: property definitiontdb4
: property details
I'm not sure what td
stands for my best guess would be "Track Data".
For properties with external values, the naming convention generally is XXst
for the parent chunk
and XXky
for the values (where XX
changes depending on the type and its meaning is fairly obvious).
I'm not sure what st
stands for, ky
most likely stands for "keyframes"
Expressions
Bodymovin modifies expressions when converting into lottie, if you add expressions but fail to convert them, the animation might not play properly.
Assets
Image
Defined within LIST
Item
, it will have idta
with type 7
.
Within that there's a LIST
Pin
, containing the following:
LIST
Als2
with alas
, which in turn has some JSON.
Inside the JSON you can get fullpath
.
opti
: Contains the asset name.
LIST
CLRS
, the last Utf8
here has some JSON with a base64-encoded color profile.
Shapes
Stroke Dashes
Look for the match name ADBE Vector Stroke Dashes
.
Inside of it you'll find a bunch of properties with match name
ADBE Vector Stroke Dash n
or ADBE Vector Stroke Gap n
, where n
is
an ineger starting from 1.
You will also find a single ADBE Vector Stroke Offset
.
They are all animatable lengths and fairly straighforward.
Note that lottie-web wants a unique "name" for these, and the file doesn't provide this but you can generate one based on the match name.
Transforms
Split Position
When a position is split the Position attribute is removed and you can get the data from Position_0 and Position_1.
For some reason Position_0 and Position_1 are present (with value 0
) even when the position is not split.
Their tdsb
seems to change from 1
(not split) to 3
(split).
Effects
The effects used in by the file are defined in the top-level chunk LIST
EfdG
, instanciations of these effects
are present in the layers that use them.
LIST
EfdG
: Effect definitions
Note that the first paramter in an effect should be ignored.
The effects in a later are listed under ADBE Effect Parade
:
Essential Graphics
Definition
Essential graphics are defined in the following chunks inside the comp's LIST
Item
:
They seem to have the same structure and (almost) identical values. But only CIF3
has data about groups:
Items have the following common structure
Comment
Group
Property
CVal
: ValueCDef
: Default ValueSmin
: Slider min value (only for scalar properties)Smax
: Slider max value (only for scalar properties)CDim
: Number of dimenstions (only for vector properties)LIST
StVc
: Enum values (only for enum properties)CprC
:1
LIST
CPrp
The JSON is a dict where the key is a string containing a number and the values are dicts like this:
index
: Index for like shape groups and such, or the value4294967295
(0xffffffff
) is used when there is no indexmatchName
: Match name as per usual
To find the property, something like this might work:
CCId = 15
CLId = 18
json_data = {
"0": {
"index":4294967295,
"matchName":"ADBE Root Vectors Group"
},
"1": {
"index":0,
"matchName":"ADBE Vector Group"
},
"2": {
"index":4294967295,
"matchName":"ADBE Vectors Group"
},
"3": {
"index":2,
"matchName":"ADBE Vector Graphic - Fill"
},
"4": {
"index":4294967295,
"matchName":"ADBE Vector Fill Opacity"
}
}
property = get_layer(CCId, CLId)
for item in json_data.values():
if item["index"] == 0xffffffff:
property = property.property(item["matchName"])
else:
property = property.properties[item["index"]]
The values in Smin
, Smax
, CVal
, CDef
depends on the type, refer to CTyp
for their representation.
Overrides
Defined in the precomp layer under match name ADBE Layer Overrides
tdmn
:ADBE Layer Overrides
LIST
OvG2
LIST
tdgp
: Property groups with the matching properties defined as usual.
Match Names
Follows a list of known match names grouped by object type.
For properties that specify a default value, you should assume they have the specified value if they are not present in the AEP file.
Layers
Match Name | Description | Default |
---|---|---|
ADBE Root Vectors Group |
shapes |
|
ADBE Layer Styles |
styles |
|
ADBE Transform Group |
ks |
|
ADBE Layer Styles |
sy |
|
ADBE Extrsn Options Group |
||
ADBE Material Options Group |
||
ADBE Audio Group |
||
ADBE Layer Sets |
||
ADBE Time Remapping |
tm |
|
ADBE Effect Parade |
ef |
|
ADBE Marker |
Markers | |
ADBE Mask Parade |
masksProperties |
|
ADBE Plane Options Group |
||
ADBE Data Group |
||
ADBE Layer Overrides |
Essential graphincs values | |
ADBE Source Options Group |
Match Name | Description | Default |
---|---|---|
ADBE Camera Options Group |
Camera Layer | Marks a layer as a camera layer |
ADBE Camera Aperture |
pe |
|
ADBE Camera Zoom |
||
ADBE Camera Focus Distance |
Match Name | Description | Default |
---|---|---|
ADBE Mask Atom |
Mask | |
ADBE Mask Shape |
pt |
|
ADBE Mask Offset |
x |
0 |
ADBE Mask Feather |
[0, 0] | |
ADBE Mask Opacity |
0 |
100 |
Match Name | Description | Default |
---|---|---|
ADBE Extrsn Options Group |
||
ADBE Bevel Direction |
Match Name | Description | Default |
---|---|---|
ADBE Material Options Group |
||
ADBE Appears in Reflections |
||
ADBE Reflection Coefficient |
||
ADBE Glossiness Coefficient |
||
ADBE Fresnel Coefficient |
||
ADBE Transparency Coefficient |
||
ADBE Transp Rolloff |
||
ADBE Index of Refraction |
Match Name | Description | Default |
---|---|---|
ADBE Source Options Group |
||
ADBE Layer Source Alternate |
Match Name | Description | Default |
---|---|---|
ADBE Layer Styles |
||
ADBE Blend Options Group |
Match Name | Description | Default |
---|---|---|
ADBE Blend Options Group |
||
ADBE Adv Blend Group |
Shapes
Match Name | Description | Default |
---|---|---|
ADBE Vector Group |
Group | |
ADBE Vector Blend Mode |
bm 12 |
|
ADBE Vectors Group |
it |
|
ADBE Vector Transform Group |
Transform | |
ADBE Vector Materials Group |
Match Name | Description | Default |
---|---|---|
ADBE Vector Shape - Rect |
Rectangle | |
ADBE Vector Shape Direction |
d 1 |
|
ADBE Vector Rect Position |
p |
|
ADBE Vector Rect Size |
s |
|
ADBE Vector Rect Roundness |
r |
Match Name | Description | Default |
---|---|---|
ADBE Vector Shape - Ellipse |
Ellipse | |
ADBE Vector Shape Direction |
d 1 |
|
ADBE Vector Ellipse Position |
p |
|
ADBE Vector Ellipse Size |
s |
Match Name | Description | Default |
---|---|---|
ADBE Vector Shape - Star |
PolyStar | |
ADBE Vector Shape Direction |
d 1 |
|
ADBE Vector Star Type |
sy 1 |
|
ADBE Vector Star Points |
pt 3 |
|
ADBE Vector Star Position |
p |
|
ADBE Vector Star Rotation |
r |
|
ADBE Vector Star Inner Radius |
ir |
|
ADBE Vector Star Outer Radius |
or |
|
ADBE Vector Star Inner Roundess |
is |
|
ADBE Vector Star Outer Roundess |
os |
Match Name | Description | Default |
---|---|---|
ADBE Vector Shape - Group |
Path | |
ADBE Vector Shape Direction |
d 1 |
|
ADBE Vector Shape |
ks 4 |
Shape Styles
Match Name | Description | Default |
---|---|---|
ADBE Vector Graphic - Fill |
Fill | |
ADBE Vector Blend Mode |
bm 12 |
|
ADBE Vector Fill Color |
c 5 |
[255, 255, 0, 0] |
ADBE Vector Fill Opacity |
o |
100 |
ADBE Vector Fill Rule |
r 1 |
1 |
ADBE Vector Composite Order |
if 2, it should be drawn over the previous shape | 1 |
Match Name | Description | Default |
---|---|---|
ADBE Vector Graphic - Stroke |
Stroke | |
ADBE Vector Blend Mode |
bm 12 |
|
ADBE Vector Stroke Color |
c 5 |
[255, 255, 255, 255, ] |
ADBE Vector Stroke Opacity |
o |
100 |
ADBE Vector Stroke Width |
w |
2 |
ADBE Vector Stroke Line Cap |
lc 1 |
1 |
ADBE Vector Stroke Line Join |
lj 1 |
1 |
ADBE Vector Stroke Miter Limit |
ml2 |
4 |
ADBE Vector Stroke Dashes |
d |
|
ADBE Vector Stroke Taper |
||
ADBE Vector Stroke Wave |
||
ADBE Vector Composite Order |
if 2, it should be drawn over the previous shape | 1 |
Match Name | Description | Default |
---|---|---|
ADBE Vector Stroke Taper |
All properties are percentages in [0, 100] | |
ADBE Vector Taper Start Length |
||
ADBE Vector Taper End Length |
||
ADBE Vector Taper Start Width |
||
ADBE Vector Taper End Width |
||
ADBE Vector Taper Start Ease |
||
ADBE Vector Taper End Ease |
Match Name | Description | Default |
---|---|---|
ADBE Vector Stroke Wave |
||
ADBE Vector Taper Wave Amount |
||
ADBE Vector Taper Wave Units |
1 for pixels, 2 for cycles | |
ADBE Vector Taper Wavelength |
||
ADBE Vector Taper Wave Phase |
Match Name | Description | Default |
---|---|---|
ADBE Vector Stroke Dashes |
||
ADBE Vector Stroke Offset |
||
ADBE Vector Stroke Gap # |
||
ADBE Vector Stroke Dash # |
Match Name | Description | Default |
---|---|---|
ADBE Vector Graphic - G-Fill |
Gradient Fill | |
ADBE Vector Blend Mode |
bm 12 |
|
ADBE Vector Grad Type |
t 1 |
|
ADBE Vector Grad Start Pt |
s |
|
ADBE Vector Grad End Pt |
e |
[100, 0] |
ADBE Vector Grad HiLite Length |
h |
|
ADBE Vector Grad HiLite Angle |
a |
|
ADBE Vector Grad Colors |
g 6 |
|
ADBE Vector Fill Opacity |
o |
100 |
ADBE Vector Fill Rule |
r 1 |
1 |
ADBE Vector Composite Order |
if 2, it should be drawn over the previous shape | 1 |
Match Name | Description | Default |
---|---|---|
ADBE Vector Graphic - G-Stroke |
Gradient Stroke | |
ADBE Vector Blend Mode |
bm 12 |
|
ADBE Vector Grad Type |
t 1 |
|
ADBE Vector Grad Start Pt |
s |
|
ADBE Vector Grad End Pt |
e |
|
ADBE Vector Grad HiLite Length |
h |
|
ADBE Vector Grad HiLite Angle |
a |
|
ADBE Vector Grad Colors |
g 6 |
|
ADBE Vector Stroke Opacity |
o |
100 |
ADBE Vector Stroke Width |
w |
2 |
ADBE Vector Stroke Line Cap |
lc 1 |
1 |
ADBE Vector Stroke Line Join |
lj 1 |
1 |
ADBE Vector Stroke Miter Limit |
ml2 |
|
ADBE Vector Stroke Dashes |
d |
|
ADBE Vector Stroke Taper |
||
ADBE Vector Stroke Wave |
||
ADBE Vector Composite Order |
if 2, it should be drawn over the previous shape | 1 |
Shape Modifiers
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - Merge |
Merge | |
ADBE Vector Merge Type |
mm |
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - Offset |
Offset Path | |
ADBE Vector Offset Amount |
a |
|
ADBE Vector Offset Line Join |
lj 1 |
|
ADBE Vector Offset Miter Limit |
ml |
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - PB |
Pucker Bloat | |
ADBE Vector PuckerBloat Amount |
a |
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - Repeater |
Repeater | |
ADBE Vector Repeater Transform |
tr |
|
ADBE Vector Repeater Copies |
c 3 |
|
ADBE Vector Repeater Offset |
o |
|
ADBE Vector Repeater Order |
m 1 |
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - RC |
Rounded Corners | |
ADBE Vector RoundCorner Radius |
r |
10 |
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - Trim |
Trim | |
ADBE Vector Trim Start |
s |
|
ADBE Vector Trim End |
e |
|
ADBE Vector Trim Offset |
o |
|
ADBE Vector Trim Type |
m 1 |
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - Twist |
Twist | |
ADBE Vector Twist Angle |
a |
|
ADBE Vector Twist Center |
c |
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - Roughen |
||
ADBE Vector Roughen Size |
||
ADBE Vector Roughen Detail |
||
ADBE Vector Roughen Points |
||
ADBE Vector Temporal Freq |
||
ADBE Vector Correlation |
||
ADBE Vector Temporal Phase |
||
ADBE Vector Spatial Phase |
||
ADBE Vector Random Seed |
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - Wiggler |
||
ADBE Vector Xform Temporal Freq |
||
ADBE Vector Correlation |
||
ADBE Vector Temporal Phase |
||
ADBE Vector Spatial Phase |
||
ADBE Vector Random Seed |
||
ADBE Vector Wiggler Transform |
Match Name | Description | Default |
---|---|---|
ADBE Vector Filter - Zigzag |
Zig Zag | |
ADBE Vector Zigzag Size |
s |
10 |
ADBE Vector Zigzag Detail |
r |
5 |
ADBE Vector Zigzag Points |
pt 1 |
Transforms
Match Name | Description | Default |
---|---|---|
ADBE Transform Group |
Transform | |
ADBE Anchor Point |
a 8 |
[0, 0] |
ADBE Position |
p |
Half of the comp size |
ADBE Position_0 |
Split position X | |
ADBE Position_1 |
Split position Y | |
ADBE Position_2 |
Split position Z | |
ADBE Scale |
s 7 |
[1, 1] |
ADBE Orientation |
or |
|
ADBE Rotate X |
rx |
|
ADBE Rotate Y |
ry |
|
ADBE Rotate Z |
rz or just normal rotation |
0 |
ADBE Opacity |
o 7 |
1 |
ADBE Envir Appear in Reflect |
Single float, probably a boolean? |
Match Name | Description | Default |
---|---|---|
ADBE Vector Transform Group |
Transform Shape | |
ADBE Vector Anchor Point |
a |
|
ADBE Vector Anchor |
a |
probably an outdated name |
ADBE Vector Position |
p |
|
ADBE Vector Scale |
s |
[100, 100] |
ADBE Vector Rotate X |
rx |
|
ADBE Vector Rotate Y |
ry |
|
ADBE Vector Rotate Z |
rz or just normal rotation |
|
ADBE Vector Rotation |
r |
|
ADBE Vector Skew |
sk |
|
ADBE Vector Skew Axis |
sa |
|
ADBE Vector Group Opacity |
o |
100 |
Match Name | Description | Default |
---|---|---|
ADBE Vector Repeater Transform |
Repeater Transform | |
ADBE Vector Repeater Anchor Point |
a |
|
ADBE Vector Repeater Position |
p |
|
ADBE Vector Repeater Scale |
s 7 |
|
ADBE Vector Repeater Rotation |
r |
|
ADBE Vector Repeater Start Opacity |
so 7 |
1 |
ADBE Vector Repeater End Opacity |
so 7 |
1 |
Effects
Match Name | Description | Default |
---|---|---|
ADBE Tint |
Tint Effect | ty =20 |
ADBE Fill |
Fill Effect | ty =21 |
ADBE Stroke |
Stroke Effect | ty =22 |
ADBE Tritone |
Tritone Effect | ty =23 |
ADBE Pro Levels2 |
Pro Levels Effect | ty =24 |
ADBE Drop Shadow |
Drop Shadow Effect | ty =25 |
ADBE Radial Wipe |
Radial Wipe | ty =26 |
ADBE Displacement Map |
Displacement Map Effect | ty =27 |
ADBE Set Matte3 |
Set Matte Effect | ty =28 |
ADBE Gaussian Blur 2 |
Gaussian Blur Effect | ty =29 |
ADBE Twirl |
Twirl Effect | ty =30 |
ADBE MESH WARP |
Mesh Warp Effect | ty =31 |
ADBE Ripple |
Wavy Effect | ty =32 |
ADBE Spherize |
Spherize Effect | ty =33 |
ADBE FreePin3 |
Puppet Effect | ty =34 |
Match Name | Description | Default |
---|---|---|
ADBE Effect Built In Params |
Marks a LIST tdgp with built-in effect properties |
|
ADBE Effect Mask Opacity |
Match Name | Description | Default |
---|---|---|
ADBE Paint Group |
Data for the paint effect | |
ADBE Paint Atom |
Contains the following properties | |
ADBE Paint Duration |
||
ADBE Paint Shape |
||
ADBE Paint Transform |
Same as other transform but match names starting with ADBE Paint |
|
ADBE Paint Properties |
contains the following | |
ADBE Paint Clone Layer |
Text
Match Name | Description | Default |
---|---|---|
ADBE Text Properties |
Text Data | |
ADBE Text Document |
d |
|
ADBE Text Path Options |
p |
|
ADBE Text More Options |
m |
|
ADBE Text Animators |
a |
Match Name | Description | Default |
---|---|---|
ADBE Text Animator |
Text Range | |
ADBE Text Selectors |
s (list) |
|
ADBE Text Animator Properties |
a |
Match Name | Description | Default |
---|---|---|
ADBE Text Selector |
Text Range Selector | |
ADBE Text Percent Start |
s |
0 |
ADBE Text Percent End |
e |
100 |
ADBE Text Percent Offset |
o |
0 |
ADBE Text Index Start |
s |
|
ADBE Text Index End |
e |
|
ADBE Text Index Offset |
o |
|
ADBE Text Range Advanced |
||
ADBE Text Selector Max Amount |
a |
|
ADBE Text Selector Smoothness |
sm |
|
ADBE Text Levels Max Ease |
xe |
|
ADBE Text Levels Min Ease |
ne |
|
ADBE Text Random Seed |
rn |
Match Name | Description | Default |
---|---|---|
ADBE Text Animator Properties |
Text Style | |
ADBE Text Anchor Point 3D |
a |
|
ADBE Text Position 3D |
p |
|
ADBE Text Scale 3D |
s |
|
ADBE Text Skew |
sk |
|
ADBE Text Skew Axis |
sa |
|
ADBE Text Rotation X |
rx |
|
ADBE Text Rotation Y |
ry |
|
ADBE Text Rotation |
r |
|
ADBE Text Opacity |
o |
|
ADBE Text Fill Color |
fc |
|
ADBE Text Fill Opacity |
fo |
|
ADBE Text Fill Hue |
fh |
|
ADBE Text Fill Saturation |
fs |
|
ADBE Text Fill Brightness |
fb |
|
ADBE Text Stroke Color |
sc |
|
ADBE Text Stroke Opacity |
so |
|
ADBE Text Stroke Hue |
sh |
|
ADBE Text Stroke Saturation |
ss |
|
ADBE Text Stroke Brightness |
sb |
|
ADBE Text Stroke Width |
sw |
|
ADBE Text Line Spacing |
ls |
|
ADBE Text Line Anchor |
||
ADBE Text Track Type |
||
ADBE Text Tracking Amount |
||
ADBE Text Character Replace |
||
ADBE Text Character Offset |
||
ADBE Text Blur |
Match Name | Description | Default |
---|---|---|
ADBE Text Path Options |
Text Follow Path | |
ADBE Text Path |
m |
|
ADBE Text Reverse Path |
r |
|
ADBE Text Perpendicular To Path |
p |
|
ADBE Text Force Align Path |
a |
|
ADBE Text First Margin |
f |
|
ADBE Text Last Margin |
l |
Match Name | Description | Default |
---|---|---|
ADBE Text More Options |
Text Alignment Options | |
ADBE Text Anchor Point Option |
g |
1 |
ADBE Text Anchor Point Align |
a |
[0, 0] |
ADBE Text Render Order |
1 | |
ADBE Text Character Blend Mode |
1 |
Misc
Match Name | Description | Default |
---|---|---|
ADBE Group End |
Indicates the end of a LIST tdgp |
Notes
-
Enumerations needs to be converted from floats, but the values match. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
Blend mode has different values than Lottie, see the section below for details. ↩↩↩↩↩
-
How to parse this? ↩
-
For asset layers, the anchor point is relative to the size of the asset (eg:
(0.5, 0.5)
would be the center). ↩
Enumerations
Most enumerated values are the same in Lottie and AEP, this section lists the exceptions to this and enums not in lottie
Blend Mode
Name | AEP | Lottie |
---|---|---|
Normal | 1 | 0 |
Darken | 3 | 4 |
Multiply | 4 | 1 |
Color Burn | 5 | 7 |
Linear Burn | 6 | |
Darker Color | 7 | |
Lighten | 9 | 5 |
Screen | 10 | 2 |
Color Dodge | 11 | 6 |
Linear Dodge | 12 | |
Lighter Color | 13 | |
Overlay | 15 | 3 |
Soft Light | 16 | 9 |
Hard Light | 17 | 8 |
Linear Light | 18 | |
Vivid Light | 19 | |
Pin Light | 20 | |
Hard Mix | 21 | 16 |
Difference | 23 | 10 |
Exclusion | 24 | 11 |
Hue | 26 | 12 |
Saturation | 27 | 13 |
Color | 28 | 14 |
Luminosity | 29 | 15 |
Label Colors
Value | Name | Default Color |
---|---|---|
0 | None | (shows as grey) |
1 | Red | #b4393b |
2 | Yellow | #e2d759 |
3 | Aqua | #abcbc8 |
4 | Pink | #e5bcca |
5 | Lavender | #a9aac9 |
6 | Peach | #e5c19f |
7 | Sea Foam | #b4c7b4 |
8 | Blue | #687fdd |
9 | Green | #4ea350 |
10 | Purple | #8d3299 |
11 | Orange | #e79228 |
12 | Brown | #7e442c |
13 | Fuchsia | #f371d5 |
14 | Cyan | #43a2a4 |
15 | Sandstone | #a7967a |
16 | Dark Green | #203f1f |
Text Render Oder
- Per character palette
- Fills over strokes
- Strokes over fills
Chunk Data
Note that chunks might have extra data after what is described here, always parse exactly as many bytes as specified in the chunk header.
LIST
This chunk is defined by the RIFF specs, its data has the following format:
Starts with an id
, specifying the type of the list, then followed by sub-chunks.
The format of specific LIST
types are described later in this document.
Note that the LIST
btdk
doesn't conform to RIFF,
so take care to not read over the chunk length.
Utf8
Contains utf-8 encoded text. Sometimes it contains the string -_0_/-
which (I guess)
is used as a placeholder for objects lacking a name.
tdsn
/ fnam
/ pdnm
Contains a Utf8
chunk, used for object names
tdmn
Contains a NUL-terminated string (You'll need to strip excess \0
) and defines a Match Name.
cmta
Comment, NUL-terminated string. The size seems to be variable but rounded to 4 bytes.
fdta
Folder data.
cdta
Composition data.
Field Name | Size | Type | Description |
---|---|---|---|
X Resolution | 2 | uint16 |
|
Y Resolution | 2 | uint16 |
|
1 | |||
Time Scale | 2 | uint16 |
How much Time values are scaled by |
14 | |||
Playhead | 2 | Time | Playhead time |
6 | |||
In Time | 2 | Time | Same as ip in Lottie |
6 | |||
Out Time | 2 | Time | Same as op in Lottie |
6 | |||
Comp duration | 2 | Time | Duration setting in AE |
5 | |||
Color | 3 | bytes |
Color as 24 bit RGB |
84 | |||
Attributes | 1 | Flags | |
Width | 2 | uint16 |
Same as w in Lottie |
Height | 2 | uint16 |
Same as h in Lottie |
Pixel Ratio Width | 4 | uint32 |
|
Pixel Ratio Height | 4 | uint32 |
|
12 | |||
Framerate | 2 | uint16 |
Same as fr in Lottie |
16 | |||
Shutter Angle | 2 | uint16 |
|
Shutter Phase | 4 | sint16 |
|
16 | |||
Samples Limit | 4 | sint16 |
|
Samples per frame | 4 | sint16 |
Note that End Time might have a value of FFFF, if that's the case assume it to be the same as Comp Duration.
The X/Y resolution represent a divisor of the size in that direction used for rendering. For example a X Resolution of 5, with a width of 500 will yield an output of 100px.
The pixel ratio is represented as a fraction of width/height, if both values are 1 you get square pixels.
Attributes:
- Shy: (0, 0): Hides Shy layers from the timeline
- Motion Blur: (0, 3): Allows layers to enable motion blur
- Frame Blending: (0, 4): Allows layers to enable frame blending
- Preserve Framerate: (0, 5): Something about nested render queues
- Preserve Resolution: (0, 7): Something about nested render queues
ldta
Layer data, it seems that AE23 adds 4 extra 00
bytes at the end compared to older versions.
Field Name | Size | Type | Description |
---|---|---|---|
Layer ID | 4 | uint32 |
|
Quality | 2 | uint16 |
0 : Wireframe, 1 : Draft, 2 : Best |
4 | |||
Stretch Numerator | 2 | uint16 |
|
1 | |||
Start Time | 2 | sint16 |
Time offset for times withing the layer |
6 | |||
In Time | 2 | Time | Same as ip in Lottie |
6 | |||
Out Time | 2 | Time | Same as op in Lottie |
6 | |||
Attributes | 3 | Flags | |
Source ID | 4 | uint32 |
Item id for the used asset |
17 | |||
Label Color Index | 1 | uint8 |
Label Colors |
2 | |||
Layer Name | 32 | string0 |
It's repeated in the Utf8 chunk right after |
11 | |||
Matte Mode | 1 | uint8 |
|
2 | |||
Stretch Denominator | 2 | uint16 |
|
19 | |||
Layer Type | 1 | uint8 |
|
Parent ID | 4 | uint32 |
ID of the parent layer, if any |
24 | |||
Matte Layer ID | 4 | uint32 |
Id of the layer masking the current layer, if any (only for AE >= 23) |
With the following Attributes:
- Guide: (0, 1) Guide layers aren't rendered
- Bicubic Sampling: (0, 6)
- Auto Orient: (1, 0)
- Adjustment: (1, 1) Whether it's an adjustment layer
- Threedimensional: (1, 2)
- Solo: (1, 3) (UI thing, only displays that layer)
- Null: (1, 7) Whether it's a null layer
- Visible: (2, 0)
- Effects: (2, 2)
- Motion Blur: (2, 3)
- Locked: (2, 5)
- Shy: (2, 6) (Used to hide some layers in the AE UI)
- Conitnuosly Rasterize (vector) / Collapse Transform (comps): (2, 7)
Layer Types:
- 0: Asset Layer
- 1: Light Layer
- 2: Camera Layer
- 3: Text Layer
- 4: Shape Layer
Matte Modes:
- No Matte
- Alpha
- Inverted Alpha
- Luma
- Inverted Luma
Time streching is defined as a fraction of Stretch Numerator / Stretch Denominator
idta
Item data.
Field Name | Size | Type | Description |
---|---|---|---|
Type | 2 | uint16 |
|
14 | |||
ID | 4 | uint32 |
ID used to reference this item |
38 | |||
Label Color | 1 | uint8 |
Label Colors |
The Type field above can have the following values:
1
: Folder4
: Composition7
: Footage
The last 2 bytes of this field seem to change every time you make a change.
tdb4
Property metadata.
Field Name | Size | Type | Description |
---|---|---|---|
2 | Always db 99 ? |
||
Components | 2 | uint16 |
Number of values in a multi-dimensional |
Attributes | 2 | Flags | |
1 | |||
1 | Some sort of flag, it has value 03 for position properties |
||
2 | |||
2 | |||
2 | Always 0000 ? |
||
2 | 2nd most significant bit always on, perhaps some kind of flag | ||
8 | float64 |
Most of the time 0.0001 |
|
8 | float64 |
Most of the time 1.0 , sometimes 1.777 |
|
8 | float64 |
Always 1.0 ? |
|
8 | float64 |
Always 1.0 ? |
|
8 | float64 |
Always 1.0 ? |
|
Type? | 4 | Flags | See below |
1 | Seems correlated with the previous byte, it's set for 04 for enum properties |
||
7 | Bunch of 00 |
||
Animated | 1 | Set to 1 when animated, kinda the reverse of the Static bit in Attributes |
|
7 | Bunch of 00 |
||
4 | Usually 0, probs flags | ||
4 | Mst likely flags, only last byte seems to contain data | ||
8 | float64 |
Always 0.0 ? |
|
8 | float64 |
Mostly 0.0 , sometimes 0.333 |
|
8 | float64 |
Always 0.0 ? |
|
8 | float64 |
Mostly 0.0 , sometimes 0.333 |
|
4 | Probs some flags | ||
4 | Probs some flags |
Attributes:
- Position: (1, 3). When
true
, this is a position property, which changes how animated values are parsed. - Static: (1, 0). When
false
, the property is animated and it will have acdat
.
Types:
- No Value: (1, 0). Used for properties like shapes, gradients, etc, where the values are not in the keyframe.
- Integer: (3, 2).
- Vector?: (3, 3).
- Color: (3, 0). Set for color properties (they have a different keyframe format).
For Integer type, you might have indexed values:
For layers, the value will be in tdpi
/ tdps
,
for masks it will be in tdli
.
cdat
Property static value.
For multi-dimensional properties, you look at the number of components in tdb4
and parse that many float64
, that's the value of the property.
shph
Header for bezier shape data, contained within LIST
shap
.
It's followed by a LIST
list
with bezier data.
Field Name | Size | Type | Description |
---|---|---|---|
3 | |||
Attributes | 1 | Flags | |
Top Left | 2 | float32 |
Top-left corner of the shape area, relative to the layer position |
Bottom Right | 2 | float32 |
Bottom-right corner of the shape area, relative to the layer position |
4 |
Flags:
- Open: (0, 3). When
true
, the shape is open (it's missing the segment connecting the last point to the first)
lhd3
Inside a LIST
list
, defines the data format, followed by ldat
.
Field Name | Size | Type | Description |
---|---|---|---|
4 | Seems to always be 00 d0 0b ee |
||
6 | All 00 |
||
Count | 2 | uint16 |
Number of items |
4 | The last byte is the only one that changes, greatest variation is on shapes | ||
2 | All 00 |
||
Item Size | 2 | uint16 |
Size of an item in the list |
3 | All 00 |
||
Type? | 1 | ||
4 | 00 00 00 01 |
||
2 | All 00 |
||
2 | Some kind of flags | ||
20 | All 00 |
Item Type | Size | Type |
---|---|---|
Gide |
00 01 |
02 |
LItm |
00 80 |
01 |
LRdr |
08 c6 |
01 |
Color Kf | 00 98 |
04 |
1D Kf | 00 30 |
04 |
2D Kf | 00 58 |
04 |
2D pos Kf | 00 68 |
04 |
3D Kf | 00 80 |
04 |
3D pos Kf | 00 80 |
04 |
Marker Kf | 00 10 |
04 |
Orientation Kf | 00 50 |
04 |
No Value Kf | 00 40 |
04 |
The corresponding ldat
should have Item Size * Count bytes, and it's omitted if Count is 0.
ldat
Inside a LIST
list
, contains the list data, preceded by lhd3
.
The number of element is the one defined in lhd3
.
It has a different format based on certain conditions, follow some of the possible element formats.
The size of an item is found like so:
item_size = ldat_chunk_length / lhd3_count
Keyframe (common)
All keyframe items start like this:
Field Name | Size | Type | Description |
---|---|---|---|
1 | |||
Time | 2 | Time | Time of the keyframe, seems they always start from 0. |
2 | |||
Ease Mode | 1 | uint8 |
|
Label Color | 1 | uint8 |
Label Colors |
Attributes | 1 | Flags |
Ease Mode: 1. Linear 2. Ease 3. Hold
Attributes:
Least significant 3 bits seems to always be on.
- Continuous Bezier (0, 3)
- Auto Bezier (0, 4)
- Roving across time (0, 5)
Keyframe - Multi-Dimensional
Given n
as the number of dimensions found in tdb4
(eg: 3 for 3D positions):
Field Name | Size | Type | Description |
---|---|---|---|
Value | 8* n | float64[n] |
Value |
In Speed | 8* n | float64[n] |
|
In Influence | 8* n | float64[n] |
|
Out Speed | 8* n | float64[n] |
|
Out Influence | 8* n | float64[n] |
Keyframe - Position
If the property is an animated position, the keyframe is formatted like so:
Field Name | Size | Type | Description |
---|---|---|---|
8 | |||
8 | float64 |
||
In Speed | 8 | float64 |
|
In Influence | 8 | float64 |
|
Out Speed | 8 | float64 |
|
Out Influence | 8 | float64 |
|
Value | 8* n | float64[n] |
Value |
Tan In | 8* n | float64[n] |
Spatial tangents |
Tan Out | 8* n | float64[n] |
Spatial tangents |
Keyframe - No Value
Used for shapes and gradients (Special set in tdb4
)
Field Name | Size | Type | Description |
---|---|---|---|
8 | |||
8 | float64 |
||
In Speed | 8 | float64 |
|
In Influence | 8 | float64 |
|
Out Speed | 8 | float64 |
|
Out Influence | 8 | float64 |
|
8 |
Keyframe - Color
Field Name | Size | Type | Description |
---|---|---|---|
8 | |||
8 | float64 |
||
In Speed | 8 | float64 |
|
In Influence | 8 | float64 |
|
Out Speed | 8 | float64 |
|
Out Influence | 8 | float64 |
|
Value | 8*4 | float64[4] |
ARGB 255 |
8*8 | float64[8] |
Shape Data
Bezier data, positions are relative to the area defined by shph
.
The list is a sequence of points, appearing in this order:
- Vertex 0
- Out Tangent 0
- In Tangent 1
- Vertex 1
- Out Tangent 1
- ...
Note that all coordinates are relative to the area in shph
but not to each other.
A coordinate of [0, 0] will correspond to the top-left corner in shph
,
and [1, 1] corresponds to the bottom-right.
Field Name | Size | Type | Description |
---|---|---|---|
X | 4 | float32 |
X Coordinate |
XY | 4 | float32 |
X Coordinate |
pprf
Color profile information as ICC data.
fiac
Folder item active, uint8
if it's 1 the previous List Item
is the active item.
wsnm
Worspace name.
Utf-16 encoded string, contains the name of the "workspace" (window layout in AE)
It's always followed by an Utf8
with the same content.
tdum
/ tduM
float64
values often found inside LIST
tdbs
.
In some cases they seem to indicate minimum and maximum values for that
property but there are some cases in which they are both 0.0
.
ppSn
Contains a float64
, unknown meaning.
otda
Orientation data
Field Name | Size | Type | Description |
---|---|---|---|
X | 8 | float64 |
X Coordinate |
Y | 8 | float64 |
Y Coordinate |
Z | 8 | float64 |
Z Coordinate |
opti
Asset data, format depends on type
Field Name | Size | Type | Description |
---|---|---|---|
Type | 4 | string |
Asset type |
Solid
Type Soli
, data for solid layers.
Field Name | Size | Type | Description |
---|---|---|---|
6 | |||
Alpha | 4 | float32 |
|
Red | 4 | float32 |
|
Green | 4 | float32 |
|
Blue | 4 | float32 |
|
Name | 256 | string0 |
Color components are in [0, 1].
sspc
Footage / asset data.
Field Name | Size | Type | Description |
---|---|---|---|
32 | |||
Width | 2 | uint16 |
|
2 | |||
Height | 2 | uint16 |
alas
JSON string containing external asset info.
Field Name | Type | Description |
---|---|---|
ascendcount_base |
number |
|
ascendcount_target |
number |
|
fullpath |
string |
The absolute path to the file |
platform |
number |
Operating system (see below) |
server_name |
string |
Hostname (?) |
server_volume_name |
string |
|
target_is_folder |
boolean |
Whether the file is a folder |
platform
values: 1
is Windows, other values are for Unix and MacOS,
but the values are to be discovered
head
Field Name | Size | Type | Description |
---|---|---|---|
AE Version? | 6 | ||
12 | |||
File Revision? | 2 | uint16 |
Increases by 2 every time you save |
Seems the first 6 bytes contain AE version information.
I haven't been able to decode it fully but here's a list of values encountered in the wild:
Version | Bytes |
---|---|
15.0 | 5c 06 07 38 06 b4 |
16.0 | 5d 04 0b 00 06 eb |
16.0.1 | 5d 04 0b 00 0e 30 |
16.1.2 | 5d 05 0b 00 96 37 |
16.1.3 | 5d 05 0b 00 9e 05 |
17.0 | 5d 09 4b 08 06 2b |
17.0.4 | 5d 0b 0b 08 26 3b |
18.2.1 | 5d 1b 0b 11 0e 08 |
18.4 | 5d 1d 0b 12 06 26 |
22.0 | 5d 1d 0b 70 06 6f |
22.6 | 5d 2b 0b 33 06 3b |
23.2.1 | 5e 03 0b 39 0e 03 |
It's possible the 3rd to the 5th bytes encode some kind of internal build number that gets mapped to AE versions somehow...
EfDC
The first byte contains the number of LIST
EfDf
in a LIST
EfdG
parn
Contains a uint64
with the number of parameters in a LIST
parT
.
pard
Effect parameter definition.
Field Name | Size | Type | Description |
---|---|---|---|
15 | |||
Type | 1 | uint8 |
Parameter type |
Name | 32 | string0 |
|
8 |
Types:
Type Name | AEP | Lottie | Lottie Object |
---|---|---|---|
Layer | 0 |
10 |
Effect Value Layer |
Scalar | 2 |
0 |
Effect Value Slider |
Angle | 3 |
1 |
Effect Value Angle |
Boolean | 4 |
4 |
Effect Value Checkbox |
Color | 5 |
2 |
Effect Value Color |
2D | 6 |
3 |
Effect Value Point |
Enum | 7 |
7 |
Effect Value Drop Down |
Paint Group | 9 |
||
Slider | 10 |
0 |
Effect Value Slider |
Group | 13 |
5 |
Custom Effect |
Unknown | 15 |
6 |
Effect No Value |
3D | 18 |
3 |
Effect Value Point |
After the data above, there is more data that depends on the type
Layer
Doesn't seem to have much data
Scalar / Angle
Field Name | Size | Type | Description |
---|---|---|---|
Last value | 4 | sint32 |
|
4 | |||
64 | |||
4 | |||
Min Value | 2 | sint16 |
|
2 | |||
Max Value | 2 | sint16 |
To get the last value, you need to divide the raw value by 0x10000
.
Boolean
Field Name | Size | Type | Description |
---|---|---|---|
Last used value | 4 | uint32 |
|
Default | 1 | uint8 |
|
3 | |||
64 | |||
4 | float32 |
||
4 | |||
4 | float32 |
Color
Field Name | Size | Type | Description |
---|---|---|---|
Last used value | 4 | uint8[4] |
ARGB |
Default | 4 | uint8[4] |
ARGB |
64 | |||
Max Value | 4 | uint8[4] |
ARGB |
2D
Field Name | Size | Type | Description |
---|---|---|---|
Last value X | 4 | sint32 |
|
Last value Y | 4 | sint32 |
Last value x/y are multiplied by 0x80, so divide them to get the right value.
Enum
Field Name | Size | Type | Description |
---|---|---|---|
Last used value | 4 | uint32 |
|
Option count | 2 | uint16 |
|
Default | 2 | uint16 |
Slider
Field Name | Size | Type | Description |
---|---|---|---|
Last used value | 8 | float64 |
|
44 | |||
4 | float32 |
||
4 | |||
Max Value | 4 | float32 |
3D Point
Field Name | Size | Type | Description |
---|---|---|---|
Last value X | 8 | float64 |
|
Last value Y | 8 | float64 |
|
Last value Z | 8 | float64 |
You need to multiply the "Last value" components by 512 to get the actual values.
pdnm
Effect parameter definition name / strings.
This will contain strings used by the widget in the effect controls of the preceding pard
.
For example if the type in the pard
is 4
(Boolean) the name of the parameter might be
empty and it will be in pdnm
as that's how AE displays it.
For Enum (type 7
), you get the drop down strings separated by |
.
tdpi
Layer index for index properties (uint32
).
tdps
Layer source for index properties (sint32
).
0
: Layer-1
: Effects & Masks-2
: Masks
tdli
Mask index for index properties (uint32
).
prin
Seems to always have the same content:
4 00
bytes, the string ADBE Escher
, 37 00
, the string Classic 3D
,
41 00
, and ends with 01
.
prda
Seems to always have the same content: 3 00
, a 01
, 8 00
.
NmHd
Marker attributes
Name | Size | Type | Description |
---|---|---|---|
3 | |||
Attributes | 1 | Flags | |
Duration | 4 | uint32 |
Duration in frames |
4 | |||
Label Color | 1 | uint8 |
Label Colors |
Flags:
- Protected: (0, 1) The marker signals a protected region
- ???: (0, 2) This flags seems to always be on
tdsb
4 bytes specifying flags for a tdgp
.
0x00'00'00'01
- object is visible0x00'00'00'02
- split position0x00'00'20'00
- locked x/y ratio
mkif
Mask properties.
Name | Size | Type |
---|---|---|
Inverted | 1 | uint8 |
Locked | 1 | uint8 |
4 | ||
Mode | 2 | uint16 |
Mask Modes:
- 0: None
- 1: Add
- 2: Subtract
- 3: Intersect
- 4: Darken
- 5: Lighten
- 6: Difference
CCId
Composition ID for essential graphics properties (uint32
)
CLId
Layer ID for essential graphics properties (uint32
)
Smin
Essential graphics slider minimum value.
Representation depends on the value of the previous CTyp
.
Smax
Essential graphics slider maximum value.
Representation depends on the value of the previous CTyp
.
CVal
Essential graphics property current value.
Representation depends on the value of the previous CTyp
.
CDef
Essential graphics property default value.
Representation depends on the value of the previous CTyp
.
CTyp
uint32
with the essential graphics item type
Name | Type | Value Format |
---|---|---|
Scalar | 2 |
float64 |
Color | 4 |
float32[4] RGBA |
Position | 5 |
float64[2] |
Comment | 8 |
|
Vector | 9 |
float64[4] |
Group | 10 |
|
Enum | 13 |
uint32 |
CprC
Essential graphics flags (4bytes)
- Is property (3, 0)
StVS
Essential graphics group item count
Name | Size | Type |
---|---|---|
Count | 1 | uint8 |
3 |
CDim
uint32
number of dimensions for an essential vector property.
fips
Contained in LIST
Fold
contains preview settings.
The chunk is repeated multiple times but only the first one seems
to be relevant.
Name | Size | Type |
---|---|---|
15 | ||
Flags | 1 | uint8 |
Flags
- Show alpha grid (0, 7)
LIST
Fold
Top level item.
LIST
Item
Item, you can check its properties with idta
contained inside it.
LIST
Layr
Defines a layer.
Layer metadata is found in a ldta
, the layer name is in a Utf8
.
Go through its LIST
tdgp
to get shapes and transforms.
You will find the following match names within it:
ADBE Root Vectors Group
: Contains shape data (shape layer in lottie)ADBE Camera Options Group
: Lottie camera layerADBE Transform Group
: Layer transformADBE Layer Styles
: Layer styles
LIST
tdgp
Defines an object / property group.
Flags for the objects are in tdsb
.
The name of the object is in tdsn
> Utf8
.
Then follows a sequence of properties / objects defined as such:
tdmn
specifies the match name of the object, then it's followed by
chunks that describe said object (usually more LIST
s).
Usually the last chunk here is a tdmn
with value ADBE Group End
.
LIST
tdbs
Defines an object's property. To know which property, you need to
check the tdmn
preceding this chunk.
It will contain a tdb4
, and usually cdat
(static) or a List
list
(animated).
For properties with expressions, it will have a Utf8
with the expression code.
LIST
GCst
Defines a gradient.
Contains a LIST
tdbs
and a LIST
GCky
.
LIST
GCky
Gradient color keyframes.
Contains a sequence of Utf8
formatted in XML with the gradient definition
for each keyframe.
LIST
om-s
Contains a LIST
tdbs
and a LIST
omks
to define a shape property.
LIST
omks
Bezier shape data.
Contains a sequence of LIST
shap
with the shape data for each keyframe.
LIST
shap
Contains a shph
and a LIST
list
with the shape data.
LIST
CPPl
Contains a pprf
.
LIST
list
For animated properties it replaces cdat
.
The list header is defined in the chunk lhd3
, the list data in ldat
.
LIST
SLay
/ LIST
DLay
/ LIST
CLay
They seem to be camera layers used to store internal views, not exported to lottie.
SLay
(Side views?) have names like "Top" and "Front", perhaps they define 3d views.
CLay
: Custom views.
DLay
: Default views.
LIST
SecL
Composition Markers Layer.
Contains ldta
and like other layers.
in LIST
tbgp
look for the match name ADBE Marker
, the data is in
the LIST
mrst
.
LIST
mrst
Marker property.
Contains a LIST
tdbs
that defines the property, which should always be animated
when present.
Marker keyframe values are available in LIST
mrky
.
LIST
mrky
Marker keyframes.
contains a LIST
Nmrd
for each keyframe
LIST
Nmrd
Marker data
There's a NmHd
with the attributes.
The marker comment is in the first Utf8
LIST
otst
Orientation property.
Contains a LIST
tdbs
and a LIST
otky
to define a shape property.
LIST
otky
Contains a sequence of otda
with the orientation data for each keyframe.
LIST
Als2
Contains alas
for external assets.
LIST
Sfdr
Asset folder contents, contains several LIST
Item
.
LIST
btdk
For some reason this doesn't conform to the RIFX specs, instead of a list its data is encoded in Carousel Object Structure (COS).
The COS format is the same used in PDF but it's extremely difficult to find detailed information on it, the best technical specs is this very old PDF 1.7 specification.
Once you parse the COS, you can find the following data:
0.1.0
: Array of available fonts:0.99
:CoolTypeFont
0.0.0
: Font family (seems to have bold/italic encoded in the name)0.0.2
:0
or1
?
1.1
: Array of text documents (one for each keyframe) in this format:0.0
: Text0.5.0
: Array of paragraph styles0.0.5
Paragraph Style:0
: Text align (0
: left,1
: right,2
: center)
1
: Length (in characters) the style applies to
0.6.0
: Array of character styles:0.0.6
: Character Style:0
: Index of the font from the array of available fonts1
: Font size2
: Faux Bold3
: Faux Italic12
:0
: Normal,1
: Small caps,2
: All caps13
:0
: Normal,1
: Superscript,2
: Subscript53.0.1
: Fill color in ARGB [0, 1]54.0.1
: Stroke color in ARGB [0, 1]57
: Stroke enabled58
: Stroke over fill63
: Stroke width
1
: Length (in characters) the style applies to
LIST
sspc
Effect Definiton.
The generic effect name is in fnam
> Utf8
.
The effect parameters are defined in LIST
parT
.
If the effect type has already been encountered, you might not find the
LIST
parT
here, you might need to match the name to an entry in LIST
EfdG
.
It finally contains a LIST
tdgp
where the effect properties are present
like any other animated property. You can also find the name
of the effect object in fnam
> Utf8
.
Inside there you can also find a match name with ADBE Effect Built In Params
which will contain values for built-in effect parameters.
LIST
parT
Effect parameters.
Contains a parn
with the number of parameters, then follows
a list of tdmn
with the match name of the parameter followed by
pard
with its definition.
Enum parameters have their values in a pdnm
separated by |
pipes.
The first property seems to be a dummy?
LIST
EfdG
Effect definitions.
This is where effect types used by the project are defined.
Basically it repeats the first instance of any effect found in the layers.
it contains a EfDC
with the number of effects, and that many LIST
EfDf
.
LIST
EfDf
Effect type definition.
Contains a tdmn
with the match name of the effect and a LIST
sspc
.
LIST
ExEn
Contains a Utf8
with the expression language (eg: javascript-1.0
).
LIST
PRin
Contains a prin
and a prda
.
LIST
Pin
Asset properties.
Contains:
LIST
CIF0
See LIST
CIF3
.
LIST
CIF2
See LIST
CIF3
.
LIST
CIF3
Essential Graphics Definition.
LIST
CCtl
Essential graphics item.
LIST
CpS2
Essential graphics header.
LIST
StVc
Essential graphics group items
LIST
CPrp
Essential graphics property definition
LIST
OvG2
Essential graphics override property identifiers
LIST
CPrp
Essential graphics override property identifier
LIST
LRdr
Render queue data. this is a top-level chunk. Items are stored in LIST
LItm
.
LIST
LItm
Render Queue items, contains a sequence of LIST
list
and
LIST
LOm
, the latter having information on the render item (one per job).
LIST
LOm
Render list item, contains the following chunks:
Roou
Output options?Ropt
Render options?LIST
Als2
Selected output fileUtf8
Name of the template applied to the itemUtf8
File name template
Gradient XML
Gradient data seems to be stored in a convoluted XML structure.
The easiest way to describe it is as a mapping, the elements can be parsed like so:
Tag Name | Logical Type | Description |
---|---|---|
prop.map |
Top-level, just get its first child | |
prop.list |
dict |
Mapping of key-value pairs |
prop.pair |
Item in prop.list |
|
key |
str |
Property key |
array |
list |
Array of values, the first item is array.type which specifies the type |
int |
int |
|
float |
float |
|
string |
str |
If you interpret the XML as a mapping, you can gather the following info:
{
"Gradient Color Data":
{
"Alpha Stops":
{
"Stops List":
{
"Stop-0":
{
"Stops Alpha":
[
0.0, // offset
0.5, // midpoint
1.0 // alpha
]
},
// More stops defined the same way...
}
"Stops Size": 2 // Number of stops
},
"Color Stops":
{
"Stops List":
{
"Stop-0":
{
"Stops Color":
[
0.0, // offset
0.5, // midpoint
0.0, // red
0.0, // green
0.5, // blue
1.0 // alpha?
]
},
// More stops defined the same way...
}
"Stops Size": 2 // Number of stops
}
},
"Gradient Colors": "1.0" // Version?
}
Midpoint
You should use the "midpoint" values to add an additional color which is halfway between the other two.
For example given these stops:
"Stop-0":
{
"Stops Color":
[
0.0, // offset
0.5, // midpoint
0.1, // red
0.2, // green
0.3, // blue
1.0 // alpha?
]
},
"Stop-0":
{
"Stops Color":
[
0.6, // offset
0.5, // midpoint
0.3, // red
0.4, // green
0.5, // blue
1.0 // alpha?
]
},
The final gradient will look like this:
[
// stop 0
0.0, // offset_0
0.1, // red_0
0.2, // green_0
0.3, // blue_0
// midpoint stop
0.3, // offset_0 * (1 - midpoint_0) + offset_1 * midpoint_0
0.2, // (red_0 + red_1) / 2
0.3, // (green_0 + green_1) / 2
0.4, // (blue_0 + blue_1) / 2
// stop 1
0.6, // offset_1
0.5, // midpoint_1
0.3, // red_1
0.4, // green_1
0.5, // blue_1
]
Opacity
For some reason in AE gradients alpha is independent from the color, so you have separate stops for color and opacity.
You should treat the midpoint value for opacity stops in a similar way as to the color ones.
Once you have both the color and opacity values, the final lottie array is simply a concatenation of the two.
XMP Metadata
After the RIFX data, an AEP file also contains some XML in the XMP format.
This section contains the version of AfterEffects, when the file has been created and modified, and related info.
XML Project Format
Aftereffects allows you to save the project as XML.
This is basically as the RIFX but with a different container format and binary data encoded as hex.
Conversion notes for elements are provided below
AfterEffectsProject
Root element, same as RIFX
.
ProjectXMPMetadata
In the RIFX file this is dumped at the end without a chunk.
string
Used instead of Utf8
.
numS / ppSn
For some reason they have their value in a <string>
but are not string in the RIFX.
tdsn / fnam / pdnm
These elements contain children but they are not LIST
in RIFX, that's the only thing of note.
Child elements
If an element has children. it's the same as the equivalent LIST
in RIFX.
bdata
Elements with the bdata
attribute have their binary data hex encoded in said attribute.
You can parse their data the same way as you'd do in RIFX.
Resources
- aftereffects-aep-parser A basic AEP parser written in Go.
- Multimedia Programming Interface and Data Specifications 1.0 RIFF specs PDF.
- Floating Point to Hex Converter Float to hex converter.
- bodymovin-extension AE extensions that exports to Lottie
- After Effects Scripting Guide
- Shape Layer Match Names
- Portable document format — Part 1: PDF 1.7 The only COS reference I've found