vitallens_flutter 0.1.0 copy "vitallens_flutter: ^0.1.0" to clipboard
vitallens_flutter: ^0.1.0 copied to clipboard

Flutter plugin for Rouast VitalLens contactless facial physiological vital signs estimation (Heart Rate, HRV, Respiration, rPPG waveforms).

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:vitallens_flutter/vitallens_flutter.dart';

void main() {
  runApp(const VitalLensExampleApp());
}

class VitalLensExampleApp extends StatelessWidget {
  const VitalLensExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'VitalLens Flutter Example',
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: const Color(0xFF0F141C),
        colorScheme: const ColorScheme.dark(
          primary: Color(0xFF00E5FF),
          secondary: Color(0xFF00E676),
        ),
      ),
      home: const ExampleHomeScreen(),
    );
  }
}

class ExampleHomeScreen extends StatefulWidget {
  const ExampleHomeScreen({super.key});

  @override
  State<ExampleHomeScreen> createState() => _ExampleHomeScreenState();
}

class _ExampleHomeScreenState extends State<ExampleHomeScreen> {
  final TextEditingController _keyController = TextEditingController(
    text: const String.fromEnvironment('ROUAST_API_KEY'),
  );

  VitalLensResult? _lastResult;
  bool _isScanning = false;

  @override
  void dispose() {
    _keyController.dispose();
    super.dispose();
  }

  Future<void> _launchScan() async {
    final key = _keyController.text.trim();
    if (key.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Please enter your Rouast VitalLens API Key'),
          backgroundColor: Colors.amber,
        ),
      );
      return;
    }

    setState(() => _isScanning = true);

    final result = await VitalLens.startScan(
      apiKey: key,
      mode: VitalLensMode.eco,
    );

    setState(() {
      _isScanning = false;
      _lastResult = result;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('VitalLens Flutter Example'),
        backgroundColor: const Color(0xFF131A26),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            TextField(
              controller: _keyController,
              obscureText: true,
              decoration: InputDecoration(
                labelText: 'VitalLens API Key',
                hintText: 'Enter API Key from rouast.com',
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(12),
                ),
                prefixIcon: const Icon(Icons.key_rounded),
              ),
            ),
            const SizedBox(height: 16),
            ElevatedButton.icon(
              onPressed: _isScanning ? null : _launchScan,
              icon: _isScanning
                  ? const SizedBox(
                      width: 18,
                      height: 18,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : const Icon(Icons.videocam_rounded),
              label: Text(_isScanning ? 'Scanning...' : 'Start 30s Face Scan'),
              style: ElevatedButton.styleFrom(
                backgroundColor: const Color(0xFF00E5FF),
                foregroundColor: Colors.black,
                padding: const EdgeInsets.symmetric(vertical: 14),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(12),
                ),
              ),
            ),
            const SizedBox(height: 24),
            if (_lastResult != null) ...[
              Card(
                color: const Color(0xFF1B2838),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(16),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(16),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        _lastResult!.isCompleted
                            ? 'Estimation Results'
                            : 'Scan Status: ${_lastResult!.message}',
                        style: const TextStyle(
                          fontSize: 16,
                          fontWeight: FontWeight.bold,
                          color: Color(0xFF00E5FF),
                        ),
                      ),
                      const SizedBox(height: 12),
                      if (_lastResult!.isCompleted) ...[
                        Text(
                          'Heart Rate: ${_lastResult!.heartRate?.toStringAsFixed(1) ?? '--'} BPM',
                          style: const TextStyle(fontSize: 18),
                        ),
                        Text(
                          'HRV (SDNN): ${_lastResult!.hrvSdnn?.toStringAsFixed(1) ?? '--'} ms',
                          style: const TextStyle(fontSize: 18),
                        ),
                        Text(
                          'Respiration: ${_lastResult!.respiratoryRate?.toStringAsFixed(1) ?? '--'} BrPM',
                          style: const TextStyle(fontSize: 18),
                        ),
                        if (_lastResult!.ppgData.isNotEmpty) ...[
                          const SizedBox(height: 16),
                          const Text(
                            'rPPG Pulse Waveform',
                            style: TextStyle(fontSize: 14, color: Colors.white70),
                          ),
                          const SizedBox(height: 8),
                          SizedBox(
                            height: 100,
                            child: PpgWaveformView(
                              dataPoints: _lastResult!.ppgData,
                              strokeColor: const Color(0xFF00E5FF),
                            ),
                          ),
                        ],
                      ],
                    ],
                  ),
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }
}
0
likes
150
points
83
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter plugin for Rouast VitalLens contactless facial physiological vital signs estimation (Heart Rate, HRV, Respiration, rPPG waveforms).

Repository (GitHub)
View/report issues

Topics

#health #camera #computer-vision #vitals #photoplethysmography

License

MIT (license)

Dependencies

flutter

More

Packages that depend on vitallens_flutter

Packages that implement vitallens_flutter