SpyDroid源码分析系列11:SpyDroid上传AAC音频原理1

上一篇文章讲了AAC音频的代码如何编写,这次就跟着这段代码,一点一点的去了解代码背后究竟做了什么操作!

以及如何根据协议构造RTCP报文及RTP报文。

个人认为,只有通过这个过程,才能算是真正理解了多媒体,否则只能是一知半解。

当然,能力有限,对于多媒体的编码解码这部分,个人认为博士级别才可以去弄清楚原理,我猜是涉及到信号处理或者类似于什么小波变换,傅里叶变换之类的。本系列就不去深究,留给大牛们去解释!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

this.sessionbuilderaac = SessionBuilder.getInstance();

这句代码是构造一个SessionBuilder对象,先来研究getInstance方法。

这个函数的核心代码就一行:SessionBuilder.sInstance = new SessionBuilder();

显然是构造一个单例模式的SessionBuilder对象,我也说过,之所以JAVA和C++比C难分析的原因之一:

就在于对象初始化时,要设计到所有的父类以及对象成员的初始化,这个一旦没有捋清楚,就白分析了,

而C语言分析时就不存在这个问题,这也是我对JAVA和C++程序分析时头痛的原因,没有办法,只好继续分析。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SessionBuilder没有父类,这个很好,只需要直接看初始化函数即可。

private SessionBuilder() 
//自定义检查点: 1 2 3
{
//自定义检查点: 1 2 3
}
显然这里没有任何操作,那么单例模式的SessionBuilder也就完成了初始化,并且赋值给了SessionBuilder.sInstance。

~~~~然后接着执行下一句代码:

this.sessionbuilderaac.setVideoEncoder(SessionBuilder.VIDEO_NONE);

作用是修改

private int mVideoEncoder = VIDEO_H263; 
//修改成---> SessionBuilder.VIDEO_NONE

表明我这次是不需要上传视频的,只需要上传音频

~~~~~~~~~~~接着执行。

this.sessionbuilderaac.setAudioEncoder(SessionBuilder.AUDIO_AAC);

作用是:

private int mAudioEncoder = AUDIO_AMRNB;
//--->SessionBuilder.AUDIO_AAC

~~~~~~~~~~~~~~~~~~~~~~接下来执行

this.sessionbuilderaac.setContext(getApplicationContext());

作用是:

private Context mContext;
//-->设置为上下文的引用
~~~~~~~~~~~~~~~~~~~~~~~~接下来执行:

this.sessionbuilderaac.setTimeToLive(64);

作用是:

private int mTimeToLive = 64;
//-->64
~~~~~~~~~~~~~~~~~~~~~~~~~~接下来执行

this.sessionbuilderaac.setDestination(InetAddress.getByAddress(dest));

这里的dest是我本地设置的一个目标IP数组:

private byte[]   dest={(byte)192,(byte)168,(byte)1,(byte)100};

真正写的时候,需要根据配置文件来设置,请注意!

作用是:

private InetAddress mDestination = null;
//--->1892.168.1.100

~~~~~~~~~~~~~~~~~~~~~~~~~~接下来执行

this.sessionbuilderaac.setOrigin(InetAddress.getLocalHost());

我本来是这么写的,后来发现,这么写会报异常:

android.os.NetworkOnMainThreadException.

那我只好百度了一下,解决方案是:采用下面这个函数即可。

public InetAddress getLocalHostIp()
    {
        String ipaddress = "";
        try
        {
            Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces();
            // 遍历所用的网络接口
            while (en.hasMoreElements())
            {
                NetworkInterface nif = en.nextElement();// 得到每一个网络接口绑定的所有ip
                Enumeration<InetAddress> inet = nif.getInetAddresses();
                // 遍历每一个接口绑定的所有ip
                while (inet.hasMoreElements())
                {
                    InetAddress ip = inet.nextElement();
                    if (!ip.isLoopbackAddress()
                            && InetAddressUtils.isIPv4Address(ip
                                    .getHostAddress()))
                    {
                        //return ipaddress = "本机的ip是" + ":" + ip.getHostAddress();
                    return ip;
                    }
                }


            }
        }
        catch (Exception e)
        {
           // Log.e("feige", "获取本地ip地址失败");
            e.printStackTrace();
        }
        return null;


    }  

~~~~~~~~~~~~~~~~~~~~~~~~~~~接下来执行

this.sessionbuilderaac.setFlashEnabled(false);

作用是:

private boolean mFlash = false;
//--->false
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~接下来执行:

this.sessionbuilderaac.setSurfaceHolder(null);

private SurfaceHolder mSurfaceHolder = null;
//--->null

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~接下来执行:

this.sessionbuilderaac.setCamera( CameraInfo.CAMERA_FACING_BACK);

private int mCamera = CameraInfo.CAMERA_FACING_BACK;
//--->  CameraInfo.CAMERA_FACING_BACK

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~接下来执行:

private VideoQuality mVideoQuality = new VideoQuality();
//---> VideoQuality.DEFAULT_VIDEO_QUALITY

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~接下来执行:

this.sessionbuilderaac.setAudioQuality(AudioQuality.DEFAULT_AUDIO_QUALITY);

作用是:

private AudioQuality mAudioQuality = new AudioQuality();
//---> AudioQuality.DEFAULT_AUDIO_QUALITY
好,所有的配料都准备好了,下一节来准备build一个session.


你可能感兴趣的:(RTP,rtcp,aac,SpyDroid,SpyDroid)