您现在的位置是:首页 >技术教程 >Android 开机动画支持mp4格式视频播放网站首页技术教程

Android 开机动画支持mp4格式视频播放

houxian1103 2024-07-23 00:01:02
简介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格式视频作为开机动画的过程

  1. 修改 ThreadLoop 中的判断(framebuffer/base/cmds/bootanimation/bootAnimation.cpp)
    if (mVideo) {
        r = video();
    } else if (mZipFileName.isEmpty()) {
        r = android();
    } else {
        r = movie();
    }
  1. 我们在 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";
  1. 实现 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;
}
  1. BootAnimation.h 中新增变量和函数
class BootAnimation : public Thread, public IBinder::DeathRecipient
{
...
private:
...
    bool        mVideo;
    String8     mVideoFileName;
    int         mVideofd;
    bool        video();
...
  1. Android.bp 中确保要加入 libmedia
shared_libs: [
        "libui",
        "libhwui",
        "libEGL",
        "libGLESv1_CM",
        "libgui",
        "libtinyalsa",
        "libmedia",
    ],
  1. 在 /system/media/ 中添加 bootvideo.mp4、shutdownvideo.mp4 后重启就可以看到开关机视频了。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。