Commit 3095789a authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Text based editing: show speech recognition progress, initial search

parent d6d10481
Pipeline #50338 passed with stage
in 10 minutes and 29 seconds
......@@ -37,15 +37,10 @@
TextBasedEdit::TextBasedEdit(QWidget *parent)
: QWidget(parent)
, m_clipDuration(0.)
{
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
setupUi(this);
m_abortAction = new QAction(i18n("Abort"), this);
connect(m_abortAction, &QAction::triggered, [this]() {
if (m_speechJob && m_speechJob->state() == QProcess::Running) {
m_speechJob->kill();
}
});
vosk_config->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
vosk_config->setToolTip(i18n("Configure speech recognition"));
connect(vosk_config, &QToolButton::clicked, [this]() {
......@@ -53,7 +48,13 @@ TextBasedEdit::TextBasedEdit(QWidget *parent)
});
connect(button_start, &QPushButton::clicked, this, &TextBasedEdit::startRecognition);
listWidget->setWordWrap(true);
search_frame->setVisible(false);
frame_progress->setVisible(false);
button_abort->setIcon(QIcon::fromTheme(QStringLiteral("process-stop")));
connect(button_abort, &QToolButton::clicked, [this]() {
if (m_speechJob && m_speechJob->state() == QProcess::Running) {
m_speechJob->kill();
}
});
connect(pCore.get(), &Core::updateVoskAvailability, this, &TextBasedEdit::updateAvailability);
connect(pCore.get(), &Core::voskModelUpdate, [&](QStringList models) {
language_box->clear();
......@@ -79,6 +80,16 @@ TextBasedEdit::TextBasedEdit(QWidget *parent)
connect(language_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), [this]() {
KdenliveSettings::setVosk_text_model(language_box->currentText());
});
connect(listWidget, &QListWidget::itemDoubleClicked, [this] (QListWidgetItem *item) {
if (item) {
double startMs = item->data(Qt::UserRole).toDouble();
double endMs = item->data(Qt::UserRole + 1).toDouble();
pCore->getMonitor(Kdenlive::ClipMonitor)->requestSeek(GenTime(startMs).frames(pCore->getCurrentFps()));
pCore->getMonitor(Kdenlive::ClipMonitor)->slotLoadClipZone(QPoint(GenTime(startMs).frames(pCore->getCurrentFps()), GenTime(endMs).frames(pCore->getCurrentFps())));
pCore->getMonitor(Kdenlive::ClipMonitor)->slotPlayZone();
}
});
connect(listWidget, &QListWidget::currentRowChanged, [this] (int ix) {
if (ix > -1) {
QListWidgetItem *item = listWidget->item(ix);
......@@ -92,6 +103,71 @@ TextBasedEdit::TextBasedEdit(QWidget *parent)
}
});
info_message->hide();
// Search stuff
search_frame->setVisible(false);
button_search->setIcon(QIcon::fromTheme(QStringLiteral("edit-find")));
search_prev->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
search_next->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
connect(button_search, &QToolButton::toggled, this, [&](bool toggled) {
search_frame->setVisible(toggled);
});
connect(search_line, &QLineEdit::textChanged, [this](const QString &searchText) {
if (searchText.length() > 2) {
int ix = listWidget->currentRow();
bool found = false;
QListWidgetItem *item;
while (!found && ix < listWidget->count()) {
item = listWidget->item(ix);
if (item) {
if (item->text().contains(searchText)) {
listWidget->setCurrentRow(ix);
found = true;
break;
}
}
ix++;
}
}
});
connect(search_next, &QToolButton::clicked, [this]() {
const QString searchText = search_line->text();
if (searchText.length() > 2) {
int ix = listWidget->currentRow() + 1;
bool found = false;
QListWidgetItem *item;
while (!found && ix < listWidget->count()) {
item = listWidget->item(ix);
if (item) {
if (item->text().contains(searchText)) {
listWidget->setCurrentRow(ix);
found = true;
break;
}
}
ix++;
}
}
});
connect(search_prev, &QToolButton::clicked, [this]() {
const QString searchText = search_line->text();
if (searchText.length() > 2) {
int ix = listWidget->currentRow() - 1;
bool found = false;
QListWidgetItem *item;
while (!found && ix > 0) {
item = listWidget->item(ix);
if (item) {
if (item->text().contains(searchText)) {
listWidget->setCurrentRow(ix);
found = true;
break;
}
}
ix--;
}
}
});
parseVoskDictionaries();
}
......@@ -139,6 +215,7 @@ void TextBasedEdit::startRecognition()
if (clipItem) {
m_sourceUrl = clipItem->url();
clipName = clipItem->clipName();
m_clipDuration = clipItem->duration().seconds();
}
}
if (m_sourceUrl.isEmpty()) {
......@@ -149,7 +226,6 @@ void TextBasedEdit::startRecognition()
}
info_message->setMessageType(KMessageWidget::Information);
info_message->setText(i18n("Starting speech recognition on %1.", clipName));
info_message->addAction(m_abortAction);
info_message->animatedShow();
qApp->processEvents();
//m_speechJob->setProcessChannelMode(QProcess::MergedChannels);
......@@ -158,6 +234,8 @@ void TextBasedEdit::startRecognition()
listWidget->clear();
qDebug()<<"=== STARTING RECO: "<<speechScript<<" / "<<modelDirectory<<" / "<<language<<" / "<<m_sourceUrl;
m_speechJob->start(pyExec, {speechScript, modelDirectory, language, m_sourceUrl});
speech_progress->setValue(0);
frame_progress->setVisible(true);
/*if (m_speechJob->QFile::exists(speech)) {
timeline->getSubtitleModel()->importSubtitle(speech, zone.x(), true);
speech_info->setMessageType(KMessageWidget::Positive);
......@@ -177,7 +255,6 @@ void TextBasedEdit::updateAvailability()
void TextBasedEdit::slotProcessSpeechStatus(int, QProcess::ExitStatus status)
{
info_message->removeAction(m_abortAction);
if (status == QProcess::CrashExit) {
info_message->setMessageType(KMessageWidget::Warning);
info_message->setText(i18n("Speech recognition aborted."));
......@@ -187,6 +264,7 @@ void TextBasedEdit::slotProcessSpeechStatus(int, QProcess::ExitStatus status)
info_message->setText(i18n("Speech recognition finished."));
info_message->animatedShow();
}
frame_progress->setVisible(false);
}
void TextBasedEdit::slotProcessSpeech()
......@@ -249,6 +327,9 @@ void TextBasedEdit::slotProcessSpeech()
if (val.isObject() && val.toObject().keys().contains("end")) {
double ms = val.toObject().value("end").toDouble();
item->setData(Qt::UserRole + 1, ms);
if (m_clipDuration > 0.) {
speech_progress->setValue(static_cast<int>(100 * ms / m_clipDuration));
}
}
}
item->setText(itemText);
......
......@@ -54,7 +54,7 @@ private:
std::unique_ptr<QProcess> m_speechJob;
QString m_binId;
QString m_sourceUrl;
QAction *m_abortAction;
double m_clipDuration;
};
#endif
......@@ -6,29 +6,103 @@
<rect>
<x>0</x>
<y>0</y>
<width>392</width>
<height>366</height>
<width>514</width>
<height>484</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0" colspan="3">
<item row="5" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>250</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="4">
<widget class="QFrame" name="frame_progress">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="button_abort">
<property name="text">
<string>...</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="speech_progress">
<property name="value">
<number>24</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="3">
<widget class="QPushButton" name="button_start">
<property name="text">
<string>Start recognition</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="4">
<widget class="KMessageWidget" name="info_message"/>
</item>
<item row="0" column="0" colspan="4">
<widget class="QListWidget" name="listWidget">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0" colspan="4">
<widget class="QFrame" name="edit_frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QToolButton" name="button_delete">
<property name="leftMargin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QToolButton" name="button_up">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="button_up">
<item row="0" column="0">
<widget class="QToolButton" name="button_delete">
<property name="text">
<string>...</string>
</property>
......@@ -41,7 +115,7 @@
</property>
</widget>
</item>
<item row="0" column="3">
<item row="0" column="4">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
......@@ -54,17 +128,27 @@
</property>
</spacer>
</item>
<item row="0" column="4">
<item row="0" column="5">
<widget class="QToolButton" name="vosk_config">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="button_search">
<property name="text">
<string>...</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" colspan="3">
<item row="4" column="0" colspan="4">
<widget class="QFrame" name="search_frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
......@@ -81,7 +165,14 @@
</widget>
</item>
<item row="0" column="0">
<widget class="QLineEdit" name="search_line"/>
<widget class="QLineEdit" name="search_line">
<property name="placeholderText">
<string>Search</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="search_next">
......@@ -93,39 +184,9 @@
</layout>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0" colspan="2">
<widget class="QComboBox" name="language_box"/>
</item>
<item row="4" column="2">
<widget class="QPushButton" name="button_start">
<property name="text">
<string>Start recognition</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QListWidget" name="listWidget">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="KMessageWidget" name="info_message"/>
</item>
<item row="4" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>250</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment