flutter_freedome_player 1.1.1 copy "flutter_freedome_player: ^1.1.1" to clipboard
flutter_freedome_player: ^1.1.1 copied to clipboard

Flutter plugin for playing 3D/AR/VR content and various media formats including .comics, .boranko, collada and others. Supports both screen display and dome projections.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FreeDome Player Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'FreeDome Player Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final FreeDomePlayer _player = FreeDomePlayer();
  String _platformVersion = 'Unknown';
  Map<String, bool> _capabilities = {};
  FreeDomePlayerController? _controller;

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    String platformVersion;
    Map<String, bool> capabilities;

    try {
      platformVersion =
          await _player.getPlatformVersion() ?? 'Unknown platform version';
      capabilities = await _player.getPlatformCapabilities();
    } catch (e) {
      platformVersion = 'Failed to get platform version: $e';
      capabilities = {};
    }

    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
      _capabilities = capabilities;
    });
  }

  void _loadComicsExample() {
    final content = FreeDomePlayer.createMediaContent(
      filePath: 'assets/comics/example.comics',
      name: 'Mahabharata Chapter 1',
      format: MediaFormat.comics,
      description: 'Первая глава великого эпоса Махабхарата',
      author: 'Игорь Баранько, Алексей Чебыкин',
    );

    setState(() {
      _controller = _player.createController(PlayerConfig.defaultComics);
      _controller!.loadMediaContent(content);
    });
  }

  void _load3DExample() {
    final content = FreeDomePlayer.createMediaContent(
      filePath: 'assets/models/example.dae',
      name: 'Buddha Meditation',
      format: MediaFormat.collada,
      description: 'Sacred Buddha model for meditation and AR experiences',
      author: 'Android Jones & Samskara Team',
    );

    setState(() {
      _controller = _player.createController(PlayerConfig.default3D);
      _controller!.loadMediaContent(content);
    });
  }

  void _loadBorankoExample() {
    final content = FreeDomePlayer.createMediaContent(
      filePath: 'assets/boranko/example.boranko',
      name: 'Quantum Meditation',
      format: MediaFormat.boranko,
      description:
          'Квантовый контент с резонансом 108 Hz для купольной проекции',
      author: 'FreeDome Quantum Team',
      playbackMode: PlaybackMode.dome,
    );

    final domeConfig = DomeConfig(
      projectionType: DomeProjectionType.fisheye,
      quantumProperties: QuantumProperties(
        resonanceFrequency: 108.0,
        interferencePattern: 'spiritual',
        consciousnessLevel: 'meditation',
      ),
    );

    setState(() {
      _controller = _player.createController(
        PlayerConfig.domeProjection(domeConfig),
      );
      _controller!.loadMediaContent(content);
    });
  }

  void _loadObjExample() {
    final content = FreeDomePlayer.createMediaContent(
      filePath: 'assets/models/simple_cube.obj',
      name: 'Simple Cube',
      format: MediaFormat.obj,
      description: 'Simple OBJ cube for testing',
    );

    setState(() {
      _controller = _player.createController(PlayerConfig.default3D);
      _controller!.loadMediaContent(content);
    });
  }

  void _loadGltfExample() {
    final content = FreeDomePlayer.createMediaContent(
      filePath: 'assets/models/triangle.gltf',
      name: 'glTF Triangle',
      format: MediaFormat.gltf,
      description: 'Modern glTF format demonstration',
    );

    setState(() {
      _controller = _player.createController(PlayerConfig.default3D);
      _controller!.loadMediaContent(content);
    });
  }

  void _clearContent() {
    setState(() {
      _controller?.clearContent();
      _controller = null;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: _controller != null ? _buildPlayer() : _buildMainMenu(),
    );
  }

  Widget _buildMainMenu() {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Информация о платформе
          Card(
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'Platform Information',
                    style: Theme.of(context).textTheme.titleLarge,
                  ),
                  const SizedBox(height: 8),
                  Text('Version: $_platformVersion'),
                  const SizedBox(height: 8),
                  Text(
                    'Capabilities:',
                    style: Theme.of(context).textTheme.titleMedium,
                  ),
                  ..._capabilities.entries.map(
                    (entry) => Row(
                      children: [
                        Icon(
                          entry.value ? Icons.check_circle : Icons.cancel,
                          color: entry.value ? Colors.green : Colors.red,
                          size: 16,
                        ),
                        const SizedBox(width: 8),
                        Text('${entry.key}: ${entry.value}'),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),

          const SizedBox(height: 20),

          // Поддерживаемые форматы
          Card(
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'Supported Formats',
                    style: Theme.of(context).textTheme.titleLarge,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: _player
                        .getSupportedFormats()
                        .map(
                          (format) => Chip(label: Text(format.toUpperCase())),
                        )
                        .toList(),
                  ),
                ],
              ),
            ),
          ),

          const SizedBox(height: 20),

          // Примеры контента
          Text('Examples', style: Theme.of(context).textTheme.titleLarge),
          const SizedBox(height: 16),

          // Кнопки примеров
          Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              ElevatedButton.icon(
                onPressed: _loadComicsExample,
                icon: const Icon(Icons.menu_book),
                label: const Text('Comics (.comics) - Mahabharata Ch1'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.orange,
                  foregroundColor: Colors.white,
                ),
              ),
              const SizedBox(height: 8),
              ElevatedButton.icon(
                onPressed: _load3DExample,
                icon: const Icon(Icons.account_balance),
                label: const Text('COLLADA (.dae) - Buddha Model'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                ),
              ),
              const SizedBox(height: 8),
              ElevatedButton.icon(
                onPressed: _loadObjExample,
                icon: const Icon(Icons.category),
                label: const Text('OBJ (.obj) - Simple Cube'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.green,
                  foregroundColor: Colors.white,
                ),
              ),
              const SizedBox(height: 8),
              ElevatedButton.icon(
                onPressed: _loadGltfExample,
                icon: const Icon(Icons.auto_awesome),
                label: const Text('glTF (.gltf) - Triangle'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.purple,
                  foregroundColor: Colors.white,
                ),
              ),
              const SizedBox(height: 8),
              ElevatedButton.icon(
                onPressed: _loadBorankoExample,
                icon: const Icon(Icons.psychology),
                label: const Text('Boranko (.boranko) - Quantum'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.deepPurple,
                  foregroundColor: Colors.white,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildPlayer() {
    return Stack(
      children: [
        // Основной плеер
        FreeDomePlayerWidget(
          content: _controller!.currentContent,
          config: _controller!.config,
          showControls: true,
          autoPlay: false,
          onContentLoaded: () {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(
                content: Text('Контент загружен успешно!'),
                backgroundColor: Colors.green,
              ),
            );
          },
          onError: (error) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text('Ошибка: $error'),
                backgroundColor: Colors.red,
              ),
            );
          },
        ),

        // Кнопка "Назад"
        Positioned(
          top: 40,
          left: 16,
          child: FloatingActionButton(
            heroTag: "back_button",
            mini: true,
            onPressed: _clearContent,
            backgroundColor: Colors.black.withOpacity(0.7),
            child: const Icon(Icons.arrow_back, color: Colors.white),
          ),
        ),
      ],
    );
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }
}