2014-01-24 61 views
1

首先一個字謹慎:這個問題是不適合心臟虛弱。這是我最近遇到的一個有趣的挑戰。看看你是否可以解決它或幫助以任何方式接近答案,風險自負。從iOS7攝像頭髮送視頻流畫布的JavaScript Web視圖中

這裏的問題是:與內部標準UIWebView創建iOS應用程序。從任一相機獲取相機流。以可以呈現爲HTML5畫布的格式發送每個幀。使這有效地發生,使視頻流可在30fps的720P或更高在iOS7設備顯示。

到目前爲止,我還沒有發現,看promissing任何解決方案。事實上,我開始看上去被編碼的base64圖像串中的每個幀,並且經由stringByEvaluatingJavaScriptFromString它傳遞給web視圖最ridiculus該溶液中。下面是確實JPEG編碼

- (NSString *)encodeToBase64StringJPEG:(UIImage *)image { 
    return [UIImageJPEGRepresentation(image, 0.7) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; 
} 

我創建viewDidLoad內並配置捕獲會話

_output = [[AVCaptureVideoDataOutput alloc] init]; 

// create a queue to run the capture on 
dispatch_queue_t captureQueue=dispatch_queue_create("captureQueue", NULL); 

// setup output delegate 
[_output setSampleBufferDelegate:self queue:captureQueue]; 

// configure the pixel format (could this be the problem? Is this suitable for JPEG? 
_output.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey, nil]; 
[_session addOutput:_output]; 
[_session startRunning]; 

幀被捕獲並轉換爲UIImage第一方法。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection { 
    _image = imageFromSampleBuffer(sampleBuffer); 

    // here comes the ridiculus part. Attempt to encode the whole image and send it to JS land: 
    _base64imgCmd = [NSString stringWithFormat:@"draw('data:image/png;base64,%@');", [self encodeToBase64StringJPEG:_image]]; 
     [self.webView stringByEvaluatingJavaScriptFromString:_base64imgCmd]; 
} 

猜猜看,它沒有工作。 XCode向我顯示這個錯誤:

DemoNativeToJS[3983:1803] bool _WebTryThreadLock(bool), 0x15e9d460: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now... 
1 0x355435d3 WebThreadLock 
2 0x3013e2f9 <redacted> 
3 0x7c3a1 -[igViewController captureOutput:didOutputSampleBuffer:fromConnection:] 
4 0x2c5bbe79 <redacted> 

這是錯誤,因爲WebView運行我們的內存qouta?我應該注意到,崩潰之前應用程序內存使用量出現大幅增長。根據爲JPEG編碼設置的質量級別,它會在14MB到20MB之間的任何地方崩潰。

enter image description here

我不想使相機流原住民 - 這不會是一個有趣的問題都沒有。我想將視頻源傳遞給JavaScript land並在畫布內繪製。

爲了您的方便,我有一個minimal demo project (XCode) on github,你可以用它來獲得一個guick領先地位:

git clone https://github.com/arasbm/DemoNativeToJS.git 

請讓我知道,如果你有通過傳遞數據,而不是使用stringByEvaluatingJavaScriptFromString其他更理智的想法。如果您有其他想法或建議,請隨時通過評論讓我知道,但我希望答案能夠用一些代碼演示哪些路徑可行。

回答

1

您遇到的崩潰是由於UIWebKit試圖從後臺線程調用UIKit。防止這種情況發生的最簡單方法是強制stringByEvaluatingJavaScriptFromString調用UIKit以在主線程中運行。你可以通過改變

[self.webView stringByEvaluatingJavaScriptFromString:_base64imgCmd]; 

對此

[self.webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:_base64imgCmd waitUntilDone:NO]; 

現在將在主執行線程,這將是安全的UIKit調用做到這一點。

+0

我現在在畫布上看到的視頻大約是5FPS,並不理想,但它向前邁進了一大步。謝謝! – Aras