在wkwebview中启用摄像头和麦克风访问

SB2*_*055 6 html5 objective-c ios swift wkwebview

我有一个移动优化的网络应用程序,可用于getUserMedia访问网络摄像头和麦克风资源.

我正在将这个应用程序包装成一个,WKWebView因为我想提供本机应用程序体验.我知道,iOS不允许通过浏览器访问摄像机-但有什么办法来获得权限的网络摄像头/麦克风与本机代码(沿着封装)和饲料这对Web应用程序-也许在某种程度上指向getUserMedia一个本地流源?

Bon*_*uin 8

是的,看一下cordova-plugin-iosrtccordova-plugin-wkwebview-engine.插件背后的想法如下:

1.创建一个JavaScript文件(WebRTC.js),定义各种WebRTC类和函数,并将调用传递给WKWebView,例如:

(function() {
  if (!window.navigator) window.navigator = {};
  window.navigator.getUserMedia = function() {
    webkit.messageHandlers.callbackHandler.postMessage(arguments);
  }
})();
Run Code Online (Sandbox Code Playgroud)

2.在WKWebView中,在文档start处注入脚本:

let contentController = WKUserContentController();
contentController.add(self, name: "callbackHandler")

let script = try! String(contentsOf: Bundle.main.url(forResource: "WebRTC", withExtension: "js")!, encoding: String.Encoding.utf8)
contentController.addUserScript(WKUserScript(source: script, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: true))

let config = WKWebViewConfiguration()
config.userContentController = contentController

webView = WKWebView(frame: CGRect.zero, configuration: config)
Run Code Online (Sandbox Code Playgroud)

3.侦听从JavaScript发送的消息:

class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler {
  var webView: WKWebView!

  func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    if message.name == "callbackHandler" {
      print(message.body)
      // make native calls to the WebRTC framework here
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

4.如果需要在JavaScript-land中执行成功或失败回调,请直接在WKWebView中评估函数调用:

webView.evaluateJavaScript("callback({id: \(id), status: 'success', args: ...})", completionHandler: nil)
Run Code Online (Sandbox Code Playgroud)

这些回调需要调用之前存储在JavaScript中的哈希值中postMessage,然后必须将哈希键发送到WKWebView.这是commandId插件中的内容.

int exec_id = 0;
function exec(success, failure, ...) {
  // store the callbacks for later
  if (typeof success == 'function' || typeof failure == 'function') {
    exec_id++;
    exec_callbacks[exec_id] = { success: success, failure: failure };
    var commandId = exec_id;
  }
  webkit.messageHandlers.callbackHandler.postMessage({id: commandId, args: ...})
}

// the native code calls this directly with the same commandId, so the callbacks can be performed and released
function callback(opts) {
  if (opts.status == "success") {
    if (typeof exec_callbacks[opts.id].success == 'function') exec_callbacks[opts.id].success(opts.args);
  } else {
    if (typeof exec_callbacks[opts.id].failure == 'function') exec_callbacks[opts.id].failure(opts.args);
  }
  // some WebRTC functions invoke the callbacks multiple times
  // the native Cordova plugin uses setKeepCallbackAs(true)
  if (!opts.keepalive) delete exec_callbacks[opts.id];
}
Run Code Online (Sandbox Code Playgroud)

5.当然,为项目添加NSCameraUsageDescriptionNSMicrophoneUsageDescription权限Info.plist.

请记住,这是一项非常重要的任务,但这是使用异步回调桥接JavaScript,WKWebView和本机框架代码的总体思路.

  • 你有例子吗?我正在尝试这样做,但没有成功 (4认同)
  • 您能否发布示例代码,这将非常有帮助。 (2认同)