jjzjj

javascript - 在 Web View 中将视频流从 iOS7 摄像头发送到 JavaScript Canvas

coder 2024-01-19 原文

首先提醒一句:这个问题不适合胆小的人。这是我最近遇到的一个有趣的挑战。看看您是否可以解决它或以任何方式帮助更接近答案,风险自负。

问题是:创建一个内部有标准 UIWebView 的 iOS 应用程序。从任一摄像头获取摄像头流。以可以呈现到 HTML5 Canvas 中的格式发送每个帧。有效地实现这一点,以便视频流可以在 iOS7 设备中以 720p 30fps 或更高的速度显示。

到目前为止,我还没有找到任何看起来有希望的解决方案。事实上,我从看起来最可笑的解决方案开始,它在 base64 图像字符串中对每个帧进行编码,然后通过 stringByEvaluatingJavaScriptFromString 将其传递给 Web View 。这是进行 JPEG 编码的方法

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

viewDidLoad 中,我创建并配置了捕获 session

_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正在运行我们的内存配额吗?我应该注意到,就在崩溃之前,应用内存使用量出现了一个大峰值。它会在 14MB 到 20MB 以上的任何地方崩溃,具体取决于为 JPEG 编码设置的质量级别。

我不想在本地渲染相机流——这根本不是一个有趣的问题。我想将视频提要传递给 JavaScript land 并将其绘制在 Canvas 中。

为了您的方便,我有一个 minimal demo project (XCode) on github你可以用它来获得快速的开端:

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

如果您有其他更明智的想法来传递数据而不是使用 stringByEvaluatingJavaScriptFromString,请告诉我。如果您有其他想法或建议,请随时在评论中告诉我,但我希望答案能够用一些代码来证明什么路径可行。

最佳答案

您遇到的崩溃是由于 UIWebKit 试图从后台线程调用 UIKit。防止这种情况发生的最简单方法是强制调用 UIKit 的 stringByEvaluatingJavaScriptFromString 在主线程中运行。您可以通过更改

[self.webView stringByEvaluatingJavaScriptFromString:_base64imgCmd];

为此

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

现在将从主执行线程调用 UIKit,这将是安全的。

关于javascript - 在 Web View 中将视频流从 iOS7 摄像头发送到 JavaScript Canvas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21327208/

有关javascript - 在 Web View 中将视频流从 iOS7 摄像头发送到 JavaScript Canvas的更多相关文章

  1. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  4. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  5. ruby - 未定义的方法 auto_upgrade!将 Sinatra/DataMapper 应用程序推送到 Heroku 时 - 2

    有谁知道在Heroku的Bamboo堆栈上启动并运行使用DataMapper的Sinatra应用程序所需的魔法咒语?Bamboo堆栈不包含任何预安装的系统gem,无论我尝试使用何种gem组合,我都会不断收到此错误:undefinedmethod`auto_upgrade!'forDataMapper:Module(NoMethodError)这是我的.gems文件中的内容:sinatrapgdatamapperdo_postgresdm-postgres-adapter这些是我将应用程序推送到Heroku时安装的依赖项:----->Herokureceivingpush----->Si

  6. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  7. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  8. ruby-on-rails - Ruby on Rails - 需要在每周的特定时间将消息发送到电子邮件 - 2

    我想知道我应该如何着手这个项目。我需要每周向人们发送一次电子邮件。但是,这必须在每周的特定时间自动生成并发送。编码有多难?我需要知道是否有任何书籍可以提供帮助,或者你们中的任何人是否可以指导我。它必须使用ruby​​onrails进行编程。因此有一个网络服务和数据库集成。干杯 最佳答案 为什么这么复杂?您只需安排工作。您可以使用Delayed::Job例如。Delayed::Job让您可以使用run_at符号在特定时间安排作业,如下所示:Delayed::Job.enqueue(SendEmailJob.new(...),:run_

  9. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  10. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

随机推荐