Flutter网页视图与文本转语音插件web_view_tts的使用

Flutter网页视图与文本转语音插件web_view_tts的使用

概览

web_view_tts version

该库用于在Android WebView中添加文本转语音(Text-To-Speech)支持。

开始使用

使用flutter_inappwebview进行WebView开发,并使用flutter_tts进行Android TTS支持。

在你的pubspec.yaml文件中添加以下依赖项:

dependencies:
  flutter_inappwebview: ^5.4.3+7
  web_view_tts: 0.0.1

设置WebView,请参考flutter_inappwebview文档。对于添加TTS支持,请参考flutter_tts文档

使用方法

flutter_inappwebviewonLoadStart回调中,添加以下方法:

onLoadStart(controller) async {
  await WebViewTTS.init(controller: controller);
}

功能特性

web_view_tts库支持以下TTS API:

  • Speak
  • Stop
  • Pause
  • Resume
  • getVoices
  • setVolume
  • setPitch
  • setRate

注意事项

此库仅在Android上添加TTS polyfill,因为iOS的WebView已支持这些功能。

额外信息

这是初始版本,欢迎贡献或报告任何问题!

示例代码

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:web_view_tts/web_view_tts.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  if (Platform.isAndroid) {
    await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
  }
  runApp(
    const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Flowser",
      home: WebsiteView(),
    ),
  );
}

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

  [@override](/user/override)
  State<WebsiteView> createState() => _WebsiteViewState();
}

class _WebsiteViewState extends State<WebsiteView> {
  var url = "https://dlutton.github.io/flutter_tts/#/";

  final urlController = TextEditingController();
  InAppWebViewController? webViewController;
  bool canGoBack = false;
  double? progress;
  int currentKey = 1;

  // 在页面加载开始时初始化TTS
  onLoadStart(controller) async {
    await WebViewTTS.init(controller: controller);
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Flowser"),
        centerTitle: true,
        leading: canGoBack
            ? IconButton(
                onPressed: () {
                  webViewController?.goBack();
                },
                icon: const Icon(Icons.arrow_back_ios),
              )
            : const SizedBox(),
        actions: [
          IconButton(
            onPressed: () async {
              setState(() {
                currentKey++;
              });
            },
            icon: const Icon(Icons.sync),
          ),
        ],
      ),
      body: SafeArea(
        child: Column(
          children: [
            progress == null
                ? const SizedBox()
                : LinearProgressIndicator(
                    color: Colors.green,
                    value: progress,
                  ),
            TextField(
              decoration: const InputDecoration(prefixIcon: Icon(Icons.search)),
              controller: urlController,
              keyboardType: TextInputType.url,
              onSubmitted: (value) {
                var url = Uri.parse(value);
                if (url.scheme.isEmpty) {
                  url = Uri.parse("https://www.google.com/search?q=$value");
                }
                webViewController?.loadUrl(urlRequest: URLRequest(url: url));
              },
            ),
            Expanded(
              child: Stack(
                children: [
                  InAppWebView(
                    key: Key('$currentKey'),
                    initialUrlRequest: URLRequest(url: Uri.parse(url)),
                    onLoadStart: (controller, url) => onLoadStart(controller),
                    initialOptions: InAppWebViewGroupOptions(
                      android: AndroidInAppWebViewOptions(
                        useHybridComposition: true,
                      ),
                    ),
                    pullToRefreshController: PullToRefreshController(
                      onRefresh: () async {
                        await webViewController?.reload();
                      },
                    ),
                    onLoadStop: (controller, uri) async {
                      bool canGoBack = await controller.canGoBack();
                      setState(() {
                        urlController.text = uri.toString();
                        canGoBack = canGoBack;
                      });
                    },
                    onProgressChanged: ((controller, prg) {
                      setState(() {
                        progress = prg / 100;
                        if (prg == 100) {
                          progress = null;
                        }
                      });
                    }),
                    onConsoleMessage: (controller, consoleMessage) {
                      print("ConsoleMessage : ${consoleMessage.messageLevel.toString()} :  ${consoleMessage.message}");
                    },
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter网页视图与文本转语音插件web_view_tts的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网页视图与文本转语音插件web_view_tts的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于在Flutter中结合使用webview_flutter插件和tts(文本转语音)插件,以下是一个基本的代码示例,展示了如何在Flutter应用中实现一个包含WebView的页面,并且在该页面内容中识别文本并进行文本转语音操作。

首先,确保在你的pubspec.yaml文件中添加必要的依赖:

dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^3.0.4  # 请检查最新版本号
  flutter_tts: ^3.3.2  # 请检查最新版本号

然后,运行flutter pub get来安装这些依赖。

接下来是主要的Dart代码示例:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter_tts/flutter_tts.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter WebView with TTS',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: WebViewWithTTS(),
    );
  }
}

class WebViewWithTTS extends StatefulWidget {
  @override
  _WebViewWithTTSState createState() => _WebViewWithTTSState();
}

class _WebViewWithTTSState extends State<WebViewWithTTS> {
  late WebViewController _controller;
  late FlutterTts flutterTts;

  @override
  void initState() {
    super.initState();
    flutterTts = FlutterTts();

    flutterTts.setLanguage("en-US");
    flutterTts.setPitch(1.0);
    flutterTts.setSpeechRate(1.0);
    flutterTts.setVolume(1.0);

    if (Platform.isAndroid) {
      flutterTts.initialize().then((_) {
        setState(() {});
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WebView with TTS'),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.mic),
            onPressed: () async {
              // Here you would typically extract text from the WebView content
              // For simplicity, let's assume we have a predefined text
              String textToRead = "Hello, this is a text to speech example.";
              await flutterTts.speak(textToRead);
            },
          ),
        ],
      ),
      body: WebView(
        initialUrl: 'https://flutter.dev',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          _controller = webViewController;
        },
        onPageFinished: (String url) async {
          // Optionally, you can try to extract text from the page here
          // Note: This is a complex process and often not feasible directly from WebView
          // You may need to use JavaScript evaluation or server-side processing
          // For simplicity, we'll skip this part in this example
        },
      ),
    );
  }

  @override
  void dispose() {
    flutterTts.stop();
    super.dispose();
  }
}

说明

  1. 依赖管理:在pubspec.yaml中添加了webview_flutterflutter_tts依赖。
  2. Flutter TTS 初始化:在initState方法中初始化了FlutterTts实例,并设置了语言、音调、语速和音量。
  3. WebView 配置:在WebView小部件中设置了初始URL,并监听onWebViewCreatedonPageFinished事件。
  4. 文本转语音操作:在AppBar中添加了一个IconButton,用于触发文本转语音操作。在这个例子中,我们直接使用了一个预定义的文本字符串。

注意:从WebView中直接提取文本内容通常是一个复杂的过程,因为它可能需要解析HTML/CSS,并且WebView本身不提供直接获取页面文本内容的API。在实际应用中,你可能需要借助JavaScript在WebView内部执行文本提取,或者将提取文本的逻辑放在服务器端处理。上述代码示例为了简洁起见,跳过了这一步骤。

回到顶部