Closed WoJiaoFuXiaoYun closed 5 months ago
appModule.call()
method call python functions are all asynchronous, and you don't need to special declaration in the python script. Asynchrony implemented by JavaScript engines using libuv thread pools, not python.
appModule.call()
method call python functions are all asynchronous, and you don't need to special declaration in the python script. Asynchrony implemented by JavaScript engines using libuv thread pools, not python.
This is my code, and I want to get word_boundaries
async def tts(content, output_file_url="test.mp3", voice="zh-CN-YunxiNeural"):
communicate = edge_tts.Communicate(content, voice)
word_boundaries = []
with open(output_file_url, "wb") as file:
async for chunk in communicate.stream():
if chunk["type"] == "audio":
file.write(chunk["data"])
elif chunk["type"] == "WordBoundary":
word_boundaries.append(chunk)
return word_boundaries
@supercoderlee
@WoJiaoFuXiaoYun Python 的 async 函数在 asyncio.run()
方法调用时就能直接返回结果,下面是简单的案例。
app.py
import asyncio
async def sum(a, b):
return a + b
def speak():
result = asyncio.run(sum(1, 2))
return result # return sum function result
main.js
const pyrunner = require('node-pyrunner')
pyrunner.config['module_search_paths'].push('./pyscript');
pyrunner.init();
let appModule = pyrunner.import('app');
// 同步调用speak函数
let data = appModule.callSync('speak', []);
console.log(data); // 3
// 异步调用speak函数
appModule.call('speak', [], (data)=>{
console.log(data); // 3
}, (error)=>{
console.log(error);
});
你可以把以上案例改为使用 edge_tts
模块。请注意,因为 Node-PyRunner
使用的是 python3.10
版本,所以请用 python3.10
创建 venv
虚拟环境,并在该环境下安装 edge_tts
模块,否则该模块无法使用。
app.py
import asyncio
import edge_tts
import json
async def tts(content, output_file_url="test.mp3", voice="zh-CN-YunxiNeural"):
communicate = edge_tts.Communicate(content, voice)
word_boundaries = []
with open(output_file_url, "wb") as file:
async for chunk in communicate.stream():
if chunk["type"] == "audio":
file.write(chunk["data"])
elif chunk["type"] == "WordBoundary":
word_boundaries.append(chunk)
return word_boundaries
def speak():
result = asyncio.run(tts('Hello Node-PyRunner'))
return json.dumps(result)
除了 return 返回值,你还可以用回调的方式返回值,在 python 脚本中用 nodepyrunner.callJs
方法回调 JavaScript 函数。nodepyrunner
是 内置的Python模块,不需要安装且只能在 Node-PyRunner
中使用。
app.py
import nodepyrunner
import asyncio
import edge_tts
import json
async def tts(content, output_file_url="test.mp3", voice="zh-CN-YunxiNeural"):
communicate = edge_tts.Communicate(content, voice)
word_boundaries = []
with open(output_file_url, "wb") as file:
async for chunk in communicate.stream():
if chunk["type"] == "audio":
file.write(chunk["data"])
elif chunk["type"] == "WordBoundary":
word_boundaries.append(chunk)
# 回调JS函数
nodepyrunner.callJs(target='speakCallback', args=[json.dumps(word_boundaries)])
def speak():
result = asyncio.run(tts('Hello Node-PyRunner'))
main.js
const pyrunner = require('node-pyrunner')
pyrunner.config['module_search_paths'].push('./pyscript');
pyrunner.init();
let appModule = pyrunner.import('app');
// 被Python回调的JS函数
speakCallback = function (data) {
console.log(`speakCallback:${data}`);
}
// 同步调用speak函数
let data = appModule.callSync('speak', []);
console.log(data);
// 异步调用speak函数
appModule.call('speak', []);
Thank you so much
The
appModule.call
method will not be able to retrieve the return value.