netease_callkit 4.5.0+3 copy "netease_callkit: ^4.5.0+3" to clipboard
netease_callkit: ^4.5.0+3 copied to clipboard

netease callkit is a kit about audio&video calls launched by CommsEase.

example/lib/main.dart

// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';

import 'package:flutter/services.dart';
import 'package:netease_callkit/netease_callkit.dart';
import 'package:nim_core_v2/nim_core.dart';
import 'config/app_config.dart';
import 'base/device_manager.dart';
import 'service/auth/auth_manager.dart';
import 'utils/nav_register.dart';
import 'constants/router_name.dart';

const _desktopShutdownChannel = MethodChannel('callkit_example/app_shutdown');
bool _desktopShutdownPrepared = false;
const _macDesktopShutdownSettleDelay = Duration(milliseconds: 500);

void _registerDesktopShutdownHandler() {
  _desktopShutdownChannel.setMethodCallHandler((call) async {
    if (call.method != 'prepareForExit') {
      throw MissingPluginException('Not implemented: ${call.method}');
    }
    await _prepareForDesktopExit();
    return null;
  });
}

Future<void> _prepareForDesktopExit() async {
  if (_desktopShutdownPrepared) return;
  _desktopShutdownPrepared = true;
  if (!(Platform.isMacOS || Platform.isWindows)) return;
  try {
    final result = await NECallEngine.instance.destroy();
    debugPrint('desktop exit destroy result: ${result.code}');
  } catch (e, st) {
    debugPrint('desktop exit destroy error: $e\n$st');
  }
  try {
    final result = await NimCore.instance.releaseDesktop();
    debugPrint('desktop exit releaseDesktop: ${result.code}');
  } catch (e, st) {
    debugPrint('desktop exit releaseDesktop error: $e\n$st');
  }
  if (Platform.isMacOS) {
    // Give NIM/logger background teardown a moment to settle before the
    // process exits, otherwise macOS may still hit dylib finalizers mid-exit.
    await Future<void>.delayed(_macDesktopShutdownSettleDelay);
  }
}

void main() {
  runZonedGuarded<Future<void>>(() async {
    WidgetsFlutterBinding.ensureInitialized();
    _registerDesktopShutdownHandler();

    // 初始化应用配置
    await AppConfig().init();

    // 初始化设备管理器
    await DeviceManager().init();

    // 初始化认证管理器
    await AuthManager().init();

    // 初始化 CallKit
    await initCallKit();

    runApp(const MyApp());
  }, (Object error, StackTrace stack) {
    print('crash exception: $error \ncrash stack: $stack');
  });
}

/// 初始化 CallKit
///
/// 桌面端(macOS/Windows)必须先初始化 NIM SDK,再初始化 CallKit,
/// 否则 CallKit 内部的 NIM 信令回调注册会因 nim_client_init 尚未调用而崩溃。
Future<void> initCallKit() async {
  // 桌面端:先初始化 NIM(仅需 appKey,不需要登录凭证)
  if (Platform.isMacOS || Platform.isWindows) {
    try {
      final nimOptions = NIMPCSDKOptions(
        basicOption: NIMBasicOption(),
        appKey: AppConfig().appKey,
      );
      await NimCore.instance.initialize(nimOptions);
      print('NIM 预初始化完成');
    } catch (e) {
      print('NIM 预初始化异常: $e');
    }
  }

  try {
    final callkit = NECallEngine.instance;

    // 调用 CallKit 初始化接口
    final result = await callkit.setup(NESetupConfig(
      appKey: AppConfig().appKey,
      enableJoinRtcWhenCall: true,
      initRtcMode: NECallInitRtcMode.global,
    ));

    if (result.code == 0) {
      print('CallKit 初始化成功');
    } else {
      print('CallKit 初始化失败: ${result.msg}');
    }
  } catch (e) {
    print('CallKit 初始化异常: $e');
  }
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      color: Colors.black,
      theme: ThemeData(
        brightness: Brightness.light,
        appBarTheme: const AppBarTheme(
          systemOverlayStyle: SystemUiOverlayStyle.light,
        ),
      ),
      themeMode: ThemeMode.light,
      home: const WelcomePage(),
      onGenerateRoute: (settings) {
        WidgetBuilder builder =
            RoutesRegister.routes(settings)[settings.name] as WidgetBuilder;
        return MaterialPageRoute(
          builder: (ctx) => builder(ctx),
          settings: RouteSettings(name: settings.name),
        );
      },
    );
  }
}

class WelcomePage extends StatefulWidget {
  const WelcomePage({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _WelcomePageState();
}

class _WelcomePageState extends State<WelcomePage> {
  @override
  void initState() {
    super.initState();
    loadLoginInfo();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CircularProgressIndicator(
              valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
            ),
            SizedBox(height: 16),
            Text(
              '正在加载...',
              style: TextStyle(
                color: Colors.white,
                fontSize: 16,
              ),
            ),
          ],
        ),
      ),
    );
  }

  void loadLoginInfo() {
    AuthManager().autoLogin().then((value) {
      if (value) {
        Navigator.of(context).pushNamedAndRemoveUntil(
          RouterName.homePage,
          (route) => false,
        );
      } else {
        Navigator.of(context).pushNamedAndRemoveUntil(
          RouterName.loginPage,
          (route) => false,
        );
      }
    });
  }
}
2
likes
130
points
335
downloads

Documentation

API reference

Publisher

verified publisheryunxin.163.com

Weekly Downloads

netease callkit is a kit about audio&video calls launched by CommsEase.

Homepage

License

MIT (license)

Dependencies

ffi, flutter, hawk_meta, json_annotation, netease_common, nim_core_v2, path_provider, uuid, yunxin_alog

More

Packages that depend on netease_callkit

Packages that implement netease_callkit