您现在的位置是:首页 >技术教程 >Android 开机动画支持mp4格式视频播放网站首页技术教程
Android 开机动画支持mp4格式视频播放
前 言
Android系统在启动的过程中,最多可以出现三个画面,每一个画面都用来描述一个不同的启动阶段。无论是哪一个画面,它们都是在一个称为帧缓冲区(frame buffer,简称fb)的硬件设备上进行渲染的。
自定义开关机动画/视频
关于开机动画的流程主要代码在 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 文件进入的就是这种方式。会加载 bootanimation.zip 中的内容。zip 文件中实际是很多帧图片的组合,通过多帧图片的逐步播放实现动画的效果。所以把做好的动画拷贝到编译好对应的目录下即可。
#define SYSTEM_BOOTANIMATION_FILE “/system/media/bootanimation.zip”
开机动画的退出
开机动画的退出是靠 property 即 #define EXIT_PROP_NAME “service.bootanim.exit” 来判断的,见函数checkExit() 。
//BootAnimation.cpp
void BootAnimation::checkExit() {
if(mShutdown){
return ;
}
// Allow surface flinger to gracefully request shutdown
char value[PROPERTY_VALUE_MAX];
property_get(EXIT_PROP_NAME, value, "0");
int exitnow = atoi(value);
if (exitnow) {
requestExit();
if (mAudioPlayer != NULL) {
mAudioPlayer->requestExit();
}
}
}
而设置个property的地方是在 SurfaceFlinger.cpp
void SurfaceFlinger::bootFinished()
{
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
mBootFinished = true;
// wait patiently for the window manager death
const String16 name("window");
sp<IBinder> window(defaultServiceManager()->getService(name));
if (window != 0) {
window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
}
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
property_set("service.bootanim.exit", "1");
}
当显示模块boot完成后,会调用 property_set(“service.bootanim.exit”, “1”); 告诉 bootanimation 模块退出动画显示。
添加 mp4格式视频作为开机动画的过程
- 修改 ThreadLoop 中的判断(framebuffer/base/cmds/bootanimation/bootAnimation.cpp)
if (mVideo) {
r = video();
} else if (mZipFileName.isEmpty()) {
r = android();
} else {
r = movie();
}
- 我们在 ReadyToRun 中实现 mVideo 的判断
... ...
mFlingerSurface = s;
mTargetInset = -1;
/* add start */
mVideo = false;
mVideoFileName = "";
SLOGE("mShuttingDown = %d ", mShuttingDown);
if (access(!mShuttingDown ? SYSTEM_BOOTVIDEO_FILE : SYSTEM_SHUTDOWNVIDEO_FILE, R_OK) == 0) {
mVideo = true;
mVideoFileName = !mShuttingDown ? SYSTEM_BOOTVIDEO_FILE : SYSTEM_SHUTDOWNVIDEO_FILE;
SLOGD("mVideoFileName string is %s, length is %zu", mVideoFileName.string(), mVideoFileName.length());
}
/* add end */
SLOGD("Get Surface mWidth is %d,mHeight is %d",mWidth,mHeight);
return NO_ERROR;
}
static const char SYSTEM_BOOTVIDEO_FILE[] = "/system/media/bootvideo.mp4";
static const char SYSTEM_SHUTDOWNVIDEO_FILE[] = "/system/media/shutdownvideo.mp4";
- 实现 video 接口
bool BootAnimation::video(){
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(mDisplay, mSurface);
const char* boot_videofile = "/system/media/bootvideo.mp4";
int fd = open(boot_videofile, O_RDONLY);
sp<MediaPlayer> mediaplayer = new MediaPlayer();
mediaplayer->reset();
mediaplayer->setDataSource(fd, 0, 0x7ffffffffffffffLL);
mediaplayer->setLooping(false);
mediaplayer->setVideoSurfaceTexture(mFlingerSurface->getIGraphicBufferProducer());
mediaplayer->prepare();
mediaplayer->start();
while(true) {
if(exitPending())
break;
usleep(100);
if(!mediaplayer->isPlaying())
checkExit();
}
mediaplayer->stop();
mediaplayer->release();
return false;
}
- BootAnimation.h 中新增变量和函数
class BootAnimation : public Thread, public IBinder::DeathRecipient
{
...
private:
...
bool mVideo;
String8 mVideoFileName;
int mVideofd;
bool video();
...
- Android.bp 中确保要加入 libmedia
shared_libs: [
"libui",
"libhwui",
"libEGL",
"libGLESv1_CM",
"libgui",
"libtinyalsa",
"libmedia",
],
- 在 /system/media/ 中添加 bootvideo.mp4、shutdownvideo.mp4 后重启就可以看到开关机视频了。