[XDA-University] threadreaper:
[Tutorial][Tool]Custom boot animations & cross platform tool to create boot animation

Changing the boot animation on your Android device is fairly trivial if you have root, and there are not many mods you can make to your device that have the same level of impact on how "custom" it feels.

There are a handful of apps on the play store you can use to change the bootanimation, if you can find one that you like. But if you can't find something that satisfies your tastes, you're stuck looking for someone else to do it for you, or using the same one from the app store that 15 other people you know have. If what you're really looking for is that completely custom look, or perhaps just the satisfaction of doing it yourself, this is the tutorial you've been looking for.

Google actually has a writeup in the AOSP repository about the format and construction of the boot animations, and it's one of the few things that actually hasn't changed much over the lifetime of Android. So this process should apply to most of the devices out there, but as I'm working on a Chinese head unit right now that's the device we'll be taking through this tutorial.

To make a boot animation essentially requires only two things. You need a series of images that represent the frames of your animation, and a short text file that tells the system how to process them. All these things go into a zip file named bootanimation.zip, stored in system/media on most devices, and there's where the system reads the boot animation from. One side note worth mentioning is that if a bootanimation.zip is present in oem/media (or presumably vendor/media on treble devices, though the Google docs haven't been updated) that takes precedence over the one in system/media. So if you've placed an animation in system/media and you're still seeing the stock one, check those locations for another bootanimation.zip and replace that one instead.

It sounds fairly straightfoward, but there are a few caveats that can be a bit frustrating when you're just getting started with making your own bootanimations, and previous tutorials I've seen either don't mention them or just aren't very clear on those steps. This is my attempt at making a more comprehensive write-up.

The text file you'll need has to be named desc.txt and lays out the structure of your animation. It's not diffiacult to create once you understand how it works, but people have been known to struggle with it. The first line is really simple; it just lays out the resolution of your animation, and the framerate you want it to play at. In the following format: width height framerate where width is the width of your images, height is the height of your images. The width and height should match the display resolution of your device for best results. You can go smaller, but you'll have to tell the system what to do with the extra space (more on this later) Setting this larger than your display resolution or using images larger than your display resolution with generally give you unpleasant results. Your animation will be either cropped (cut off) or squished to fit the device resolution. If you don't know your the resolution of your device for sure, Aida64 or any of the other system info apps from the play store can reveal it to you. Framerate is an integer (whole) number describing how many frames per second should be displayed. The higher this number is, the smoother than animation can be. However, that means more frames you will need to create, and some devices can lag at higher framerates. It's tempting to go for something like 60 frames per second, but a lot of devices can't keep up with this framerate (remember it's still trying to load all of its drivers and get the operating system started at this point too). I have found that the most satisfactory results at around 10-15 frames per second. My display resolution is 1024x600 and I'm going to shoot for 15 frames per second. So with those details in place, the first line of my desc.txt looks like this:

1024 600 15

The remaining lines in desc.txt may vary depending on how you want your animation to play. The animation can be divided into "parts" with separate rules for how many times each part plays, whether or not to repeat it, how many times to repeat it, etc. Each remaining line has 4 required and 3 optional columns and describes one of these "parts." The four columns are the "type" - containing a single character, either p or c, determining what type this particular part is. A "p" type can be interrupted when the system is finished booting and ready to display the home screen. A "c" type will play to completion no matter what. So if a "c" type is still playing when the boot process is finished, you'll have to wait for that part of the animation to be through before you can see your home screen. The next column must be an integer number that represents how many times to loop through that particular part of the animation. If you set it to 0, it will loop repeatedly until the boot process is completed. The third column is another integer number indicating that the system should pause the animation for this number of *frames* (not seconds) before looping again or going on to the next part, whatever it's doing next. This entry can be 0 for no pause, or represent any number of frames. So if your animation is playing at 15 frames per second, and you want it to be paused for 1 second at this point, you'll want to set this to 15. If you wanted to pause for half of a second, well you're out of luck because the number has to be an integer, but you can set it to either 7 frames for slightly less than half a second pause or 8 frames for a slightly more than half a second pause. Still with me? If your target framerate is some other value, this value must change accordingly. The fourth column represents a folder name where the images for this part of the animation are stored. If your animation is just a loop that you want to play continuously until the system boots, you will only need this one line and it could look like this:

p 0 0 part0

This line simply directs the system to play this "part" repeatedly until the system boots up, with no pauses between the loops, to interrupt the animation as soon as it's ready to load up the home screen, and to look for the images to play in a folder named "part0." Earlier I mentioned using images of a lower resolution than your display and also three optional columns in these lines for desc.txt. The fifth column is optional, and it contains a background color to be displayed in the case that your image doesn't cover the entire screen, and its value, if present, must be a color code in hex format with a leading # ex. #FFFFFF for a white background. You might use this for example to put a colored border around your animation if your frames are slightly smaller than the screen resolution. Or if your images are mostly in the center of the screen, and have a solid background color (let's say black to keep it simple) you can actually save some rendering time and get a bit smoother playback by making your images only as big as they need to be to account for what will change from frame to frame, and set this to #000000 to fill in a black background around it. So if your animation was just a spinning globe centered in the screen, and 2/3 of the screen stayed black the whole time, you might size the image at 300x300 pixels and set the background color. This can produce smoother animations in lower end devices, because the system isn't wasting it's time overwriting all the black pixels with a new set of black pixels 15 times per second, and you can achieve higher framerates with more fluid results using this method. The final two optional columns are used mostly for Android smartwatches and contain x y coordinates telling the system where on screen to display the time. The values are integer amounts, in pixels, or "c" for center. The rules for using them are a bit complex. We'll call these columns CLOCK1 and CLOCK2. If CLOCK1 is set and CLOCK2 is not, then CLOCK1 sets the y coordinate, and x is defaulted to "c" for centered. If both CLOCK1 and CLOCK2 are set, then CLOCK1 represents the *x* coordinate and CLOCK2 is *y*. Positive values for x will position the time x pixels from the left, and negative values will position the time x pixels from the right. For y, positive values position the time y pixels up from the bottom of the screen, and negative values position the time y pixels down from the top of the screen. Clear as mud? Good, let's move on.

So after that lengthy explanation, we can move on to adding more lines to desc.txt and why we might want to. I find it helpful to visualize how I want each animation to look from start to finish and then consider what that's going to look like if it happens to repeat, in order to decide if my animation needs more than one part. So let's return to the spinning globe example to illustrate an example of when we might want to do this. To make the overall effect more interesting, let's say that our globe is going to come into the screen from the left side and travel until it gets to the center at the start of our animation, after which it will remain in the center and continue to spin. If my animation has 100 frames in total, I could shove them all into a part0 folder and use the p 0 0 part0 line from above and call it good. But after the first 100 frames play, something like 6 and a half seconds will have elapsed, and if the device isn't ready to boot by then, the animation will loop, and we'll watch the globe entering from the left side of the screen again, which would be kind of a jarring effect. It would be a much nicer visual if it simply stayed in the middle and continued to spin until the system interrupted the animation. To achieve that effect, I'd need to use separate parts, and some slightly more complex rules. Looking through my frames, I might determine that it takes 50 frames of the animation for the globe to reach the center of the screen, where I want it to remain for the whole time. So I would take those 50 frames and put them in the part0 folder, and add a line to desc.txt like this:

c 1 0 part0

This tells the system to play these 50 frames through only 1 time, and not to interrupt the animation at this point if it's ready to boot, and not to pause before moving on to the next part. To complete the effect, my second line should look something like this.

p 0 0 part1

Now we're telling the system that it's ok to interrupt at this point any time it's ready to start up, but until that point, just keep playing this part of the animation (the spinning part) over and over, without returning all the way to the beginning where we entered the screen from the left. Nifty, huh? With some clever application of this technique you can create some very interesting effects.

To add audio to the animation, each part folder can contain a .wav file that will play when that part starts. If that part of the animation loops, the audio will also loop.

Gotchas:

If you've followed everything up to this point, you're almost ready to get started. There are a couple more details you need to know to be successful making your sweet custom boot animation.

First, the zip file that you put all of this stuff in has to be constructed in a particular way. The archive must be assembled in "storage only" mode, meaning no compression. So whatever utility you use to construct the zip file must support this method. This may lead you to question why use a zip archive if nothing is supposed to be compressed? Why not just use a folder? The answer to this is what ends up frustrating most people who set out to make a boot animation and end up giving up on it. The binary that controls this process expects all these files to be in a certain order, and Linux (and by extension, Android) can do some unexpected things with the order of files inside a directory. The images used in your animation can be named anything you want as long as they all have the same naming convention, which must include sequential numbers. For example, image01.png, image02.png, image03.png etc. The same rule applies to your part folders. They don't necessarily have to be named "part" but they must include sequential numbers, so folder00, folder01, folder02, etc. In either case, if you skip a number, the process hangs and you end up with a soft brick. So if you have image01.png, image02.png and then image04.png with no image03.png, your animation will hang, and you'll have to fix it from recovery mode, because the device will never manage to boot. Not only must all these files be present, they must be *stored in order*. So if I have 01.png, 02.png, 03.png but they're store as 01.png, 03.png, 02.png, I'll get a soft brick, because the process isn't smart enough to organize the files on its own, it just expects the next one out of the archive to be the right one. This can screw you up in various ways if you're not careful. To keep things simple, I normally just name my images with numbers, so 000.png, 001.png, 002.png, etc. If I have 10 of these images in a folder on my Linux machine, and within that folder I do an "ls" command to list what files are there, Linux sorts them for me before outputting them to the screen, so I see them all in numerical order. But if I do "ls -U" which tells the shell to skip the sorting step, they are almost never anywhere close to being in numerical order. That's because in Linux, everything is a file, so in reality there is no such thing as a folder. A folder is just another file, containing pointers to all the files that are "stored in it." These files may be stored all over the disk, in whatever spot the system decided was the most efficient place to put them at the time. And they can get rearranged over time, as disk operations happen. So the purpose of the zip archive is to keep all of the files neatly in numerical order so the "dumb" bootanimation process doesn't get confused. We have to be aware of this behavior when we create the archive! If you just stuff all the files into the archive at once, the system is going to place them in there in the order it fetches them, not necessarily in the order that it's displaying them to you in. So what may appear to be a neatly sorted group of files before the archiving process can end up being a random mess inside the zip file that's going to soft brick your phone. I don't know off hand if Windows behaves the same way, but I discovered the hard way that this issue can be quite troublesome to work around on a Linux system. One way around it is to manually add files to the zip archive one at a time so you can force them to be in the right order, but this proves to be really tricky to do from the command line, not to mention tedious. It's similarly tedious and easy to mess up doing it in a gui. To that end, I have another utility to share that will automate this process and ensure that everything goes in the archive in the correct order!

You can get the tool from my https://github.com/threadreaper/abatools.git

Once you've cloned the git repository, from the top level directory (the one with the setup.py file):

pip3 install .

Alternatively, it's availble on PyPi. If you have Python installed, you should be able to execute:

pip3 install abatools

Once the tool is installed, it should be available to you from your command line. Execute:

abatools -a bootanimation.zip

from within a folder containing ONLY your desc.txt and your directories of image files, and the tool will properly package up the zip file for you.

BONUS! The tool can also auto-magically produce a boot animation from a .gif animation. To use this function, use the -g switch and point the tool to your gif file as follows:

abatools -g mygif.gif bootanimation.zip

That's it! You're already to go create some sweet custom boot animations!