video_windows_live 0.0.3
video_windows_live: ^0.0.3 copied to clipboard
Um plugin sobre video para Windows
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:video_windows_live/video_player_vms.dart';
void main() {
runApp(
const MaterialApp(
home: VMSStressTestApp(),
debugShowCheckedModeBanner: false,
),
);
}
class VMSStressTestApp extends StatefulWidget {
const VMSStressTestApp({super.key});
@override
State<VMSStressTestApp> createState() => _VMSStressTestAppState();
}
class _VMSStressTestAppState extends State<VMSStressTestApp> {
final int rows = 5;
final int cols = 5;
late final List<VideoPlayerVMSController> _controllers;
late final List<TextEditingController> _urlControllers;
@override
void initState() {
super.initState();
int total = rows * cols;
_controllers = List.generate(total, (_) => VideoPlayerVMSController());
_urlControllers = List.generate(total, (index) {
return TextEditingController(text: linkVideo(index));
});
_initializePlayers();
}
String linkVideo(int index) {
List<String> links = [
"https://live35.analitico.app.br/stream/get/homologacaopt00.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live36.analitico.app.br/stream/get/associacaodas00.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live36.analitico.app.br/stream/get/associacaodas01.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://c.vms.tutorsa.cloud/stream/get/associacaodas02.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://c.vms.tutorsa.cloud/stream/get/associacaodas03.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor06.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor07.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor08.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor11.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor12.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor13.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor14.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live12.analitico.app.br/stream/get/associacaomor20.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live9.analitico.app.br/stream/get/associacaomor18.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live12.analitico.app.br/stream/get/associacaomor19.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live23.analitico.app.br/stream/get/associacaomor23.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live23.analitico.app.br/stream/get/associacaomor24.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live26.analitico.app.br/stream/get/associacaomor25.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor00.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor01.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor02.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor03.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live3.analitico.app.br/stream/get/associacaomor04.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live8.protenet.com.br/stream/get/associacaomor21.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
"https://live42.analitico.app.br/stream/get/atacadaolivre02.m3u8?token=nSX45IJaVe0kP2TuUMh9ud8Xbf0wkw",
];
return links[index % links.length];
}
Future<void> _initializePlayers() async {
for (var controller in _controllers) {
await controller.initialize();
}
}
@override
void dispose() {
for (var controller in _controllers) {
controller.dispose();
}
for (var urlController in _urlControllers) {
urlController.dispose();
}
super.dispose();
}
void _playAll() {
for (int i = 0; i < _controllers.length; i++) {
if (_controllers[i].status == VideoPlayerStatus.idle ||
_controllers[i].status == VideoPlayerStatus.error) {
_controllers[i].play(_urlControllers[i].text);
}
}
}
void _stopAll() {
for (int i = 0; i < _controllers.length; i++) {
_controllers[i].stop();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('VMS Stress Test - 36 Cameras (6x6)'),
backgroundColor: Colors.blueGrey[900],
foregroundColor: Colors.white,
actions: [
IconButton(
icon: const Icon(Icons.play_arrow),
onPressed: _playAll,
tooltip: 'Play All',
),
IconButton(
icon: const Icon(Icons.stop),
onPressed: _stopAll,
tooltip: 'Stop All',
),
],
),
backgroundColor: Colors.black,
body: Column(
children: List.generate(rows, (row) {
return Expanded(
child: Row(
children: List.generate(cols, (col) {
int index = row * cols + col;
return Expanded(
child: Padding(
padding: const EdgeInsets.all(1.0),
child: PlayerCell(
controller: _controllers[index],
urlController: _urlControllers[index],
index: index,
),
),
);
}),
),
);
}),
),
);
}
}
class PlayerCell extends StatelessWidget {
final VideoPlayerVMSController controller;
final TextEditingController urlController;
final int index;
const PlayerCell({
super.key,
required this.controller,
required this.urlController,
required this.index,
});
@override
Widget build(BuildContext context) {
return ListenableBuilder(
listenable: controller,
builder: (context, _) {
return GestureDetector(
onTap: () {
if (controller.status == VideoPlayerStatus.idle ||
controller.status == VideoPlayerStatus.error) {
controller.play(urlController.text);
} else {
controller.stop();
}
},
child: Container(
decoration: BoxDecoration(
color: Colors.grey[900],
border: Border.all(
color: _getStatusColor(controller.status),
width: 1,
),
),
child: Stack(
children: [
ClipRect(
child: SizedBox.expand(
child: FittedBox(
fit: BoxFit.cover,
child: SizedBox(
width: 1280,
height: 720,
child: VideoPlayerVMS(controller: controller),
),
),
),
),
Positioned.fill(child: _buildOverlay()),
Positioned(
top: 2,
left: 2,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 2,
),
color: Colors.black54,
child: Text(
"CAM ${index + 1}",
style: const TextStyle(color: Colors.white, fontSize: 10),
),
),
),
],
),
),
);
},
);
}
Widget _buildOverlay() {
switch (controller.status) {
case VideoPlayerStatus.buffering:
return Container(
color: Colors.black38,
child: const Center(
child: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(Colors.orangeAccent),
),
),
),
);
case VideoPlayerStatus.idle:
return Container(
color: Colors.black26,
child: Center(
child: Icon(
Icons.play_circle_fill,
size: 30,
color: Colors.white.withOpacity(0.8),
),
),
);
case VideoPlayerStatus.error:
return Container(
color: Colors.black54,
child: const Center(
child: Icon(Icons.error, color: Colors.redAccent, size: 30),
),
);
case VideoPlayerStatus.playing:
default:
return const SizedBox.shrink();
}
}
Color _getStatusColor(VideoPlayerStatus status) {
switch (status) {
case VideoPlayerStatus.playing:
return Colors.greenAccent.withOpacity(0.5);
case VideoPlayerStatus.buffering:
return Colors.orangeAccent.withOpacity(0.5);
case VideoPlayerStatus.error:
return Colors.redAccent.withOpacity(0.5);
case VideoPlayerStatus.idle:
default:
return Colors.white24;
}
}
}