runwayml_flutter 0.0.4 copy "runwayml_flutter: ^0.0.4" to clipboard
runwayml_flutter: ^0.0.4 copied to clipboard

A Flutter package that provides a Dart wrapper for the RunwayML API, enabling integration of AI-generated content into Flutter apps.

example/lib/main.dart

// ignore_for_file: depend_on_referenced_packages

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:runwayml_flutter/runwayml_flutter.dart';

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

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

  @override
  AppWidgetState createState() => AppWidgetState();
}

class AppWidgetState extends State<AppWidget> {
// This will be used to interact with the RunwayML API and perform video generation tasks.
  late RunwayMLClient client;

// This is a controller for the video player. It's used to initialize and control the video playback once the video URL is retrieved.
  VideoPlayerController? _videoPlayerController;

// This holds the URL of the video that will be generated and shown in the UI once the task is complete.
  String? videoUrl;

// This holds the unique task ID that is used to track the status of the video generation task.
  String? taskId;

// This holds the current progress as a string, which will be used to show percentage or status updates (e.g., "50%" or "Initializing...").
  String? progressText;

// A boolean flag to track whether the video generation is in progress and loading.
  bool isLoading = false;

// A boolean flag to track whether the task cancellation process is in progress, so we avoid multiple cancel clicks.
  bool isCanceling = false;

// A boolean flag to track whether the video generation process is ongoing. This ensures the generate button isn't tapped repeatedly.
  bool isGenerating = false;

// A boolean flag to track whether the app is polling for updates from the API regarding the task status.
  bool isPolling = false;

  @override
  void initState() {
    super.initState();
    // apiKey starts with 'key_'
    client = RunwayMLClient(apiKey: 'YOUR_API_KEY');
  }

  void generateVideo() async {
    setState(() {
      isLoading = true;
      isCanceling = false;
      isGenerating = true;
      videoUrl = null;
      taskId = null;
      progressText = '';
    });

    try {
      final TaskResponse response = await client.generateVideo(
        promptImageUrl: 'https://i.ibb.co/21mkFGSL/efefluter.jpg',
        model: 'gen3a_turbo',
        seed: 42,
        promptText:
            'A dynamic shot of a young developer jumping with excitement, holding a Flutter Dash toy in one hand and a business card in the other. A Flutter Dart flag flutters from his pocket, caught by the breeze. Behind him, a digital development board flashes with changing lines of code, with neon lighting creating an energetic, cinematic glow around him, emphasizing the forward motion and passion for tech.',
        watermark: false,
        duration: 5,
        ratio: '1280:768',
      );

      setState(() {
        taskId = response.id;
      });

      await checkTaskStatus();
    } catch (e) {
      setState(() {
        videoUrl = 'Error: $e';
      });
    } finally {
      setState(() {
        isLoading = false;
        isGenerating = false;
      });
    }
  }

  Future<void> checkTaskStatus() async {
    isPolling = true;

    while (isPolling && taskId != null) {
      try {
        final TaskStatusResponse statusResponse =
            await client.getTaskStatus(taskId!);

        setState(() {
          progressText = statusResponse.progress == null
              ? '0.0%'
              : '${statusResponse.progress}%';
        });

        if (statusResponse.status == 'SUCCEEDED') {
          setState(() {
            videoUrl = statusResponse.output?.first;
            isPolling = false;
            progressText = null;
          });

          if (videoUrl != null) {
            _videoPlayerController =
                VideoPlayerController.networkUrl(Uri.parse(videoUrl!))
                  ..initialize().then((_) {
                    setState(() {
                      _videoPlayerController?.setLooping(true);
                    });
                    _videoPlayerController?.play();
                  });
          }

          break;
        } else if (statusResponse.status == 'FAILED') {
          setState(() {
            videoUrl = 'Video generation failed';
            isPolling = false;
            progressText = null;
          });

          break;
        }

        await Future.delayed(const Duration(seconds: 3));
      } catch (e) {
        setState(() {
          videoUrl = 'Error checking task status: $e';
          isPolling = false;
          progressText = null;
        });

        break;
      }
    }
  }

  Future<void> cancelTask() async {
    if (taskId == null || isCanceling) return;

    setState(() {
      isCanceling = true;
      progressText = 'Canceling...';
    });

    try {
      await client.deleteTask(taskId!);
      setState(() {
        videoUrl = 'Task canceled successfully.';
        taskId = null;
        isPolling = false;
        progressText = null;
      });
    } catch (e) {
      setState(() {
        videoUrl = 'Error canceling task: $e';
        progressText = null;
      });
    } finally {
      setState(() {
        isCanceling = false;
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: const Text('RunwayML Flutter Example')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            spacing: 20,
            children: [
              isGenerating
                  ? const Text('Generating Video...')
                  : ElevatedButton(
                      onPressed: generateVideo,
                      child: const Text('Generate Video'),
                    ),
              if (taskId != null && isLoading)
                isCanceling
                    ? const Text('Task is being canceled...')
                    : ElevatedButton(
                        onPressed: cancelTask,
                        child: const Text('Cancel Task'),
                      ),
              if (progressText != null) Text(progressText!),
              isLoading
                  ? const CircularProgressIndicator()
                  : videoUrl != null
                      ? _videoPlayerController != null &&
                              _videoPlayerController!.value.isInitialized
                          ? AspectRatio(
                              aspectRatio:
                                  _videoPlayerController!.value.aspectRatio,
                              child: VideoPlayer(_videoPlayerController!),
                            )
                          : Text(videoUrl ?? '')
                      : const SizedBox(),
            ],
          ),
        ),
      ),
    );
  }
}
7
likes
0
points
47
downloads

Publisher

verified publisheralperefesahin.dev

Weekly Downloads

A Flutter package that provides a Dart wrapper for the RunwayML API, enabling integration of AI-generated content into Flutter apps.

Repository (GitHub)
View/report issues

Topics

#runwayml-flutter #runway #runwayml

Funding

Consider supporting this project:

github.com

License

unknown (license)

Dependencies

flutter, http

More

Packages that depend on runwayml_flutter