• Android4.2.2启动动画前播放视频


    首先声明測试平台为瑞芯微的rk3168,Android4.2.2,Android版本号非常重要,由于Android4.0和Android4.2.2的代码有些地方就有差别,并不通用!


    首先接到任务不知怎样下手,由于我了解中Android启动时没有出现过播放视频的,特别是在启动动画之前,Linux企鹅之后,而动画也是一幅幅的图片,根本不是啥视频如mp4,3gp等!

    由于启动动画时能够播放声音,并且上层应用的mediaplayer也能够播放声音,结合surface能够播放视频!这就是入口点~

    动画播放的关键文件在:Z:Backup k3168_v4.2frameworksasecmdsootanimation下!

    1、了解Android显示开机画面的原理!

    1. Linux 系统启动,出现Linux小企鹅画面(reboot)(Android 1.5及以上版本号已经取消载入图片);
    2. Android平台启动初始化,出现"A N D R I O D"文字字样画面;
    3. Android平台图形系统启动,出现含闪动的ANDROID字样的动绘图片(start)。

    4、原理參考资料:

    http://blog.csdn.net/luoshengyang/article/details/7691321

    http://blog.csdn.net/conowen/article/details/7884009

    http://www.cnblogs.com/jqyp/archive/2012/03/07/2383973.html

    http://blog.csdn.net/backgarden_straw/article/details/8571992

    http://www.eoeandroid.com/thread-114742-1-1.html


    1、播放音乐:

    在瑞芯微提供的源代码中事实上能够支持播放音乐了,仅仅是没有提供音乐文件!声音移植

    a、首先在BootAnimation.h加入方法的声明和头文件的引用

    1
    2
    #include <media/AudioSystem.h>
    #include <media/mediaplayer.h>

    b、在 class BootAnimation : public Thread, public IBinder::DeathRecipient中

    加入方法 void playMusic();

    c、然后在BootAnimation.cpp中实现这种方法:

    #define BOOTMUSIC_FILE "/system/media/audio/alarms/gx.mp4"

    void BootAnimation::playMusic()
    {
        sp<MediaPlayer> mp = new MediaPlayer();
        if ((0 == access(BOOTMUSIC_FILE, F_OK)) && mp != NULL) {
            mp->setDataSource(BOOTMUSIC_FILE, NULL) //设置资源
            mp->prepare();                                                                 //准备,同步
            mp->start();                                                                      //播放
        }                                                                                           //事实上mediaplayer还有

    非常多方法,能够查看mediaplayer类
    }

    d、调用并启动声音

    bool BootAnimation::threadLoop()

    {
        bool r;

    playMusic()
        if (mAndroidAnimation) {
            r = android();
        } else {
            r = movie();
        }

    .......

    }

    e、Android.mk的改动

    由于播放声音还须要引入库

    LOCAL_SHARED_LIBRARIES :=
    libcutils
    libandroidfw
    libutils
    libbinder
        libui
    libskia
        libEGL
        libGLESv1_CM
        libmedia
        libgui

    请注意,libmedia是新加入的;

    f、声音文件的加入

    源代码文件夹在声音在:

    Z:source k3168_v4.2frameworksasedatasounds

    视频在:

    Z:source k3168_v4.2frameworksasedatavideos

    至于编译完毕后放到什么地方了那是AllAudio.mk文件上配置的

    $(LOCAL_PATH)/XXXX.mp3:system/etc/xxxx.mp3

    g、将音频放到此文件夹编译,就有开机声音了!


    2、视频移植

    a、事实上看了前面的资料了解动画的启动过程和对上层应用播放视频的方法事实上非常easy了!

    事实上动画的播放也是用surface来展示的,然后用OpenGL将图片绘制上去的!

    联系上层应用播放视频的步骤(mediaplayer+surfaceview):

    player=new MediaPlayer();
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);
    player.setDisplay(surfaceHolder);
    player.setDataSource("/sdcard/gx.mp4");
    player.prepare();
    player.start();
    。。。。。。。
    所以假设你做了声音播放后是不是非常自然想到,就差player.setDisplay(surfaceHolder);

    既然如此就倒推这方法做了什么:

    由于setdisplay是mediaplayer的方法

    basemediajavaandroidmediamediaplayer.Java--->

     public void setDisplay(SurfaceHolder sh) {
            mSurfaceHolder = sh;
            Surface surface;
            if (sh != null) {
                surface = sh.getSurface();
            } else {
                surface = null;
            }
            _setVideoSurface(surface);//重点设置一个surface
            updateSurfaceScreenOn();
        }

    private native void _setVideoSurface(Surface surface); //本地方法


    basemediajniandroid_media_MediaPlayer.cpp ----->
    {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer_setVideoSurface},
    
    ---->android_media_MediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface)
    {
        setVideoSurface(env, thiz, jsurface, true /* mediaPlayerMustBeAlive */);
    }
    ------------>
    static void
    setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface, jboolean mediaPlayerMustBeAlive)
    {
        sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
        if (mp == NULL) {
            if (mediaPlayerMustBeAlive) {
                jniThrowException(env, "java/lang/IllegalStateException", NULL);
            }
            return;
        }
    
    
        decVideoSurfaceRef(env, thiz);
    
    
        sp<ISurfaceTexture> new_st;
        if (jsurface) {
            sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
            if (surface != NULL) {
                new_st = surface->getSurfaceTexture();
                if (new_st == NULL) {
                    jniThrowException(env, "java/lang/IllegalArgumentException",
                        "The surface does not have a binding SurfaceTexture!");
                    return;
                }
                new_st->incStrong(thiz);
            } else {
                jniThrowException(env, "java/lang/IllegalArgumentException",
                        "The surface has been released");
                return;
            }
        }
    
    
        env->SetIntField(thiz, fields.surface_texture, (int)new_st.get());
    
    
        // This will fail if the media player has not been initialized yet. This
        // can be the case if setDisplay() on MediaPlayer.java has been called
        // before setDataSource(). The redundant call to setVideoSurfaceTexture()
        // in prepare/prepareAsync covers for this case.
        mp->setVideoSurfaceTexture(new_st);                //重点
    }
    
    分析到这里我们心里基本有数了,就是要活的一个surface就可以!
    b、分析动画中surface 的构建过程:
    在basecmdsootanimationBootAnimation.cpp的status_t BootAnimation::readyToRun()中有对surface的初始化,到了就完毕了大半获取这个surface在调用上面的方法就大功告成!
    
    

  • 相关阅读:
    微信公众平台开发心得笔记
    MFC中 在线程里获取主对话框上编辑框中的内容
    MFC中 使用Tab Control 控件在对话框中添加属性页
    MFC中 将std::string转换为LPCTSTR的方法
    MFC中 给按钮添加图片的方法
    MFC中 使用多线程实现语音播放功能
    MFC中 Group Box 控件会覆盖掉部分其他控件
    MFC中 CSting与std::string互相转换
    MFC中 给对话框添加背景图片
    MFC中 通过对子对话框的操作来更新主对话框
  • 原文地址:https://www.cnblogs.com/yxwkf/p/3793275.html
Copyright © 2020-2023  润新知