如何将Dart生成的MediaStreamTrack传递给JavaScript第三方WebRTC库?
解决Dart MediaStreamTrack与原生JS WebRTC库兼容的问题
我之前也碰到过一模一样的坑,Dart对Web API的封装确实会把底层原生对象藏得比较深,但其实有几个靠谱的方法能直接解决这个问题:
核心思路
Dart里的MediaStreamTrack(来自dart:html包)本质是对原生JS MediaStreamTrack对象的一层封装,我们要做的不是手动模拟它的方法属性,而是直接拿到被封装的真实原生JS对象——毕竟WebRTC的API在执行构造、关联这类操作时,会严格校验对象的内部类型,手动造的"假"对象根本过不了这关。
方法1:用JsObject.fromBrowserObject(旧版JS互操作)
如果你还在使用旧的dart:js库,直接用这个方法就能把Dart的MediaStreamTrack转成对应的原生JS对象:
import 'dart:js'; import 'dart:html'; void main() async { // 先获取到Dart侧的MediaStreamTrack实例 MediaStreamTrack dartTrack = await window.navigator.mediaDevices.getUserMedia({ 'audio': true, }).then((stream) => stream.getAudioTracks().first); // 转换为原生JS MediaStreamTrack对象 JsObject jsTrack = JsObject.fromBrowserObject(dartTrack); // 现在可以安全传给JS库用了,比如构造MediaStream JsObject jsStream = JsObject(context['MediaStream'], [jsTrack]); }
方法2:用package:js_util(推荐,新版JS互操作)
现在Dart官方更推荐用dart:js_interop和js_util来做JS互操作,步骤也很简单:
- 先在
pubspec.yaml里加依赖:
dependencies: js_util: ^0.1.4 # 可以换成最新版本
- 然后在代码里提取底层原生对象:
import 'dart:html'; import 'package:js_util/js_util.dart'; import 'package:js/js.dart'; // 先定义要调用的JS侧函数(比如第三方WebRTC库的方法) @JS() external MediaStream createMediaStream(MediaStreamTrack track); void main() async { // 获取Dart侧的MediaStreamTrack MediaStreamTrack dartTrack = await window.navigator.mediaDevices.getUserMedia({ 'audio': true, }).then((stream) => stream.getAudioTracks().first); // 拿到底层的原生JS MediaStreamTrack对象 dynamic jsTrack = getProperty(dartTrack, 'nativeElement'); // 直接传给JS函数,此时JS拿到的是真实的原生对象 MediaStream jsStream = createMediaStream(jsTrack as MediaStreamTrack); }
为什么手动映射对象没用?
你之前尝试构造JsObject并映射方法属性的思路,本质是在造一个"高仿"的MediaStreamTrack,但WebRTC的核心API(比如构造MediaStream)会检查对象的内部原型链和类型标识,只有原生JS对象才能通过校验,手动模拟的对象自然会报错。
注意事项
- 确保你的
MediaStreamTrack是来自dart:html包的官方封装,第三方WebRTC库的自定义Track对象可能没有原生对象的引用。 - 如果是Flutter Web项目,要确保第三方JS库已经正确引入到
web/index.html中,并且相关对象挂载到了全局上下文。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

