安卓上開發 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猜測是設備處理能力不足引起, 不知道是不是這個原因...