学习WebRTC的基本概念。
在此之前,我尝试了HTML和JS:
<!DOCTYPE html>
<html>
<head>
<title>Basic WebRTC Page</title>
<style>
video {
border: 1px solid black;
--width: 25%;
width: var(--width);
height: calc(var(--width) * 0.75);
margin: 0 0 20px 0;
vertical-align: top;
}
</style>
</head>
<body>
<video id="local" autoplay></video>
<video id="remote" autoplay></video>
<script charset="utf-8">
const alice = new RTCPeerConnection();
const bob = new RTCPeerConnection();
alice.onicecandidate = e => {
if (e.candidate) {
bob.addIceCandidate(e.candidate);
}
}
bob.onicecandidate = e => {
if (e.candidate) {
alice.addIceCandidate(e.candidate);
}
}
navigator.mediaDevices.getUserMedia({
video: true
})
.then(stream => {
document.getElementById('local').srcObject = stream;
alice.addStream(stream);
return alice.createOffer();
})
.then(offer => alice.setLocalDescription(new RTCSessionDescription(offer)))
.then(() => bob.setRemoteDescription(alice.localDescription))
.then(() => bob.createAnswer())
.then(answer => bob.setLocalDescription(new RTCSessionDescription(answer)))
.then(() => alice.setRemoteDescription(bob.localDescription));
bob.ontrack = e => {
document.getElementById("remote").srcObject = e.streams[0];
}
</script>
</body>
</html>
这段代码在Web浏览器上工作没有任何问题。
现在,将该代码移植到flutter项目:
import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
void main() {
runApp(BasicApplication());
}
class BasicApplication extends StatelessWidget {
const BasicApplication({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late RTCPeerConnection alice;
late RTCPeerConnection bob;
MediaStream? localStream;
late RTCVideoRenderer localRenderer;
late RTCVideoRenderer remoteRenderer;
@override
void initState() {
super.initState();
localRenderer = RTCVideoRenderer();
remoteRenderer = RTCVideoRenderer();
initWebRTC();
}
Future<void> initWebRTC() async {
try {
await localRenderer.initialize();
await remoteRenderer.initialize();
final mediaStream = await navigator.mediaDevices.getUserMedia({
'audio': false,
'video': true,
});
print('Local stream has ${mediaStream.getVideoTracks().length} video tracks');
alice = await createPeerConnection({});
bob = await createPeerConnection({});
localRenderer.srcObject = mediaStream;
setState(() {
localStream = mediaStream;
});
bob.onTrack = (event) {
setState(() {
remoteRenderer.srcObject = event.streams.first;
});
};
final offer = await alice.createOffer({});
await alice.setLocalDescription(offer);
await bob.setRemoteDescription(offer);
final answer = await bob.createAnswer({});
await bob.setLocalDescription(answer);
await alice.setRemoteDescription(answer);
} catch (error) {
print(error);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WebRTC Page'),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.black ,
border: Border.all(color: Colors.black),
),
margin: EdgeInsets.all(20),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RTCVideoView(
remoteRenderer,
objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
mirror: true,
placeholderBuilder: (BuildContext context) {
return Container(
color: Colors.grey,
child: Center(
child: Text('Waiting for remote video...'),
),
);
},
),
),
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
),
margin: EdgeInsets.all(20),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RTCVideoView(
localRenderer,
objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
placeholderBuilder: (BuildContext context) {
return Container(
color: Colors.grey,
child: Center(
child: Text('Waiting for local video...'),
),
);
},
),
),
),
),
],
),
),
);
}
@override
void dispose() {
localRenderer.dispose();
remoteRenderer.dispose();
alice.close();
bob.close();
super.dispose();
}
}
任何人都可以向我解释为什么在chrome浏览器localRenderer返回我的网络摄像头图像,但remoterendered不能正常工作!
我的代码哪部分错了
1条答案
按热度按时间m1m5dgzv1#
修复了我在initWebRTC()方法中忘记的一些事情: