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

A Flutter plugin for text-to-speech audio file conversion with background processing support.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Audiocraft Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Audiocraft 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 AudioManagerService _audioManager = AudioManagerService();
  final TextEditingController _textController = TextEditingController();

  String _statusText = 'Ready';
  double _conversionProgress = 0.0;
  String _conversionMessage = '';
  Duration _currentPosition = Duration.zero;
  Duration _totalDuration = Duration.zero;
  double _currentSpeed = 1.0;

  @override
  void initState() {
    super.initState();
    _initializeAudioManager();
    _textController.text = 'Hello, this is a test text for audio conversion. '
        'The text-to-speech system will convert this text into an audio file. '
        'You can then play the audio file using the controls below.';
  }

  Future<void> _initializeAudioManager() async {
    await _audioManager.initialize();

    // Setup callbacks
    _audioManager.onConversionProgress = (progress) {
      setState(() {
        _conversionProgress = progress.progress;
        _conversionMessage = progress.message;
      });
    };

    _audioManager.onPlaybackProgress = (progress) {
      setState(() {
        _currentPosition = progress.position;
        _totalDuration = progress.duration;
        _currentSpeed = progress.speed;
      });
    };

    _audioManager.onStateChanged = (state) {
      setState(() {
        _statusText = state.toString().split('.').last;
      });
    };

    _audioManager.onError = (error) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Error: $error')),
      );
    };

    _audioManager.onChapterCompleted = () {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Audio playback completed!')),
      );
    };
  }

  Future<void> _loadChapter() async {
    final text = _textController.text.trim();
    if (text.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Please enter some text')),
      );
      return;
    }

    await _audioManager.loadChapter(
      chapterId: 'test_chapter',
      chapterContent: text,
    );
  }

  Future<void> _playPause() async {
    if (_audioManager.isPlaying) {
      await _audioManager.pause();
    } else {
      await _audioManager.play();
    }
  }

  Future<void> _stop() async {
    await _audioManager.stop();
  }

  Future<void> _setSpeed(double speed) async {
    await _audioManager.setSpeed(speed);
  }

  String _formatDuration(Duration duration) {
    String twoDigits(int n) => n.toString().padLeft(2, '0');
    String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
    String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
    return '${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // Status
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Status: $_statusText', style: Theme.of(context).textTheme.titleMedium),
                    const SizedBox(height: 8),
                    if (_audioManager.isConverting) ...[
                      Text('Conversion: ${(_conversionProgress * 100).toStringAsFixed(1)}%'),
                      const SizedBox(height: 4),
                      LinearProgressIndicator(value: _conversionProgress),
                      const SizedBox(height: 4),
                      Text(_conversionMessage, style: Theme.of(context).textTheme.bodySmall),
                    ],
                    if (_audioManager.isPlaying || _audioManager.isPaused) ...[
                      Text('Position: ${_formatDuration(_currentPosition)} / ${_formatDuration(_totalDuration)}'),
                      const SizedBox(height: 4),
                      LinearProgressIndicator(
                        value: _totalDuration.inMilliseconds > 0 
                            ? _currentPosition.inMilliseconds / _totalDuration.inMilliseconds 
                            : 0.0,
                      ),
                      const SizedBox(height: 4),
                      Text('Speed: ${_currentSpeed}x'),
                    ],
                  ],
                ),
              ),
            ),
            
            const SizedBox(height: 16),
            
            // Text input
            TextField(
              controller: _textController,
              maxLines: 5,
              decoration: const InputDecoration(
                labelText: 'Text to convert',
                border: OutlineInputBorder(),
                hintText: 'Enter the text you want to convert to audio...',
              ),
            ),
            
            const SizedBox(height: 16),
            
            // Convert button
            ElevatedButton(
              onPressed: _audioManager.isConverting ? null : _loadChapter,
              child: Text(_audioManager.isConverting ? 'Converting...' : 'Convert to Audio'),
            ),
            
            const SizedBox(height: 16),
            
            // Playback controls
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        IconButton(
                          onPressed: (_audioManager.isReady || _audioManager.isPlaying || _audioManager.isPaused) 
                              ? _playPause 
                              : null,
                          icon: Icon(_audioManager.isPlaying ? Icons.pause : Icons.play_arrow),
                          iconSize: 32,
                        ),
                        IconButton(
                          onPressed: (_audioManager.isPlaying || _audioManager.isPaused) 
                              ? _stop 
                              : null,
                          icon: const Icon(Icons.stop),
                          iconSize: 32,
                        ),
                      ],
                    ),
                    
                    const SizedBox(height: 16),
                    
                    // Speed control
                    Row(
                      children: [
                        const Text('Speed: '),
                        Expanded(
                          child: Slider(
                            value: _currentSpeed,
                            min: 0.5,
                            max: 2.0,
                            divisions: 6,
                            label: '${_currentSpeed}x',
                            onChanged: _audioManager.isReady || _audioManager.isPlaying || _audioManager.isPaused
                                ? (value) => _setSpeed(value)
                                : null,
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
            
            const Spacer(),
            
            // Cache info
            FutureBuilder<int>(
              future: _audioManager.getCacheSize(),
              builder: (context, snapshot) {
                final cacheSize = snapshot.data ?? 0;
                return Card(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text('Cache Size: ${_audioManager.formatCacheSize(cacheSize)}'),
                        const SizedBox(height: 8),
                        ElevatedButton(
                          onPressed: () async {
                            await _audioManager.clearAllCache();
                            setState(() {});
                            ScaffoldMessenger.of(context).showSnackBar(
                              const SnackBar(content: Text('Cache cleared!')),
                            );
                          },
                          child: const Text('Clear Cache'),
                        ),
                      ],
                    ),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _audioManager.dispose();
    _textController.dispose();
    super.dispose();
  }
}
1
likes
140
points
19
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for text-to-speech audio file conversion with background processing support.

Homepage

Documentation

API reference

License

MIT (license)

Dependencies

audioplayers, ffmpeg_kit_flutter, flutter, flutter_local_notifications, flutter_tts, path, path_provider, record

More

Packages that depend on audiocraft

Packages that implement audiocraft