Move all business logic into liblivecaption_core (no Qt dependency) and the widgets into liblivecaption_ui, leaving two executables: the caption window and the CLI, which no longer links Qt Widgets. Abstract the ASR backend behind IAsr so the streaming policy and the live pipeline can be tested with a scripted fake backend instead of a real model. 把全部业务逻辑下沉到不依赖 Qt 的 liblivecaption_core,界面独立成 liblivecaption_ui,拆出悬浮窗与命令行两个可执行程序(CLI 不再链接 Qt Widgets);并用 IAsr 抽象推理后端,使流式策略与实时管线可脱离真模型 用假实现做单元测试。测试还抓到一个真 bug:段恰好结束在 chunk 边界时 只提交了稳定部分,最后几个词被丢掉,已修。
61 lines
1.5 KiB
C++
61 lines
1.5 KiB
C++
#include "livetranscriber.h"
|
|
|
|
#include "iasr.h"
|
|
|
|
namespace lc {
|
|
|
|
LiveTranscriber::LiveTranscriber(IAsr & asr, QObject * parent)
|
|
: QObject(parent), asr_(asr)
|
|
{
|
|
}
|
|
|
|
LiveTranscriber::~LiveTranscriber()
|
|
{
|
|
stop();
|
|
}
|
|
|
|
QString LiveTranscriber::deviceName() const
|
|
{
|
|
return pipeline_ ? QString::fromStdString(pipeline_->deviceName()) : QString();
|
|
}
|
|
|
|
bool LiveTranscriber::start(const StreamOptions & opts, QString * error)
|
|
{
|
|
stop();
|
|
|
|
LivePipelineOptions popt;
|
|
popt.stream = opts;
|
|
|
|
pipeline_ = std::make_unique<LivePipeline>(asr_, popt);
|
|
|
|
// 回调在工作线程上被调用;连到主线程的接收者时 Qt 会自动排队投递。
|
|
pipeline_->setCaptionCallback([this](const std::string & committed,
|
|
const std::string & tail,
|
|
const std::string & language) {
|
|
Q_EMIT caption(QString::fromStdString(committed),
|
|
QString::fromStdString(tail),
|
|
QString::fromStdString(language));
|
|
});
|
|
pipeline_->setErrorCallback([this](const std::string & message) {
|
|
Q_EMIT failed(QString::fromStdString(message));
|
|
});
|
|
|
|
std::string err;
|
|
if (!pipeline_->start(&err)) {
|
|
if (error) *error = QString::fromStdString(err);
|
|
pipeline_.reset();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void LiveTranscriber::stop()
|
|
{
|
|
if (pipeline_) {
|
|
pipeline_->stop();
|
|
pipeline_.reset();
|
|
}
|
|
}
|
|
|
|
} // namespace lc
|