Add a frameless always-on-top caption window wired to the live capture pipeline. Silence-based segmentation gates the audio so the model never sees silence, and the panel background is painted in paintEvent with a configurable opacity instead of a style sheet. 新增悬浮字幕窗(无边框、置顶、可折叠/展开),接入实时采集与流式转写。 分段由静音检测驱动,静音期间不送音频,避免模型对静音产生幻觉。底板 改为在 paintEvent 中绘制,不透明度可调。
53 lines
1.3 KiB
C++
53 lines
1.3 KiB
C++
#pragma once
|
|
|
|
#include <QObject>
|
|
#include <QString>
|
|
|
|
#include <condition_variable>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
#include "audio.h"
|
|
#include "streamingasr.h"
|
|
|
|
namespace lc {
|
|
|
|
class Qwen3Asr;
|
|
|
|
// 实时字幕:采集默认输出 → 流式转写 → 用信号把文本推给 UI。
|
|
// 分段由静音检测驱动:句子之间的自然停顿就收束一段、清空上下文,
|
|
// 这样解码器的上下文不会无限增长(见 docs/phase2-streaming.md)。
|
|
class LiveTranscriber : public QObject {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit LiveTranscriber(Qwen3Asr & asr, QObject * parent = nullptr);
|
|
~LiveTranscriber() override;
|
|
|
|
bool start(const StreamOptions & opts, QString * error = nullptr);
|
|
void stop();
|
|
|
|
QString deviceName() const;
|
|
|
|
Q_SIGNALS:
|
|
// committed = 已稳定文本;tail = 不稳定尾部(UI 用暗色显示)
|
|
void caption(const QString & committed, const QString & tail, const QString & language);
|
|
void failed(const QString & message);
|
|
|
|
private:
|
|
void workerLoop();
|
|
|
|
Qwen3Asr & asr_;
|
|
MonitorCapture capture_;
|
|
StreamOptions opts_;
|
|
std::thread worker_;
|
|
std::mutex mutex_;
|
|
std::condition_variable cv_;
|
|
std::vector<float> pending_;
|
|
bool quit_ = false;
|
|
};
|
|
|
|
} // namespace lc
|