aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mardelle <[email protected]>2015-06-08 23:36:09 +0200
committerJean-Baptiste Mardelle <[email protected]>2015-06-08 23:36:09 +0200
commit2a20154fa3b36ffdfce0473c49c9c5577ac5dfff (patch)
treebe57486215745567cf6609f5f1d65eaf238ccfb3
parenta7388d6c1ddbad39b0d40667b2972c885dfcff43 (diff)
Re-introduce recording. Currently only screen grab works.
Available from the clip monitor, click on the "+" icon next to the timecode to show/hide rec controls CCBUG: 348891
-rw-r--r--src/bin/bin.cpp9
-rw-r--r--src/bin/bin.h2
-rw-r--r--src/monitor/monitor.cpp151
-rw-r--r--src/monitor/monitor.h17
4 files changed, 177 insertions, 2 deletions
diff --git a/src/bin/bin.cpp b/src/bin/bin.cpp
index 5db51af..133143d 100644
--- a/src/bin/bin.cpp
+++ b/src/bin/bin.cpp
@@ -512,6 +512,7 @@ QUrl Bin::projectFolder() const
void Bin::setMonitor(Monitor *monitor)
{
m_monitor = monitor;
+ connect(m_monitor, SIGNAL(addClipToProject(QUrl)), this, SLOT(slotAddClipToProject(QUrl)));
connect(m_eventEater, SIGNAL(focusClipMonitor()), m_monitor, SLOT(slotActivateMonitor()), Qt::UniqueConnection);
}
@@ -1640,6 +1641,14 @@ void Bin::droppedUrls(QList <QUrl> urls, const QMap<QString,QString> properties)
slotItemDropped(urls, current);
}
+void Bin::slotAddClipToProject(QUrl url)
+{
+ QList <QUrl> urls;
+ urls << url;
+ QModelIndex current = m_proxyModel->mapToSource(m_proxyModel->selectionModel()->currentIndex());
+ slotItemDropped(urls, current);
+}
+
void Bin::slotItemDropped(const QList<QUrl>&urls, const QModelIndex &parent)
{
QStringList folderInfo;
diff --git a/src/bin/bin.h b/src/bin/bin.h
index 9665aed..30dca6e 100644
--- a/src/bin/bin.h
+++ b/src/bin/bin.h
@@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QPainter>
#include <QDomElement>
#include <QPushButton>
+#include <QUrl>
class KdenliveDoc;
class ClipController;
@@ -460,6 +461,7 @@ private slots:
void slotEffectDropped(QString effect, const QModelIndex &parent);
void slotItemEdited(QModelIndex,QModelIndex,QVector<int>);
void slotAddUrl(QString url, QMap <QString, QString> data = QMap <QString, QString>());
+ void slotAddClipToProject(QUrl url);
void slotPrepareJobsMenu();
void slotShowJobLog();
/** @brief process clip job result. */
diff --git a/src/monitor/monitor.cpp b/src/monitor/monitor.cpp
index 5cb5027..d850c54 100644
--- a/src/monitor/monitor.cpp
+++ b/src/monitor/monitor.cpp
@@ -69,6 +69,11 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren
, m_splitProducer(NULL)
, m_effectCompare(NULL)
, m_forceSizeFactor(0)
+ , m_recAction(NULL)
+ , m_recToolbar(NULL)
+ , m_screenCombo(NULL)
+ , m_captureProcess(NULL)
+ , m_switchRec(NULL)
{
QVBoxLayout *layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
@@ -118,6 +123,12 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren
m_toolbar = new QToolBar(this);
m_toolbar->setIconSize(QSize(s, s));
+ if (id == Kdenlive::ClipMonitor) {
+ // Add options for recording
+ m_recToolbar = new QToolBar(this);
+ m_recToolbar->setIconSize(QSize(s, s));
+ }
+
m_playIcon = QIcon::fromTheme("media-playback-start");
m_pauseIcon = QIcon::fromTheme("media-playback-pause");
@@ -185,12 +196,35 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren
if (KdenliveSettings::volume() == 0) icon = QIcon::fromTheme("audio-volume-muted");
else icon = QIcon::fromTheme("audio-volume-medium");
m_volumeWidget = m_toolbar->widgetForAction(m_toolbar->addAction(icon, i18n("Audio volume"), this, SLOT(slotShowVolume())));
-
if (id == Kdenlive::ClipMonitor) {
m_toolbar->addSeparator();
m_effectCompare = m_toolbar->addAction(QIcon::fromTheme("view-split-left-right"), i18n("Compare effect"));
m_effectCompare->setCheckable(true);
- connect(m_effectCompare, SIGNAL(toggled(bool)), this, SLOT(slotSwitchCompare(bool)));
+ connect(m_effectCompare, &QAction::toggled, this, &Monitor::slotSwitchCompare);
+
+ // Recording options
+ m_recAction = m_recToolbar->addAction(QIcon::fromTheme("media-record"), i18n("Record"));
+ m_recAction->setCheckable(true);
+ connect(m_recAction, &QAction::toggled, this, &Monitor::slotRecord);
+
+ // Check number of monitors for FFmpeg screen capture
+ int screens = QApplication::desktop()->screenCount();
+ if (screens > 1) {
+ m_screenCombo = new QComboBox(this);
+ for (int ix = 0; ix < screens; ix++) {
+ m_screenCombo->addItem(i18n("Monitor %1", ix));
+ }
+ m_recToolbar->addWidget(m_screenCombo);
+ // Update screen grab monitor choice in case we changed from fullscreen
+ m_screenCombo->setEnabled(KdenliveSettings::grab_capture_type() == 0);
+ }
+ QWidget *spacer = new QWidget(this);
+ spacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+ m_recToolbar->addWidget(spacer);
+ m_switchRec = m_recToolbar->addAction(QIcon::fromTheme("list-add"), i18n("Show Record Control"));
+ m_switchRec->setCheckable(true);
+ connect(m_switchRec, &QAction::toggled, this, &Monitor::slotSwitchRec);
+ m_recToolbar->setVisible(false);
}
// we need to show / hide the popup once so that it's geometry can be calculated in slotShowVolume
m_volumePopup->show();
@@ -230,11 +264,13 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren
QWidget *spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
m_toolbar->addWidget(spacer);
+ if (m_switchRec) m_toolbar->addAction(m_switchRec);
m_timePos = new TimecodeDisplay(m_monitorManager->timecode(), this);
m_toolbar->addWidget(m_timePos);
connect(m_timePos, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotSeek()));
m_toolbar->setMaximumHeight(m_timePos->height());
layout->addWidget(m_toolbar);
+ if (m_recToolbar) layout->addWidget(m_recToolbar);
// Info message widget
m_infoMessage = new KMessageWidget(this);
@@ -1445,3 +1481,114 @@ Mlt::Profile *Monitor::profile()
return m_monitorManager->binController()->profile();
}
+
+void Monitor::slotRecord(bool record)
+{
+ if (!record) {
+ if (!m_captureProcess) return;
+ m_captureProcess->terminate();
+ QTimer::singleShot(1500, m_captureProcess, SLOT(kill()));
+ return;
+ }
+ if (m_captureProcess) return;
+ m_recError.clear();
+ m_captureProcess = new QProcess;
+ connect(m_captureProcess, &QProcess::stateChanged, this, &Monitor::slotProcessStatus);
+ connect(m_captureProcess, &QProcess::readyReadStandardError, this, &Monitor::slotReadProcessInfo);
+
+ QString extension = KdenliveSettings::grab_extension();
+ QString capturePath = KdenliveSettings::capturefolder();
+ QString path = QUrl(capturePath).path() + QDir::separator() + "capture0000." + extension;
+ int i = 1;
+ while (QFile::exists(path)) {
+ QString num = QString::number(i).rightJustified(4, '0', false);
+ path = QUrl(capturePath).path() + QDir::separator() + "capture" + num + '.' + extension;
+ ++i;
+ }
+ m_captureFile = QUrl(path);
+ QString args;
+ QString captureSize;
+ int screen = -1;
+ if (m_screenCombo) {
+ // Multi monitor setup, capture monitor selected by user
+ screen = m_screenCombo->currentIndex();
+ }
+ QRect screenSize = QApplication::desktop()->screenGeometry(screen);
+ QStringList captureArgs;
+ captureArgs << "-f" << "x11grab";
+ if (KdenliveSettings::grab_follow_mouse()) captureArgs << "-follow_mouse" << "centered";
+ if (!KdenliveSettings::grab_hide_frame()) captureArgs << "-show_region" << "1";
+ captureSize = ":0.0";
+ if (KdenliveSettings::grab_capture_type() == 0) {
+ // Full screen capture
+ captureArgs << "-s" << QString::number(screenSize.width()) + 'x' + QString::number(screenSize.height());
+ captureSize.append('+' + QString::number(screenSize.left()) + '.' + QString::number(screenSize.top()));
+ } else {
+ // Region capture
+ captureArgs << "-s" << QString::number(KdenliveSettings::grab_width()) + 'x' + QString::number(KdenliveSettings::grab_height());
+ captureSize.append('+' + QString::number(KdenliveSettings::grab_offsetx()) + '.' + QString::number(KdenliveSettings::grab_offsetx()));
+ }
+ // fps
+ captureArgs << "-r" << QString::number(KdenliveSettings::grab_fps());
+ if (KdenliveSettings::grab_hide_mouse()) captureSize.append("+nomouse");
+ captureArgs << "-i" << captureSize;
+ if (!KdenliveSettings::grab_parameters().simplified().isEmpty())
+ captureArgs << KdenliveSettings::grab_parameters().simplified().split(' ');
+ captureArgs << path;
+
+ m_captureProcess->start(KdenliveSettings::ffmpegpath(), captureArgs);
+ if (!m_captureProcess->waitForStarted()) {
+ // Problem launching capture app
+ warningMessage(i18n("Failed to start the capture application:\n%1", KdenliveSettings::ffmpegpath()));
+ //delete m_captureProcess;
+ }
+}
+
+
+void Monitor::slotProcessStatus(QProcess::ProcessState status)
+{
+ if (status == QProcess::NotRunning) {
+ m_recAction->setEnabled(true);
+ m_recAction->setChecked(false);
+ //device_selector->setEnabled(true);
+ if (m_captureProcess) {
+ if (m_captureProcess->exitStatus() == QProcess::CrashExit) {
+ warningMessage(i18n("Capture crashed, please check your parameters"));
+ } else {
+ if (true) {
+ int code = m_captureProcess->exitCode();
+ if (code != 0 && code != 255) {
+ warningMessage(i18n("Capture crashed, please check your parameters"));
+ }
+ else {
+ // Capture successfull, add clip to project
+ emit addClipToProject(m_captureFile);
+ }
+ }
+ }
+ }
+ delete m_captureProcess;
+ m_captureProcess = NULL;
+ }
+}
+
+void Monitor::slotReadProcessInfo()
+{
+ QString data = m_captureProcess->readAllStandardError().simplified();
+ m_recError.append(data + '\n');
+}
+
+void Monitor::slotSwitchRec(bool enable)
+{
+ if (enable) {
+ m_toolbar->setVisible(false);
+ m_recToolbar->setVisible(true);
+ }
+ else {
+ if (m_captureProcess) {
+ slotRecord(false);
+ }
+ m_recToolbar->setVisible(false);
+ m_toolbar->setVisible(true);
+ }
+}
diff --git a/src/monitor/monitor.h b/src/monitor/monitor.h
index 9c67663..bc62b54 100644
--- a/src/monitor/monitor.h
+++ b/src/monitor/monitor.h
@@ -34,6 +34,7 @@
#include <QToolBar>
#include <QWindow>
#include <QIcon>
+#include <QProcess>
class SmallRuler;
class ClipController;
@@ -48,6 +49,7 @@ class KSelectAction;
class KMessageWidget;
class QQuickItem;
class QScrollBar;
+class QComboBox;
class Monitor : public AbstractMonitor
{
@@ -131,6 +133,13 @@ private:
Mlt::Producer *m_splitProducer;
int m_length;
bool m_dragStarted;
+ //TODO: Move capture stuff in own class
+ QAction *m_switchRec;
+ QString m_captureFolder;
+ QUrl m_captureFile;
+ QString m_recError;
+ QProcess *m_captureProcess;
+
QIcon m_playIcon;
QIcon m_pauseIcon;
/** @brief The widget showing current time position **/
@@ -140,10 +149,12 @@ private:
/** Has to be available so we can enable and disable it. */
QAction *m_loopClipAction;
QAction *m_effectCompare;
+ QAction *m_recAction;
QMenu *m_contextMenu;
QMenu *m_configMenu;
QMenu *m_playMenu;
QMenu *m_markerMenu;
+ QComboBox *m_screenCombo;
QPoint m_DragStartPosition;
/** Selected clip/transition in timeline. Used for looping it. */
AbstractClipItem *m_selectedClip;
@@ -152,6 +163,7 @@ private:
bool m_loopClipTransition;
GenTime getSnapForPos(bool previous);
QToolBar *m_toolbar;
+ QToolBar *m_recToolbar;
QWidget *m_volumeWidget;
QSlider *m_audioSlider;
QAction *m_editMarker;
@@ -187,6 +199,10 @@ private slots:
void slotShowMenu(const QPoint pos);
void slotForceSize(QAction *a);
void slotSeekToKeyFrame();
+ void slotRecord(bool record);
+ void slotProcessStatus(QProcess::ProcessState status);
+ void slotReadProcessInfo();
+ void slotSwitchRec(bool enable);
public slots:
void slotOpenFile(const QString &);
@@ -247,6 +263,7 @@ signals:
void effectChanged(const QRect);
void addKeyframe();
void seekToKeyframe(int);
+ void addClipToProject(QUrl);
};
#endif