Back to oliverwolfson.com

 

Use the following shell script to extract raw key frame data from After Effects formatted key fame data files, so that Maya can use it.

 

The script:

 

#!/bin/sh

 

theFile="$1"

newFile=`basename -s ".txt" $theFile`.extracted.txt

theDir=`dirname $theFile`

 

cat "$theFile"  | tr '\r' '\n' \

                                                | grep -n -e "" \

                                                | grep -v -e ^1: -e ^2: \

                                                  -e ^3: -e ^4: -e ^5: \

                                                  -e ^6: -e ^7: -e ^8: \

                                                  -e ^9: -e ^10: -e ^11: \

                                                  -e ^12: -e ^13: -e ^14: \

                                                  -e End -e "^$" \

                                                  | awk -F ":" '{print $2}' \

                                                  | awk  '{print $2}' \

                                                  | grep -v "^$" > "$theDir/$newFile"

 

exit 0

 

 

You can copy After Effects keyframes from the timeline, and paste them into a text file. The data will look something like this:

--

Adobe After Effects 8.0 Keyframe Data

 

            Units Per Second       29.97

            Source Width 900

            Source Height            506

            Source Pixel Aspect Ratio     1

            Comp Pixel Aspect Ratio       1

 

Effects            Sound Keys #1          Output 1 #22

            Frame

            1          0.000261479

            2          0.00608461

            3          0.0153011

            4          0.0274689

            5          0.0395869

            6          0.0493024

            7          0.0562797

            8          0.0557284

            9          0.0997545    

            10       0.103466      

 

 

End of Keyframe Data

--

 

The script will produce something like this:

 

--

 

0.000261479

0.00608461

0.0153011

0.0274689

0.0395869

0.0493024

0.0562797

0.0557284

0.0997545    

0.103466      

 

--

 

The Script commented:

 

#!/bin/sh

 

# $1 is the first argument, meaning the first argument used when executing the script: scriptName.sh firstArgument.

# This argument should be a file containing After Effects keyframe data.

# So to execute this script you would write AfterEffectsExtract.sh /path/to/file/myAeKeyframeData.txt

# theFile is a variable holding that first argument.

# Using this variable in the script makes it somewhat more human readable.

theFile="$1"

# newFile is a variable which holds the name of the new file we are creating.

# `basename -s ".txt" $theFile` gets the name of theFile and strips off the ".txt" extension.

# .extracted.txt is added to the end of the name, creating a unique name for the new file.

newFile=`basename -s ".txt" $theFile`.extracted.txt

# theDir is a variable which holds the path to the directory we are working in.

theDir=`dirname $theFile`

# cat "prints" the contents of theFile, that is, it delivers it via pipe, |, to the tr command.

# the tr command is a search and replace command.

# Here it is set up to replace all Mac style line returns "\r" with Unix style line returns "\n".

# The \ creates a line return, visually  so we can read this code, but does not interrupt the code.

cat "$theFile"  | tr '\r' '\n' \

                                                            # grep -n -e "" adds line numbers, a numeral and a colon (1:, 2: , 3:, etc) to each line of data.

                                                            # -e = pattern, -n = line number, "" = all

                                                            # see ** below to see what the data looks like after running this grep command!

                                                | grep -n -e "" \

                                                            # grep will return matching lines

                                                            # grep -v will invert, return lines not matching the arguments

                                                            # -e = pattern, ^ = starts with

                                                            # we list the lines we don't want to include: lines that start with 1:, 2:, 3:, etc.

                                                            # also excluded are lines that include the word "End" and any blank lines (-e "^$", ^ = starts with, $ = ends with, "nothing")

                                                | grep -v -e ^1: -e ^2: \

                                                  -e ^3: -e ^4: -e ^5: \

                                                  -e ^6: -e ^7: -e ^8: \

                                                  -e ^9: -e ^10: -e ^11: \

                                                  -e ^12: -e ^13: -e ^14: \

                                                  -e End -e "^$" \

                                                            # with awk, we can edit the lines. We can remove part of the lines up to and including a delimiter.

                                                            # The -F option defines the input field separator to be the regular expression.

                                                            # the delimiter, or input field separator, is ":"

                                                            # {print $2} prints $2, the second column.

                                                            # so in fact we could just write awk  '{print $2}', that would give us the same result.

                                                            # yes this part is redundant ;), but it still works.

                                                  | awk -F ":" '{print $2}' \

                                                  | awk  '{print $2}' \

                                                            # grep -v "^$" makes certain that there are no remaining blank lines. Redundant, maybe, again, it works..

                                                            # > "$theDir/$newFile" writes newFile to theDir directory.

                                                  | grep -v "^$" > "$theDir/$newFile"

# exit(0) is a shell built-in command that causes program termination.

# The exit statement will exit the current shell script.

# It can be given a numeric argument which is the script's exit status.

# If omitted the exit status of the last run command is used.

# 0 (zero) signifies success, non-zero signifies failure.

exit 0

 

--

 

** The data will look something like this, below, after we run grep –n –e рс

 

1:Adobe After Effects 8.0 Keyframe Data

2:

3: Units Per Second 29.97

4: Source Width 900

5: Source Height 506

6: Source Pixel Aspect Ratio 1

7: Comp Pixel Aspect Ratio 1

8:

9:Effects Sound Keys #1 Output 1 #22

10: Frame

11: 874 22.9339

12: 875 22.0806

13: 876 12.0954

 

 

 

Detailed explanation of AfterEffectsKeyExtract.sh by Jeshua Lacock OpenOSX.com

 

this line:

theFile="$1"

sets the variable theFile to the first argument

(which is the file name)

it is an argument variable

 

we could just use it directly, but it makes it more clear if we label it

 

this line:

newFile=`basename -s ".txt" $1`.key

makesit remove .txt and append .key

 

so this line:

newFile=`basename -s ".txt" $theFile`.extracted.txt

sets a newFile variable to be the file name minus .txt plus .extracted.txt

 

cat "$theFile"

just prints the file to the screen which is piped to tr

 

 

tr '\r' '\n'

changes it from Mac to Unix line returns

 

which pipes it to grep

 

grep -n -e ""

grep is like a find for individual lines

 

numbers the lines with the -n option, and -e is what we want to match - everything in this case

-n is the number of lines/

By default, grep prints the matching lines.

that is the option to print the line number

 

so all we are doing so far is printing all of the lines with the line number for each line first

 

so the lines look like this at this point:

1:Adobe After Effects 8.0 Keyframe Data

2:

3: Units Per Second 29.97

4: Source Width 900

5: Source Height 506

6: Source Pixel Aspect Ratio 1

7: Comp Pixel Aspect Ratio 1

8:

9:Effects Sound Keys #1 Output 1 #22

10: Frame

11: 874 22.9339

12: 875 22.0806

13: 876 12.0954

 

next is a long grep line, starting with:

grep -v -e ^1:

grep -v is the opposite of grep - it print everything *but* the matching lines

^1: means match a line that starts with 1:

so you list the line u dont want

so the -v makes it not print that line

 

up to 14

 

because we don't want the first 14 lines

 

we also want to ignore lines that say the word "End" with:

-e End

and we want to ignore blank lines with:

-e "^$"

 

so at this point it looks like:

11: 874 22.9339

12: 875 22.0806

13: 876 12.0954

14: 877 7.173

15: 878 5.63299

16: 879 7.08297

17: 880 9.63439

18: 881 10.511

19: 882 10.6646

20: 883 9.12829

 

next, we pipe it to awk

| awk -F ":" '{print $2}'

with -F we are specifying the delimiter

which is :

and saying we want the 2nd field

'{print $2}'

so 11: 874 22.9339 becomes 874 22.9339

so unix sees each block of text as a "feild"?

field

it sees the fields based on the -F

which is :

by default it is any blank space

(space tab, etc)

 

then we send it awk that uses the space as the delimiter:

| awk '{print $2}'

we don't have to specify the delimiter because it is space by default

 

note that we actually would only need this

we don't need the first one now that I think about it

okay so the delimiter in the first case is :

anways, that makes 874 22.9339 become 22.9339

in the second case is a space

yeah - and we could go straight from 11: 874 22.9339 to 22.9339 by using the space only

 

I used : because the first thing I wanted to get rid of is the line numbers

 

awk = pattern-directed scanning and processing language

:-&

have no idea why awk though

 

then it pipes it grep:

grep -v "^$"

which ignores any blank lines (again)

 

> "$newFile" sends the whole stream out to our new file variable

thats it