Flutter直播网页嵌入插件ditto_live_web_alpha的使用

ditto_live_web_alpha

警告:此插件是一个早期的Alpha版本,旨在使用户能够在Web平台上使用Ditto。其他平台不受此包支持,这些平台由package:ditto_live覆盖。

更多详细信息,请参阅package:ditto_live的文档。


安装

  1. 将插件添加到您的pubspec.yaml文件中,或者运行以下命令:

    flutter pub add ditto_live_web_alpha
    
  2. 编辑您的应用的index.html文件,在<body>标签内加载ditto.es6.js

    修改前

    <body>
      <script src="flutter_bootstrap.js" async></script>
    </body>
    

    修改后

    <body>
      <script type="module">
        import * as dittoJS from "/assets/packages/ditto_live_web_alpha/lib/assets/ditto.es6.js";
        window.dittoJS = dittoJS;
      </script>
    
      <script src="flutter_bootstrap.js" async></script>
    </body>
    

使用

在使用Ditto的WebAssembly库之前,必须先下载并初始化它。默认情况下,WebAssembly二进制文件将从插件的资源中加载。

初始化方式1:从本地资产加载

import 'package:ditto_live_web_alpha/ditto_live_web_alpha.dart';

WidgetsFlutterBinding.ensureInitialized();
await initWasm();

初始化方式2:从远程URL加载

确保设置了正确的CORS头,并以application/wasm作为MIME类型。可以在本包的lib/assets目录下找到ditto.wasm文件。

await initWasm("https://example.com/ditto.wasm");

初始化完成后,请参阅package:ditto_live的文档以了解如何初始化Ditto实例并开始操作文档。


已知问题

某些功能在本插件中不受支持。具体包括:

  • 不支持除OnlinePlaygroundIdentityOnlineWithAuthenticationIdentity以外的身份验证。
  • 不支持任何存在API,例如Ditto.presence.observe()

对于上述功能的API文档,请查阅package:ditto_live的API文档。有关Ditto的一般文档,请访问docs.ditto.live

此外,此插件的所有API抛出的错误可能具有与package:ditto_live不同的类型和消息。


完整示例代码

以下是完整的示例代码,展示如何在Flutter中使用ditto_live_web_alpha插件。

示例代码

import 'dart:async';

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

import 'dialog.dart';
import 'task.dart';
import 'task_view.dart';

const appID = "caf9e870-d416-4b1c-9ab4-fb6e8319dd25";
const token = "cb639c76-5633-44dd-ad28-03a5a43f092e";

const authAppID = "3cffb689-8a99-4b4c-bca1-0809a5135748";

const collection = "tasks13";

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

  // 加载WebAssembly二进制文件(从本地资源)
  await initWasm();

  // 如果需要从远程URL加载,确保设置了CORS头和MIME类型
  // await initWasm("http://localhost:3000/ditto.wasm");

  final authenticationHandler = AuthenticationHandler(
    authenticationExpiringSoon: (authenticator, secondsRemaining) async {
      await authenticator.login(token: token, provider: "auth-webhook");
    },
    authenticationRequired: (authenticator) async {
      await authenticator.login(token: token, provider: "auth-webhook");
    },
  );
  final identity = await OnlineWithAuthenticationIdentity.create(
    appID: authAppID,
    authenticationHandler: authenticationHandler,
  );
  assert(identity.appID == authAppID);
  assert(identity.enableDittoCloudSync == true);
  assert(identity.customAuthUrl == null);
  assert(identity.authenticationHandler == authenticationHandler);

  // 设置日志级别
  DittoLogger.setMinimumLogLevel(LogLevel.info);
  DittoLogger.setEmojiLogLevelHeadingsEnabled(true);

  // 打开Ditto实例
  final ditto = await Ditto.open(
    identity: identity,
    persistenceDirectory: "foo",
  );

  // 启动同步
  await ditto.startSync();

  // 获取设备名称并设置新名称
  print("设备名称: ${ditto.deviceName}");
  await ditto.setDeviceName("web2");
  assert(ditto.deviceName == "web2");

  // 获取持久化目录路径
  print("持久化目录路径: ${ditto.persistenceDirectoryString}");

  // 确保已激活
  assert(ditto.isActivated == true);

  // 打印版本号
  print("版本: ${Ditto.version}");

  // 注册存储观察器
  final storeObserver = await ditto.store.registerObserver(
    "SELECT * FROM COLLECTION $collection (${Task.schema}) WHERE deleted = false",
    onChange: (qr) => setState(() => _queryResult = qr),
  );

  // 注册同步订阅
  final syncSubscription = await ditto.sync.registerSubscription(
    "SELECT * FROM $collection WHERE deleted = false",
  );

  runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    home: MyApp(ditto: ditto),
  ));
}

class MyApp extends StatefulWidget {
  final Ditto ditto;
  const MyApp({Key? key, required this.ditto}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  QueryResult? _queryResult;
  bool _syncing = true;

  StoreObserver? _storeObserver;
  SyncSubscription? _syncSubscription;

  [@override](/user/override)
  void initState() {
    super.initState();

    _init();
  }

  Future<void> _init() async {
    _storeObserver = await widget.ditto.store.registerObserver(
      "SELECT * FROM COLLECTION $collection (${Task.schema}) WHERE deleted = false",
      onChange: (qr) => setState(() => _queryResult = qr),
    );

    _syncSubscription = await widget.ditto.sync.registerSubscription(
      "SELECT * FROM $collection WHERE deleted = false",
    );
  }

  [@override](/user/override)
  void dispose() {
    _storeObserver?.cancel();
    _syncSubscription?.cancel();
    super.dispose();
  }

  Future<void> _addTask() async {
    final pair = await showAddTaskDialog(context, widget.ditto);
    if (pair == null) return;
    final (task, attachment) = pair;

    try {
      await widget.ditto.store.execute(
        "INSERT INTO COLLECTION $collection (${Task.schema}) DOCUMENTS (:task)",
        arguments: {
          "task": {
            ...task.toJson(),
            "image": attachment.toJson(),
          },
        },
      );
    } on DittoException catch (e) {
      print("Ditto Exception: ${e.message}");
    }
  }

  Future<void> _clearTasks() async {
    await widget.ditto.store.execute(
      "EVICT FROM COLLECTION $collection (${Task.schema}) WHERE true",
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text("Ditto任务管理"),
          actions: [
            IconButton(
              onPressed: _clearTasks,
              icon: const Icon(Icons.clear),
            ),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _addTask,
          child: const Icon(Icons.add),
        ),
        body: Center(
          child: ListView(
            children: [
              SwitchListTile(
                title: const Text("同步状态"),
                value: _syncing,
                onChanged: (value) async {
                  if (value) {
                    await widget.ditto.startSync();
                  } else {
                    await widget.ditto.stopSync();
                  }
                  widget.ditto
                      .isSyncActive()
                      .then((value) => print("isSyncActive: $value"));
                  setState(() => _syncing = value);
                },
              ),
              ...?_queryResult?.items.map(
                (item) => TaskView(
                  ditto: widget.ditto,
                  task: Task.fromJson(item.value),
                  token: item.value["image"],
                ),
              ),
            ],
          ),
        ),
      );
}

更多关于Flutter直播网页嵌入插件ditto_live_web_alpha的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter直播网页嵌入插件ditto_live_web_alpha的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


ditto_live_web_alpha 是一个用于在 Flutter 应用中嵌入直播网页的插件。它允许你在 Flutter 应用中嵌入网页内容,特别适用于需要展示直播流或其他网页内容的场景。以下是如何使用 ditto_live_web_alpha 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 ditto_live_web_alpha 插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  ditto_live_web_alpha: ^0.0.1  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 导入插件

在你的 Dart 文件中导入 ditto_live_web_alpha 插件。

import 'package:ditto_live_web_alpha/ditto_live_web_alpha.dart';

3. 使用 DittoLiveWeb 组件

你可以在你的 Flutter 应用中使用 DittoLiveWeb 组件来嵌入网页内容。

class LiveWebPage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Live Web Page'),
      ),
      body: DittoLiveWeb(
        initialUrl: 'https://example.com/live', // 替换为你的直播网页URL
        javascriptMode: JavascriptMode.unrestricted, // 允许执行JavaScript
      ),
    );
  }
}

4. 运行应用

现在你可以运行你的 Flutter 应用,并查看嵌入的直播网页。

5. 其他配置

DittoLiveWeb 组件还支持其他一些配置选项,例如:

  • onPageStarted: 当网页开始加载时触发。
  • onPageFinished: 当网页加载完成时触发。
  • onWebResourceError: 当网页资源加载失败时触发。

你可以根据需要添加这些回调函数来处理网页加载过程中的事件。

DittoLiveWeb(
  initialUrl: 'https://example.com/live',
  javascriptMode: JavascriptMode.unrestricted,
  onPageStarted: (String url) {
    print('Page started loading: $url');
  },
  onPageFinished: (String url) {
    print('Page finished loading: $url');
  },
  onWebResourceError: (WebResourceError error) {
    print('Error loading resource: ${error.description}');
  },
)

6. 注意事项

  • 由于 ditto_live_web_alpha 是一个 alpha 版本的插件,可能存在一些不稳定或未完善的功能。建议在使用前进行充分测试。
  • 确保你嵌入的网页内容符合相关法律法规,并遵守平台的使用政策。

7. 示例代码

以下是一个完整的示例代码:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Live Web Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LiveWebPage(),
    );
  }
}

class LiveWebPage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Live Web Page'),
      ),
      body: DittoLiveWeb(
        initialUrl: 'https://example.com/live',
        javascriptMode: JavascriptMode.unrestricted,
        onPageStarted: (String url) {
          print('Page started loading: $url');
        },
        onPageFinished: (String url) {
          print('Page finished loading: $url');
        },
        onWebResourceError: (WebResourceError error) {
          print('Error loading resource: ${error.description}');
        },
      ),
    );
  }
}
回到顶部