上一篇文章讲了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.