android mp4开机动画,[Android]添加自定义开机动画(视频)并去黑屏

平台 :RK3288

OS:Android5.1

参考文章:Android系统的开机画面显示过程分析(罗升阳)

补丁如下

源码分析及修改方式

关于开机动画的流程主要代码在

framebuffer/base/cmds/bootanimation/bootAnimation.cpp

从 BootAnimation::threadLoop() 中的我们可以看到

if(mZip == NULL) {

r = android();

} else {

r = movie();

}

根据 mZip(这是一个叫做 bootanimation.zip 的文件)是否存在,决定调用 Android() 接口还是 movie() 接口。

android()

如果没有 zip 文件进入的就是这种方式。

会加载”images/android-logo-mask.png”和”images/android-logo-shine.png” 这两张图片,前者是镂空的 ANDROID 字样,后者是一副很长的银白黑渐进的背景图,通过固定前者,移动后者,实现 ANDROID 字样的反光效果。

想修改android闪动的那两张图片的话,最简单的方法是直接替换图片(图片在 /frameworks/base/core/res/assets/images),如果懂 openGL 的话也可以自己做酷炫的动画。

movie()

如果有 bootanimation.zip 文件进入的就是这种方式。

#define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"

会加载 bootanimation.zip 中的内容。zip 文件中实际是很多帧图片的组合,通过多帧图片的逐步播放实现动画的效果。

所以把做好的动画拷贝到编译好对应的目录下即可,然后执行make snod整合进 img 包就可以看到效果了。

具体制作 bootanimation.zip 的文章参考这两篇:

http://blog.csdn.net/mlbcday/article/details/7410509

http://luq1985428.blog.163.com/blog/static/12243116220131198011812/

但这样默认是没有音乐的,还需要实现一个 playMusic() 的接口,来同步的播放音乐。

具体实现 playMusic() 接口的方式参考这一篇的 “1.播放音乐”:

http://www.voidcn.com/blog/longtian635241/article/p-2095371.html

从 mp4 中提取音频为 ogg 或者 wav 格式的网站有

http://media.io/

缺点是

1. 多帧图片由于画面色彩丰富、动画较长,这样做出来的 zip 会比较大,播放效果会出现明显、严重卡顿

2. 播放时music时可能出现动画和声音不同步

所以我们可以调用 mediaPlayer 的接口来实现播放视频(mp4)

自行添加 video 接口

修改 ThreadLoop 中的判断

// We have no bootanimation file, so we use the stock android logo

// animation.

- if (mZip == NULL) {

+ if (mVideo) {//这里的 mVideo 是一个标志位,表示是否有开机视频

+ r = video();

+ }else if (mZip == NULL) {

r = android();

} else {

r = movie();

我们在 ReadyToRun 中实现 mVideo 的判断。

@@ -359,6 +362,7 @@ status_t BootAnimation::readyToRun() {

mFlingerSurfaceControl = control;

mFlingerSurface = s;

+ mVideo = false;

// If the device has encryption turned on or is in process

// of being encrypted we show the encrypted boot animation.

char decrypt[PROPERTY_VALUE_MAX];

@@ -366,6 +370,9 @@ status_t BootAnimation::readyToRun() {

bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt);

+ if (access(BOOTANIMATION_VIDEO, R_OK) == 0)

+ mVideo = true;

+

ZipFileRO* zipFile = NULL;

if ((encryptedAnimation

&& (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0)

下面可以开始添加 video 接口了

+bool BootAnimation::video()

+{

+ const float MAX_FPS = 60.0f;

+ const bool LOOP = true;

+ const float CHECK_DELAY = ns2us(s2ns(1) / MAX_FPS);

+ sp httpService;

+ eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

+ eglDestroySurface(mDisplay, mSurface);

+ /* + float asp = 1.0f * mWidth / mHeight; + SurfaceComposerClient::openGlobalTransaction(); + mFlingerSurfaceControl->setPosition(mWidth, 0); + mFlingerSurfaceControl->setMatrix(0, 1 / asp, -asp, 0); + SurfaceComposerClient::closeGlobalTransaction(); + */

+

+ sp mp = new MediaPlayer();

+ mp->setDataSource(httpService, BOOTANIMATION_VIDEO, NULL);//设置播放资源

+ mp->setLooping(true);//确定是否播放循环

+ mp->setVideoSurfaceTexture(mFlingerSurface->getIGraphicBufferProducer());

+ mp->prepare();

+ mp->start();

+ while(true) {

+ if(exitPending())

+ break;

+ usleep(CHECK_DELAY);

+ checkExit();

+ }

+ mp->stop();

+ return false;

+}

如果要实现开关机动画不同也可以增加一个判断。

这里的 BOOTANIMATION_VIDEO 为 mp4 的路径,setDataSource 接口有多种重载方式,这里采用 url 的方式。

+#define BOOTANIMATION_VIDEO "/system/media/bootanimation.mp4"

+#include

最后修改头文件,添加增加的两个成员变量

/cmds/bootanimation/BootAnimation.h

@@ -106,6 +106,8 @@ private:

EGLDisplay mSurface;

sp mFlingerSurfaceControl;

sp mFlingerSurface;

+ bool mVideo;

+ bool video();

ZipFileRO *mZip;

int mHardwareRotation;

GLfloat mTexCoords[8];

至此已经完成 video() 接口的编写了。

(具体 MediaPlayer 的用法参考的 http://www.voidcn.com/article/p-budkmfhq-by.html )

后面可以在 /system/media/ 中添加 bootanimation.mp4 尝试能否播放 mp4。

开机视频前黑屏 5s

是由于等待电池的后台服务启动导致的,屏蔽如下代码。

frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

0818b9ca8b590ca3270a3433284dd417.png

屏蔽后黑屏时间减为 1s 左右。

你可能感兴趣的:(android,mp4开机动画)