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)是在软件开发中经过验证的最佳实践,用于解决常见的设计问题。它们提供了一种可复用的解决方案,可以帮助开发人员提高代码质量、可维护性和可重用性。设计模式的采用通常在以下情…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
华为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…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
