說說android端實現Airplay多屏互動(二)

zjc08125發表於2014-02-13

原文地址:http://blog.csdn.net/ville_zeng/article/details/19159439,轉載請註明出處!

Android端實現

       宣告: 此博文是延續上一篇博文說說android端實現Airplay多屏互動(一),建議先閱讀上述博文,再繼續該篇的閱讀。

        首先,感謝GitHub上大牛pentateu的無私分享—DroidAirPlay https://github.com/pentateu/DroidAirPlay

         DroidAirPlay只實現了音訊的投影,即只發布並處理AirTunes服務。若要實現圖片和視訊的投影,還需要在原始碼中進行更改,新增發布AirPlay服務。

        DroidAirplay中所有功能均在Android層實現,未使用lib庫在本地處理。大概功能實現:

        1.使用JmDNS進行服務發現。其中AirTunes服務型別設定為”_raop._tcp.local.”, AirPlay服務型別設定為“_airplay._tcp.local.”。

        2.使用netty來發布服務,分別用來處理上述兩種服務對應的請求處理。其中,AirTunes,AirPlay會指定不同的埠號,我們在netty釋出服務時分別繫結對應的埠號。

        3.音訊方面:從IOS裝置裝置傳送過來的音訊資料是經過加密的ALAC資料(ALAC 即Apple lossless audio codec的縮寫,是蘋果公司開發的一種無損音訊格式),經過解密,我們可以得到原始的ALAC資料,但是該格式的資料在android裝置上無法直接播放,因此,需要將alac格式轉碼成PCM格式,此格式的資料是原始的未經壓縮的音訊資料,可以直接播放,但是DroidAirplay在播放時,只能聽到吱吱的雜音,並沒有音樂輸出。後來除錯發現,原始碼中,處理的音訊取樣資料是16位雙聲道的,在解決資料大小端問題時並不完善,需要再次更改才行。同時因為DroidAirPlay是基於AirReceiver的,後者利用java sound中的部分api,但是Android中用android.media.AudioTrack替代了java sound的介面,導致DroidAirPlay在處理時有些小問題,當然在使用DroidAirplay時將這些地方改過來就行了。

        4.視訊圖片方面:AirPlay服務這邊相對比較簡單,協議相對單一,分別對應請求時去做相應處理就行了。

----------------------------------------------- 分割下子 ------------------------------------------------------------------

ps:

好多朋友想知道吱吱的聲音如何解決,筆者給出一個臨時的解決方案,有興趣的朋友可以試試,也歡迎提出改進意見。

程式碼改動有兩個地方,均在檔案nz.co.iswe.android.airplay.audio.AudioOutputQueue.java中

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
	}
}

本人QQ:447959344 ,歡迎交流。

QQ群(Airplay討論組1群):374092724(已滿)

(Airplay討論組2群):154113049


有朋友已經有成熟c/c++實現方案AirFly Receiver

AirFly Receiver 是基於AirPlay協議的成熟的接收端解決方案,可執行於各種硬體和作業系統之上,並支援多達16路的同時呈現。有興趣的朋友可以參考使用。

相關文章