feat: 添加 WebSocket、WebRTC 与 Protobuf 支持
This commit is contained in:
131
lib/test_page.dart
Normal file
131
lib/test_page.dart
Normal file
@@ -0,0 +1,131 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||
|
||||
class TestPage extends StatefulWidget {
|
||||
const TestPage({super.key});
|
||||
|
||||
@override
|
||||
State<TestPage> createState() => _TestPageState();
|
||||
}
|
||||
|
||||
class _TestPageState extends State<TestPage> {
|
||||
final TextEditingController _controller = TextEditingController();
|
||||
WebSocketChannel? _channel;
|
||||
final List<String> _messages = [];
|
||||
|
||||
final RTCVideoRenderer _localRenderer = RTCVideoRenderer();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
initRenderers();
|
||||
}
|
||||
|
||||
Future<void> initRenderers() async {
|
||||
await _localRenderer.initialize();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_channel?.sink.close();
|
||||
_localRenderer.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _connectWebSocket() {
|
||||
final url = _controller.text.trim();
|
||||
if (url.isNotEmpty) {
|
||||
setState(() {
|
||||
_channel = WebSocketChannel.connect(Uri.parse(url));
|
||||
_messages.clear();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _sendMessage() {
|
||||
if (_channel != null) {
|
||||
_channel!.sink.add('Hello from Flutter!');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _startWebRTC() async {
|
||||
final Map<String, dynamic> mediaConstraints = {
|
||||
'audio': true,
|
||||
'video': {
|
||||
'facingMode': 'user',
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
MediaStream stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
|
||||
_localRenderer.srcObject = stream;
|
||||
setState(() {});
|
||||
} catch (e) {
|
||||
print('Error getting user media: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('WebSocket & WebRTC Test'),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
TextField(
|
||||
controller: _controller,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'WebSocket URL (e.g. ws://echo.websocket.org)',
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: _connectWebSocket,
|
||||
child: const Text('Connect'),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
ElevatedButton(
|
||||
onPressed: _sendMessage,
|
||||
child: const Text('Send Message'),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: StreamBuilder(
|
||||
stream: _channel?.stream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
_messages.add(snapshot.data.toString());
|
||||
}
|
||||
return ListView.builder(
|
||||
itemCount: _messages.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text(_messages[index]),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
const Text('WebRTC Test:'),
|
||||
ElevatedButton(
|
||||
onPressed: _startWebRTC,
|
||||
child: const Text('Start Camera'),
|
||||
),
|
||||
SizedBox(
|
||||
height: 200,
|
||||
child: RTCVideoView(_localRenderer),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user