安卓上开发 AirPlay Server 主要是参考了和修改了 DroidAirPlay项目 , 和Airplay 协议
1, 将DroidAirPlay 下载下来
2, Eclipse 新建一个 Android 项目, 并 添加JRE Library(防止报错,仅仅编译使用),项目中使用如下几个jar包, 自行下载, 别忘了加入网络及存储的权限
base64-2.3.8.jar
bcprov-ext-jdk16-1.46.jar
dd-plist.jar jmdns-3.4.0.jar
netty-3.2.4.Final.jar
(以上jar包可从 search.maven.org 搜索下载)
3, 将DroidAirPlay 项目的src下的包拷贝到 新建的项目的src 下
4, 新建Activity , 在 onCreate 方法中 使用如下代码 启动服务
AirPlayServer dwa = AirPlayServer.getIstance();
dwa.setRtspPort(8998); new Thread(new Runnable() {
@Override
public void run() { dwa.run();
}
}).start();
5, 需要修改的地方,都在 nz.co.iswe.android.airplay.audio.AudioOutputQueue 这个类中, 参考了这篇文章
1, audioTrack的实例化
//create the AudioTrack
//audioTrack = new AudioTrack(streamType, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes, mode);
audioTrack = new AudioTrack(streamType, sampleRateInHz, AudioFormat.CHANNEL_CONFIGURATION_STEREO, audioFormat, bufferSizeInBytes, mode);//FIXME
2, 采集数据处理
byte bytTemp = 0x00;
if (convertUnsignedToSigned) {
/* The line expects signed PCM samples, so we must
* convert the unsigned PCM samples to signed.
* Note that this only affects the high bytes!
*/
for(int i=0; i < samplesConverted.length; i += 2){
samplesConverted[i] = (byte)((samplesConverted[i] & 0xff) - 0x80);
//add by ville
bytTemp = samplesConverted[i];
samplesConverted[i] = samplesConverted[i + 1];
samplesConverted[i + 1] = bytTemp;
//end
}
}
6, 修改完后应该可以运行了, 但是使用iPhone连接后播放音乐会发现音量调整不了,因为android中 AudioTrack 最大音量为 1.0, 而根据AirPlay 协议文档的说明
The volume is a float value representing the audio attenuation in dB. A value of –144 means the audio is muted. Then it goes from –30 to 0.
需要修改 nz.co.iswe.android.airplay.audio.RaopAudioHandler 如下地方(大约744 行),
if ("volume".equals(name)) {
if (audioOutputQueue != null){
float vol = Math.abs(Float.parseFloat(value));
vol = (float) (1.0 - (vol / 29.0));
audioOutputQueue.setRequestedVolume(vol);
}
}
然后修改 AudioOutputQueue 的 setStereoVolume 方法
//注释掉如下两行
leftVolume = AudioTrack.getMaxVolume();
rightVolume = AudioTrack.getMaxVolume();
8, 修改设备名, 默认iPhone会搜索到名字为 localhost(wlan0) 的设备, 通过修改 nz.co.iswe.android.airplay.AirPlayServer, 可以定制设备名
//157 行
String hostName = "DwAirPlay";//networkUtils.getHostUtils();
9, 以上代码 大神F2 测试通过, 但是在C8650 这款老机器上发现没声音, 通过log猜测是设备处理能力不足引起, 不知道是不是这个原因...