当前位置: 首页 > news >正文

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 &#xff0c;编写 js_bind_speak.lpr 如下&#xff0c;通过JSBridge调用本机…...

C语言静态库深入剖析

在C语言编程实践中&#xff0c;库是代码复用和模块化开发的重要基础结构。静态库作为其中一种主要的库类型&#xff0c;其内容在编译链接阶段即被完整地嵌入到最终生成的可执行文件中&#xff0c;从而使得程序在运行时无需外部依赖。本篇博客将系统性、详细地剖析C语言静态库的…...

A股上市以来涨幅排行榜

一、统计数据说明 1. 涨幅排行榜是根据股价的后复权价格计算的&#xff0c;该价格考虑了分红送股拆股等事件对股价的影响&#xff0c;相当于是分红再投资的股价。 2. 年化投资收益率&#xff0c;是根据IPO收盘价至今涨幅计算的复合年化收益率。例如&#xff0c;假设一个股票上…...

鸿蒙开发系列教程(十八)--页面内动画(1)

页面内的动画 显示动画 语法&#xff1a;animateTo(value: AnimateParam, event: () > void): void 第一个参数指定动画参数 第二个参数为动画的闭包函数。 如&#xff1a;animateTo({ duration: 1000, curve: Curve.EaseInOut }, () > {动画代码}&#xff09; dura…...

Web基础01-HTML+CSS

目录 一、HTML 1.概述 2.html结构解析 3.HTML标签分类 4.HTML标签关系 5.HTML空元素 6.HTML属性 7.常用标签 &#xff08;1&#xff09;HTML标签 &#xff08;2&#xff09;标题标签 &#xff08;3&#xff09;换/折行标签 &#xff08;4&#xff09;段落标签 &am…...

Linux命令行全景指南:从入门到实践,掌握命令行的力量

目录 知识梳理思维导图&#xff1a; linux命令入门 为什么要学Linux命令 什么是终端 什么是命令 关于Linux命令的语法 tab键补全 关于命令提示符 特殊目录 常见重要目录 /opt /home /root /etc /var/log/ man命令 shutdown命令 history命令 which命令 bash…...

蓝桥杯嵌入式第11届真题(完成) STM32G431

蓝桥杯嵌入式第11届真题(完成) STM32G431 题目 代码 程序和之前的大同小异&#xff0c;不过多解释 main.c /* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief :…...

ChatGPT高效提问—prompt实践(教师助手)

ChatGPT高效提问—prompt实践&#xff08;教师助手&#xff09; 下面来看看ChatGPT在教育领域有什么用途。 首先设定ChatGPT的角色为高中教师助手。 输入prompt: ChatGPT输出&#xff1a; ​ 教师助手的角色已经设置完成。下面通过几种不同的情景演示如何使用。 1.1.1 制定…...

AI绘画作品的展示和变现-2

4.7 制作红包封面 中国的节日和传统文化元素仍然可以成为创作者们的创作灵感&#xff0c;创造出更多的变现机会。比如元宵节&#xff0c;可以制作大型元宵图案&#xff0c;进行引流并卖出元宵。 而春分、谷雨等节气也可以成为创作的灵感来源&#xff0c;创作出与之相关的图案&…...

Linux---网络套接字

端口号 端口号 端口号是一个2字节16位的整数; 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理; IP地址 端口号能够标识网络上的某一台主机的某一个进程; 一个端口号只能被一个进程占用 在公网上&#xff0c;IP地址能表示唯一的一台主机&…...

前端vue 数字 字符串 丢失精度问题

1.问题 后端返回的数据 是这样的 一个字符串类型的数据 前端要想显示这个 肯定需要使用Json.parse() 转换一下 但是 目前有一个问题 转换的确可以 showId:1206381711026823172 有一个这样的字段 转换了以后 发现 字段成了1206381711026823200 精度直接丢了 原本的数据…...

智能汽车行业产业研究报告:4D成像毫米波雷达—自动驾驶最佳辅助

今天分享的是智能汽车系列深度研究报告&#xff1a;《智能汽车行业产业研究报告&#xff1a;4D成像毫米波雷达—自动驾驶最佳辅助》。 &#xff08;报告出品方&#xff1a;开源证券&#xff09; 报告共计&#xff1a;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的发展前景非常广阔&#xff0c;随着5G、6G等高速网络通信技术的普及和边缘计算能力的提升&#xff0c;以及AI算法和硬件的不断优化进步&#xff0c;分布式AI将在多个领域展现出强大的应用潜力和市场价值&#xff1a; 1. **物联网&#xff08;IoT&#xff0…...

机器学习:ROC曲线笔记

ROC曲线&#xff08;Receiver Operating Characteristic Curve&#xff09;是一种用于评估二分类模型性能的图形化工具&#xff0c;主要用于展示在不同阈值&#xff08;Threshold&#xff09;下模型的真阳性率&#xff08;True Positive Rate&#xff0c;TPR&#xff09;和假阳…...

【lesson54】线程互斥

文章目录 线程互斥 线程互斥 互斥量mutex 大部分情况&#xff0c;线程使用的数据都是局部变量&#xff0c;变量的地址空间在线程栈空间内&#xff0c;这种情况&#xff0c;变量归属单个线程&#xff0c;其他线程无法获得这种变量。但有时候&#xff0c;很多变量都需要在线程间…...

Android14音频进阶:MediaPlayerService如何启动AudioTrack 上篇(五十五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…...

K8sGPT 的使用

K8sGPT 介绍 k8sgpt 是一个扫描 Kubernetes 集群、诊断和分类问题的工具。它将 SRE 经验编入其分析器中&#xff0c;并帮助提取最相关的信息&#xff0c;通过人工智能来丰富它。它还可以与 OpenAI、Azure、Cohere、Amazon Bedrock 和本地模型结合使用。 K8sGPT Github 地址 …...

《CSS 简易速速上手小册》第4章:视觉美学(2024 最新版)

文章目录 4.1 颜色理论在 CSS 设计中的应用&#xff1a;网页的调色盘4.1.1 基础知识4.1.2 重点案例&#xff1a;创建一个具有情感设计的登录页面4.1.3 拓展案例 1&#xff1a;使用颜色增强信息的可视化表示4.1.4 拓展案例 2&#xff1a;利用颜色创建网站的品牌身份 4.2 字体与文…...

设计模式浅析

一、设计模式的使用场景 设计模式&#xff08;Design Patterns&#xff09;是在软件开发中经过验证的最佳实践&#xff0c;用于解决常见的设计问题。它们提供了一种可复用的解决方案&#xff0c;可以帮助开发人员提高代码质量、可维护性和可重用性。设计模式的采用通常在以下情…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

华为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代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...