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;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, 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
从 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调用本机…...
C语言静态库深入剖析
在C语言编程实践中,库是代码复用和模块化开发的重要基础结构。静态库作为其中一种主要的库类型,其内容在编译链接阶段即被完整地嵌入到最终生成的可执行文件中,从而使得程序在运行时无需外部依赖。本篇博客将系统性、详细地剖析C语言静态库的…...
A股上市以来涨幅排行榜
一、统计数据说明 1. 涨幅排行榜是根据股价的后复权价格计算的,该价格考虑了分红送股拆股等事件对股价的影响,相当于是分红再投资的股价。 2. 年化投资收益率,是根据IPO收盘价至今涨幅计算的复合年化收益率。例如,假设一个股票上…...
鸿蒙开发系列教程(十八)--页面内动画(1)
页面内的动画 显示动画 语法:animateTo(value: AnimateParam, event: () > void): void 第一个参数指定动画参数 第二个参数为动画的闭包函数。 如:animateTo({ duration: 1000, curve: Curve.EaseInOut }, () > {动画代码}) dura…...
Web基础01-HTML+CSS
目录 一、HTML 1.概述 2.html结构解析 3.HTML标签分类 4.HTML标签关系 5.HTML空元素 6.HTML属性 7.常用标签 (1)HTML标签 (2)标题标签 (3)换/折行标签 (4)段落标签 &am…...
Linux命令行全景指南:从入门到实践,掌握命令行的力量
目录 知识梳理思维导图: linux命令入门 为什么要学Linux命令 什么是终端 什么是命令 关于Linux命令的语法 tab键补全 关于命令提示符 特殊目录 常见重要目录 /opt /home /root /etc /var/log/ man命令 shutdown命令 history命令 which命令 bash…...
蓝桥杯嵌入式第11届真题(完成) STM32G431
蓝桥杯嵌入式第11届真题(完成) STM32G431 题目 代码 程序和之前的大同小异,不过多解释 main.c /* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief :…...
ChatGPT高效提问—prompt实践(教师助手)
ChatGPT高效提问—prompt实践(教师助手) 下面来看看ChatGPT在教育领域有什么用途。 首先设定ChatGPT的角色为高中教师助手。 输入prompt: ChatGPT输出: 教师助手的角色已经设置完成。下面通过几种不同的情景演示如何使用。 1.1.1 制定…...
AI绘画作品的展示和变现-2
4.7 制作红包封面 中国的节日和传统文化元素仍然可以成为创作者们的创作灵感,创造出更多的变现机会。比如元宵节,可以制作大型元宵图案,进行引流并卖出元宵。 而春分、谷雨等节气也可以成为创作的灵感来源,创作出与之相关的图案&…...
Linux---网络套接字
端口号 端口号 端口号是一个2字节16位的整数; 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理; IP地址 端口号能够标识网络上的某一台主机的某一个进程; 一个端口号只能被一个进程占用 在公网上,IP地址能表示唯一的一台主机&…...
前端vue 数字 字符串 丢失精度问题
1.问题 后端返回的数据 是这样的 一个字符串类型的数据 前端要想显示这个 肯定需要使用Json.parse() 转换一下 但是 目前有一个问题 转换的确可以 showId:1206381711026823172 有一个这样的字段 转换了以后 发现 字段成了1206381711026823200 精度直接丢了 原本的数据…...
智能汽车行业产业研究报告:4D成像毫米波雷达—自动驾驶最佳辅助
今天分享的是智能汽车系列深度研究报告:《智能汽车行业产业研究报告:4D成像毫米波雷达—自动驾驶最佳辅助》。 (报告出品方:开源证券) 报告共计:43页 视觉感知最佳辅助——4D 成像毫米波雷达 感知是自动…...
docker 3.1 镜像
docker 3.1 镜像命令 拉取镜像 docker pull debian #从 Docker Hub 拉取名为 debian 的镜像docker pull hello-world #从 Docker Hub 拉入名为 hello-world 的镜像 运行镜像/容器 docker run hello-world 查看本地所有的镜像 docker images 容器生成镜像…...
如何在极低成本硬件上落地人工智能算法 —— 分布式AI
一、背景 分布式AI的发展前景非常广阔,随着5G、6G等高速网络通信技术的普及和边缘计算能力的提升,以及AI算法和硬件的不断优化进步,分布式AI将在多个领域展现出强大的应用潜力和市场价值: 1. **物联网(IoT࿰…...
机器学习:ROC曲线笔记
ROC曲线(Receiver Operating Characteristic Curve)是一种用于评估二分类模型性能的图形化工具,主要用于展示在不同阈值(Threshold)下模型的真阳性率(True Positive Rate,TPR)和假阳…...
【lesson54】线程互斥
文章目录 线程互斥 线程互斥 互斥量mutex 大部分情况,线程使用的数据都是局部变量,变量的地址空间在线程栈空间内,这种情况,变量归属单个线程,其他线程无法获得这种变量。但有时候,很多变量都需要在线程间…...
Android14音频进阶:MediaPlayerService如何启动AudioTrack 上篇(五十五)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…...
K8sGPT 的使用
K8sGPT 介绍 k8sgpt 是一个扫描 Kubernetes 集群、诊断和分类问题的工具。它将 SRE 经验编入其分析器中,并帮助提取最相关的信息,通过人工智能来丰富它。它还可以与 OpenAI、Azure、Cohere、Amazon Bedrock 和本地模型结合使用。 K8sGPT Github 地址 …...
《CSS 简易速速上手小册》第4章:视觉美学(2024 最新版)
文章目录 4.1 颜色理论在 CSS 设计中的应用:网页的调色盘4.1.1 基础知识4.1.2 重点案例:创建一个具有情感设计的登录页面4.1.3 拓展案例 1:使用颜色增强信息的可视化表示4.1.4 拓展案例 2:利用颜色创建网站的品牌身份 4.2 字体与文…...
设计模式浅析
一、设计模式的使用场景 设计模式(Design Patterns)是在软件开发中经过验证的最佳实践,用于解决常见的设计问题。它们提供了一种可复用的解决方案,可以帮助开发人员提高代码质量、可维护性和可重用性。设计模式的采用通常在以下情…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 ;/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
