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