一、前景介紹

設(shè)備.png

效果.gif
- 任務(wù)前提:上面這個硬件打開開關(guān)后開啟Wi-Fi,電腦連接上這個Wi-Fi,在網(wǎng)頁中輸入設(shè)備給定的IP地址就能看到設(shè)備攝像頭里面的實時畫面
- 任務(wù)目標:要求手機連接上Wi-Fi后,app能夠獲取到硬件實時視頻,并且可以對視頻內(nèi)容朝向進行操作!
設(shè)備發(fā)出視頻流的原理和使用 multipart/x-mixed-replace 實現(xiàn) http 實時視頻流類似,就是硬件攝像頭通過取幀的方式,間隔一段時間從攝像頭讀取當(dāng)前圖像,連續(xù)多張圖就構(gòu)成了一個視頻(這個設(shè)備是每秒30幀)。通過 stream 形式,將圖片通過 http 協(xié)議輸出到客戶端,要客戶端支持 multipart/x-mixed-replace 頭,就可以從響應(yīng)中讀取視頻幀。
二、OC對接數(shù)據(jù)
一開始也沒想明白怎么去對接這種數(shù)據(jù),我們平時寫app的時候基本上都是將AFN封裝一下就使用了,沒有像這種連接一次可以多次獲取到數(shù)據(jù)的方式。實在沒招就想到了iOS自有的NSURLSession網(wǎng)絡(luò)請求方式去嘗試了,一開始走了很多的彎路,也不多說了,我們直接進主題。
選擇創(chuàng)建session對象的方式:
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id <NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue;
這里就是普通的session請求任務(wù),只不過請求的結(jié)果不是一次性接收就完了,而是一次請求后能夠多次接收值,所以采用NSURLSessionDataTask里面的dataTaskWithURL方法:
-(NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
數(shù)據(jù)請求的完整代碼:
//獲取圖片流
- (void )loadInputStream{
NSURL *url = [NSURL URLWithString:@"http:/***"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"GET"];
session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
dataTask = [session dataTaskWithRequest:request];
[dataTask resume];
}
代理方法有四個:
//1.接收到服務(wù)器響應(yīng)的時候調(diào)用
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{
NSLog(@"接收響應(yīng)");
//必須告訴系統(tǒng)是否接收服務(wù)器返回的數(shù)據(jù)
//默認是completionHandler(NSURLSessionResponseAllow)
//可以再這邊通過響應(yīng)的statusCode來判斷否接收服務(wù)器返回的數(shù)據(jù)
completionHandler(NSURLSessionResponseAllow);
}
//2.接受到服務(wù)器返回數(shù)據(jù)的時候調(diào)用,可能被調(diào)用多次
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
NSLog(@"接收到數(shù)據(jù)");
}
//3.請求完成或者是失敗的時候調(diào)用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error{
NSLog(@"請求完成或者是失敗");
//在這邊進行完整數(shù)據(jù)的解析,回調(diào)
}
//4.將要緩存響應(yīng)的時候調(diào)用(必須是默認會話模式,GET請求才可以)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
willCacheResponse:(NSCachedURLResponse *)proposedResponse
completionHandler:(void (^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler{
//可以在這邊更改是否緩存,默認的話是completionHandler(proposedResponse)
//不想緩存的話可以設(shè)置completionHandler(nil)
completionHandler(proposedResponse);
}
當(dāng)下網(wǎng)絡(luò)請求的情況是,一次請求完多次返回值,但沒有結(jié)束點,所以上面的代理方法,只是用到了前兩種。這里也有點坑,結(jié)束的方法不會進,我怎么知道這張圖片什么時候才是一張完整的圖片呢,然后就換了種思路,在每次開始接收數(shù)據(jù)的時候,不正是上張圖接收完整的時候嗎。

完整代碼.png

最終效果.gif