iOS語(yǔ)音對(duì)講(二)RTSP+RTP協(xié)議實(shí)時(shí)傳輸

本文介紹iOS實(shí)時(shí)語(yǔ)音雙向?qū)χv(語(yǔ)音通話)功能:
(一)實(shí)時(shí)采集PCM并編碼AAC
(二)RTSP+RTP協(xié)議實(shí)時(shí)傳輸
(三)FFmpeg實(shí)時(shí)解碼AAC并播放PCM

第二篇介紹使用基于CocoaAsyncSocket的第三方開(kāi)源庫(kù)GCDAsyncSocket進(jìn)行RTSP協(xié)議的Socket網(wǎng)絡(luò)通訊。
GitHub下載地址:https://github.com/robbiehanson/CocoaAsyncSocket


具體過(guò)程如下:
創(chuàng)建socket并建立一個(gè)連接

- (int)connectServer:(NSString *)hostIP port:(int)hostPort {
    if (_socket == nil) {
        _socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
        NSError *err = nil;
        int t = [_socket connectToHost:hostIP onPort:hostPort error:&err];
        if (!t) {
            return 0;
        }else{
            return 1;
        }
    }else {
        [_socket readDataWithTimeout:-1 tag:0];
        return 1;
    }
}

GCDAsyncSocketDelegate代理方法

//連接成功
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
    BOOL state = [self.socket isConnected];
    if (state) {
        [self sendCmd];
    }
}
//斷開(kāi)連接
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {
    BOOL state = [_socket isConnected];
    NSLog(@"disconnect,state=%d",state);
    self.socket = nil;
}

發(fā)送RTSP命令

- (void)sendCmd
{
    [self doSetup:self.url];
}

- (void)doSetup:(NSString *)url {
    NSMutableString *dataString = [NSMutableString string];
    [dataString appendString:[NSString stringWithFormat:@"SETUP %@ RTSP/1.0\r\n", url]];
    [dataString appendString:@"Content-Length: 0\r\n"];
    [dataString appendFormat:@"CSeq: 0\r\n"];
    [dataString appendString:@"Transport: RTP/AVP/DHTP;unicast\r\n"];
    [dataString appendString:@"\r\n"];
    NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    [self.socket writeData:data withTimeout:-1 tag:0];
    [self.socket readDataWithTimeout:-1 tag:0];
}

- (void)doPlay:(NSString *)url {
    NSMutableString *dataString = [NSMutableString string];
    [dataString appendString:[NSString stringWithFormat:@"PLAY %@ RTSP/1.0\r\n", url]];
    [dataString appendString:@"Content-Length: 0\r\n"];
    [dataString appendFormat:@"CSeq: 1\r\n"];
    [dataString appendString:@"\r\n"];
    NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    [self.socket writeData:data withTimeout:-1 tag:1];
    [self.socket readDataWithTimeout:-1 tag:1];
}

- (void)doTeardown:(NSString *)url {
    NSMutableString *dataString = [NSMutableString string];
    [dataString appendString:[NSString stringWithFormat:@"TEARDOWN %@ RTSP/1.0\r\n", url]];
    [dataString appendString:@"Content-Length: 0\r\n"];
    [dataString appendString:@"CSeq: 2\r\n"];
    [dataString appendString:@"\r\n"];
    NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    [self.socket writeData:data withTimeout:-1 tag:2];
}

讀取數(shù)據(jù)

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    switch (tag) {
        case 0:
            [self doPlay:self.url];
            break;
        case 1:
            [self startCapture];
            break;
        case 200:
            if (!dataString) {
                [self getPayload:data];
            }
            break;
        default:
            break;
    }
    [sock readDataWithTimeout:-1 tag:200];
}
PS:標(biāo)準(zhǔn)的RTSP協(xié)議DESCRIBE结执、OPTIONS、SETUP、PLAY、TEARDOWN等方法一般都需要發(fā)送闸英,作者這里為非標(biāo)準(zhǔn)RTSP枚驻,只需發(fā)送SETUP、PLAY蒿辙、TEARDOWN”醢停可參考RTSP百科:RTSP

其中readDataWithTimeout表示需要讀取發(fā)送后返回的數(shù)據(jù)思灌,-1表示不會(huì)使用超時(shí)。

以上恭取,則實(shí)現(xiàn)了RTSP的通訊泰偿,可將編碼后的AAC以RTP的形式進(jìn)行傳輸,且可以一邊發(fā)送一邊讀取蜈垮。


Demo地址:https://github.com/XuningZhai/TalkDemo
支持G711的Demo地址:https://github.com/XuningZhai/TalkDemo_G711_AAC

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耗跛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子攒发,更是在濱河造成了極大的恐慌调塌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惠猿,死亡現(xiàn)場(chǎng)離奇詭異羔砾,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)偶妖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)姜凄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人趾访,你說(shuō)我怎么就攤上這事态秧。” “怎么了扼鞋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵申鱼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我云头,道長(zhǎng)捐友,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任盘寡,我火速辦了婚禮楚殿,結(jié)果婚禮上撮慨,老公的妹妹穿的比我還像新娘竿痰。我一直安慰自己脆粥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布影涉。 她就那樣靜靜地躺著变隔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蟹倾。 梳的紋絲不亂的頭發(fā)上匣缘,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音鲜棠,去河邊找鬼肌厨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛豁陆,可吹牛的內(nèi)容都是我干的柑爸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼盒音,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼表鳍!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起祥诽,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤譬圣,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后雄坪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體厘熟,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年诸衔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盯漂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笨农,死狀恐怖就缆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谒亦,我是刑警寧澤竭宰,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站份招,受9級(jí)特大地震影響切揭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锁摔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一廓旬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谐腰,春花似錦孕豹、人聲如沸涩盾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)春霍。三九已至,卻和暖如春叶眉,著一層夾襖步出監(jiān)牢的瞬間址儒,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工衅疙, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莲趣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓饱溢,卻偏偏與公主長(zhǎng)得像妖爷,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子理朋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容