avatar_kit 1.0.0-beta.1 copy "avatar_kit: ^1.0.0-beta.1" to clipboard
avatar_kit: ^1.0.0-beta.1 copied to clipboard

A Flutter plugin for AvatarKit which provides avatar rendering with audio driving support.

example/lib/main.dart

import 'dart:convert';
import 'package:flutter/material.dart' hide ConnectionState;
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:avatar_kit/avatar_kit_plugin.dart';

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  MockData? mockData;

  String version = '';
  bool supportsCurrentDevice = false;

  Avatar? avatar;
  AvatarController? avatarController;

  bool isConnected = false;

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

    // test: host mode
    // loadMockData();
  }

  Future<void> initPlatformState() async {
    try {
      final configuration = Configuration(environment: Environment.test, drivingServiceMode: DrivingServiceMode.sdk, logLevel: LogLevel.all);
      await AvatarSDK.initialize(appID: 'appID', configuration: configuration);
      await AvatarSDK.setSessionToken('');
      await AvatarSDK.setUserID('userID');
      final version = await AvatarSDK.version();
      final supportsCurrentDevice = await AvatarSDK.supportsCurrentDevice();
      setState(() {
        this.version = version;
        this.supportsCurrentDevice = supportsCurrentDevice;
      });
    } catch (e) {
      debugPrint(e.toString());
    }
  }

  Future<void> loadMockData() async {
    try {
      final response = await http.get(
        Uri.parse('https://avatar-sdk-go-test.spatialwalk.cn/media'),
      );
      if (response.statusCode == 200) {
        final data = MockData.fromJson(jsonDecode(response.body));
        setState(() {
          mockData = data;
        });
      }
    } catch (e) {
      debugPrint('Fetching data failed: $e');
    }
  }

  void schedulePlaying() async {
    if (mockData == null) {
      return;
    }
    final audioData = mockData!.audio;
    final animations = mockData!.animations;

    final conversationID = await avatarController!.yieldAudioData(audioData, end: true);

    for (var i = 0; i < animations.length; i++) {
      final animation = animations[i];
      Future.delayed(Duration(seconds: i + 1), () {
        avatarController!.yieldAnimations([animation], conversationID: conversationID);
      },);
    }
  }

  void setBackgroundImage() async {
    final backgroundImage = await rootBundle.load('assets/background.jpeg').then((value) => value.buffer.asUint8List());
    await avatarController!.setBackgroundImage(backgroundImage);
    debugPrint('set background image: done');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.grey,
        appBar: AppBar(
          title: const Text('AvatarKit Example'),
        ),
        body: Center(child: Column(
          children: [
            Text('Version: $version'),

            Text('Supports Current Device: $supportsCurrentDevice'),

            Text('Is Connected: $isConnected'),

            ElevatedButton(onPressed: () async {
              try {
                final avatar = await AvatarManager.shared.load(id: 'e41f7ee0-3807-4956-b169-1becf8497ebc', onProgress: (progress) {
                  debugPrint('load progress: $progress');
                });
                setState(() {
                  this.avatar = avatar;
                });
              } on AvatarError catch (e) {
                debugPrint('load avatar error: ${e.name}');
              } catch (e) {
                debugPrint('load avatar failed: ${e.toString()}');
              }
            }, child: const Text('Load Avatar')),

            Container(
              margin: const EdgeInsets.only(top: 20),
              width: 300,
              height: 300,
              child: avatar != null ? AvatarWidget(avatar: avatar!, onPlatformViewCreated: (controller) {
                controller.onConnectionState = (state, errorMessage) {
                  debugPrint('onConnectionState: ${state.name}. ${errorMessage != null ? 'error: $errorMessage' : ''}');
                  setState(() {
                    isConnected = state == ConnectionState.connected;
                  });
                };
                controller.onConversationState = (state) {
                  debugPrint('onConversationState: ${state.name}');
                };
                controller.onError = (error) {
                  debugPrint('onError: ${error.name}');
                };
                
                // test volume
                controller.setVolume(1.0).then((_) {
                  debugPrint('set volume: 1.0');
                  controller.volume().then((volume) {
                    debugPrint('get volume: $volume');
                  });
                });

                // test opaque
                controller.setOpaque(false).then((_) {
                  debugPrint('set opaque: false');
                  controller.isOpaque().then((isOpaque) {
                    debugPrint('get isOpaque: $isOpaque');
                  });
                });

                // test background image
                // setBackgroundImage();

                setState(() {
                  avatarController = controller;
                });
              }) : const SizedBox.shrink(),
            ),

            avatarController != null ? ElevatedButton(onPressed: () async {
              await avatarController!.start();
            }, child: const Text('Start')) : const SizedBox.shrink(),

            avatarController != null ? ElevatedButton(onPressed: () async {
              if (!isConnected) { return; }
              final audioData = await rootBundle.load('assets/audio_01.pcm').then((value) => value.buffer.asUint8List());
              final conversationID = await avatarController!.send(audioData, end: false);
              debugPrint('send audio, conversationID: $conversationID');
            }, child: const Text('Send Audio 01')) : const SizedBox.shrink(),

            avatarController != null ? ElevatedButton(onPressed: () async {
              if (!isConnected) { return; }
              final audioData = await rootBundle.load('assets/audio_02.pcm').then((value) => value.buffer.asUint8List());
              final conversationID = await avatarController!.send(audioData, end: true);
              debugPrint('send audio, conversationID: $conversationID');
            }, child: const Text('Send Audio 02')) : const SizedBox.shrink(),

            avatarController != null ? ElevatedButton(onPressed: () async {
              await avatarController!.interrupt();
            }, child: const Text('Interrupt')) : const SizedBox.shrink(),

            avatarController != null ? ElevatedButton(onPressed: () async {
              await avatarController!.close();
            }, child: const Text('Close')) : const SizedBox.shrink(),

            // // test: host mode
            // avatarController != null && mockData != null ? Column(
            //   children: [
            //     ElevatedButton(onPressed: () async {
            //       schedulePlaying();
            //     }, child: const Text('Schedule Playing'))
            //   ],
            // ) : const SizedBox.shrink(),
          ],
        )),  
      ),
    );
  }
}

class MockData {
  final Uint8List audio;
  final List<Uint8List> animations;

  MockData({required this.audio, required this.animations});

  factory MockData.fromJson(Map<String, dynamic> json) {
    return MockData(
      audio: base64Decode(json['audio']),
      animations: (json['animations'] as List<dynamic>)
          .map<Uint8List>((animation) => base64Decode(animation as String))
          .toList(),
    );
  }
}
0
likes
0
points
759
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for AvatarKit which provides avatar rendering with audio driving support.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on avatar_kit

Packages that implement avatar_kit