free pascal:fpwebview 组件通过 JSBridge 调用本机TTS

2024-02-16 11:52

本文主要是介绍free pascal:fpwebview 组件通过 JSBridge 调用本机TTS,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

从 https://github.com/PierceNg/fpwebview 下载 fpwebview-master.zip 简单易用。

先请看 \fpwebview-master\README.md

cd \lazarus\projects\fpwebview-master\demo\js_bidir

学习 js_bidir.lpr ,编写 js_bind_speak.lpr 如下,通过 JSBridge 调用本机TTS。

program js_bind_speak;{$linklib libwebview}
{$mode objfpc}{$H+}uses{$ifdef unix}cthreads,{$endif}Classes,Process,SysUtils,StrUtils,Variants,ComObj, math,webview;varw: PWebView;sapi: Variant;url: String;txt: String;// seq:sequence; req:request; arg:argument
procedure speak(const seq: PAnsiChar; const req: PAnsiChar; arg: Pointer); cdecl;
vars: String;
beginif req <> nil thenbegins := strPas(req);writeln('speak:'+s);trysapi.Speak(s);Sleep(1000)exceptwriteln(' OLE Error ')  end;endelsewriteln(' req is nil');//webview_return(w, seq, WebView_Return_Ok, '{result: "?"}');
end;beginif Assigned(InitProc) thenTProcedure(InitProc);{ Set math masks. libwebview throws at least one of these from somewhere deep inside. }SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);trysapi := CreateOleObject('SAPI.SpVoice')exceptwriteln(' OLE Error ')end;url := 'http://localhost/';if ParamCount =1 thenbeginif Length(ParamStr(1))<6 thenurl := 'http://localhost:' + ParamStr(1)elsebeginif AnsiStartsStr('http', ParamStr(1)) then url := ParamStr(1)else if AnsiStartsStr('192.', ParamStr(1)) then url := 'http://' + ParamStr(1)else url := 'https://' + ParamStr(1);end;endelseurl := ParamStr(1);writeln(url);w := webview_create(WebView_DevTools, nil);webview_set_size(w, 1024, 768, WebView_Hint_None);webview_set_title(w, PAnsiChar('WebView - Pascal Javascript Bridge'));
//webview_bind(w: PWebView; const name: PAnsiChar; fn: TWebViewBindProc; arg: Pointer);webview_bind(w, PAnsiChar('sapi_speak'), @speak, PAnsiChar(txt));webview_navigate(w, PAnsiChar(url));webview_run(w);webview_destroy(w);
end.

注意这一句:webview_bind(w, PAnsiChar('sapi_speak'), @speak, PAnsiChar(txt));

编写 编译批命令:winbuild.bat  如下

@echo offecho Set up FPC executable path.
set fpcexe=D:\lazarus\fpc\3.2.2\bin\x86_64-win64\fpc.exe
if not exist "%fpcexe%" (echo ERROR: Edit this batch file to set up location of fpc.exeexit /b 1
)
echo "%fpcexe%"echo Building...
copy "..\..\dll\x86_64\libwebview.a" .
copy "..\..\dll\x86_64\webview.dll" .
copy "..\..\dll\x86_64\WebView2Loader.dll" .
"%fpcexe%" -Fu..\..\src -Fl. js_bind_speak.lpr

编写 运行批命令:winrun.bat  如下

@echo off
@echo js_bind_speak.exe 
js_bind_speak.exe  %1

前端 js 代码:index6.html  如下

<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0">   <title>查询英汉词典</title> <script src="jquery-3.2.1.min.js"></script>
<style>
/* portrait 判断为竖屏 */
@media only screen and (orientation: portrait){#lab1 {display:none;}
} 
/* landscape 判断为横屏 */ 
@media only screen and (orientation: landscape){#lab1 {display: ;} 
}    
</style>
</head>
<body><form name="form" id="form" action="trans" method="POST" target="iframe"><label id="lab1">请输入:</label><input type="text" name="txt" id='txt' size="30" placeholder="请输入 a word"><input type="submit" name="eng_han" value="英译汉"><input type="button" name="btn1" id="btn1" value="前缀查询"><input type="button" name="btn2" id="btn2" value="TTS读音" onclick="tts2()"></form><p></p>
<div style="float:left; width:100%;"><div id="result" style="float:left; width:80%; height:400; border:2px;"><iframe name="iframe" id="iframe" width="100%" height="400"> </iframe></div><div id="alist" style="float:right; width:20%; height:400; border:2px;"></div>
</div><script type="text/javascript">$(function(){$("#btn1").click(function(){$.getJSON("/prefix?txt="+$("#txt").val(), function(data){$('#alist').empty();var items = [];$.each(data, function(i, item){if (i<=20){items[i] = '<a href="/trans?txt=' +item+ '" target="iframe">' +item+ "</a><br>";}});var a = items.join('\n');if (a) $('#alist').html(a);})})});//定义对象 customHost,方便js函数调用//var hostObj = window.chrome.webview.hostObjects.customHost;// pascal TTSfunction tts() {var txt = document.getElementById('txt').value;if (txt.length >1) {(async ()=>{await sapi_speak(txt);})();}}// 屏幕双击取词, pascal TTSfunction tts2() {// 获取iframe里的选择内容var select = window.frames['iframe'].getSelection();var txt = select.toString();txt = txt.trim();if (txt.length >1) { // alert(txt);(async ()=>{await sapi_speak(txt);})();} else {tts();}}// 页面加载添加:监听iframe网页点击事件$(document).ready(function(){var listener = window.addEventListener('blur', function(){if (document.activeElement === document.getElementById('iframe')){$('iframe').contents().find('a.fayin').click(function(event){event.preventDefault();var a = $(this);if (a){var addr = a.attr('href');if (addr.indexOf('sound://')==0){var url = "/data" + addr.substring(7);var mp3 = new Audio(url);mp3.addEventListener("canplaythrough", (event)=> {mp3.play();});} else {alert('href='+addr);}}})}        });});
</script> 
</body>
</html>

web 服务程序请参考:python:mdict + bottle = web 查询英汉词典

记得修改一句:def server_static(filepath="index6.html"):

先运行 web 服务程序:python mdict_bottle.py

再执行编译:winbuild.bat

最后运行:winrun.bat 8086

访问  http://localhost:8086/

这篇关于free pascal:fpwebview 组件通过 JSBridge 调用本机TTS的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/714450

相关文章

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

SpringQuartz定时任务核心组件JobDetail与Trigger配置

《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

使用Python实现文本转语音(TTS)并播放音频

《使用Python实现文本转语音(TTS)并播放音频》在开发涉及语音交互或需要语音提示的应用时,文本转语音(TTS)技术是一个非常实用的工具,下面我们来看看如何使用gTTS和playsound库将文本... 目录什么是 gTTS 和 playsound安装依赖库实现步骤 1. 导入库2. 定义文本和语言 3

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

kotlin中的行为组件及高级用法

《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine