1
/***************************************************************************
2
* Copyright (C) 2009 by Kai Dombrowe <just89@gmx.de> *
4
* This program is free software; you can redistribute it and/or modify *
5
* it under the terms of the GNU General Public License as published by *
6
* the Free Software Foundation; either version 2 of the License, or *
7
* (at your option) any later version. *
9
* This program is distributed in the hope that it will be useful, *
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12
* GNU General Public License for more details. *
14
* You should have received a copy of the GNU General Public License *
15
* along with this program; if not, write to the *
16
* Free Software Foundation, Inc., *
17
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
18
***************************************************************************/
22
#include "recordmydesktoprecorder.h"
23
#include <recorditnow_recordmydesktop.h>
26
#include <kplugininfo.h>
29
#include <kstandarddirs.h>
33
#include <QtGui/QWidget>
34
#include <QtCore/QDir>
37
#include <sys/types.h>
42
K_PLUGIN_FACTORY(myFactory, registerPlugin<RecordMyDesktopRecorder>();)
43
K_EXPORT_PLUGIN(myFactory("recordmydesktop_recorder"))
44
RecordMyDesktopRecorder::RecordMyDesktopRecorder(QObject *parent, const QVariantList &args)
45
: AbstractRecorder(parent, args)
49
m_data.paused = false;
54
RecordMyDesktopRecorder::~RecordMyDesktopRecorder()
62
void RecordMyDesktopRecorder::record(const AbstractRecorder::Data &d)
65
const QString recordMyDesktop = KGlobal::dirs()->findExe("recordmydesktop");
66
if (recordMyDesktop.isEmpty()) {
67
emit error(i18n("Cannot find recordmydesktop!\n"
68
"Please install recordmydesktop or use another plugin."));
78
m_data.overwrite = d.overwrite;
79
m_data.outputFile = d.outputFile;
80
m_data.tmpFile = getTemporaryFile(d.workDir)+".ogv";
81
args << "-o" << m_data.tmpFile;
84
args << "--windowid" << QString::number(d.winId);
86
if (d.geometry.x() > 0) {
87
args << QString("-x") << QString::number(d.geometry.x());
89
if (d.geometry.y() > 0) {
90
args << QString("-y") << QString::number(d.geometry.y());
92
args << QString("-width") << QString::number(d.geometry.width());
93
args << QString("-height") << QString::number(d.geometry.height());
95
args << "--fps" << QString::number(d.fps);
96
args << "--workdir" << d.workDir;
98
// recordmydesktop cfg
99
Settings::self()->readConfig(); // cfg changed?
102
if (Settings::__no_cursor()) {
103
args << "--no-cursor";
105
if (Settings::__no_shared()) {
106
args << "--no-shared";
108
if (Settings::__full_shots()) {
109
args << "--full-shots";
111
if (Settings::__subsampling()) {
112
args << "--quick-subsampling";
116
if (Settings::__channels() != -1) {
117
args << "--channels" << QString::number(Settings::__channels());
119
if (Settings::__freq() != -1) {
120
args << "--freq" << QString::number(Settings::__freq());
122
if (Settings::__buffer_size() != -1) {
123
args << "--buffer-size" << QString::number(Settings::__buffer_size());
125
if (Settings::__ring_buffer_size() != -1) {
126
args << "--ring-buffer-size" << QString::number(Settings::__ring_buffer_size());
128
if (Settings::__device() != "hw:0,0" && !Settings::__device().isEmpty()) {
129
args << "--device" << Settings::__device();
131
if (!Settings::__use_jack().isEmpty()) {
132
args << "--use-jack" << Settings::__use_jack();
136
if (Settings::__on_the_fly_encoding()) {
137
args << "--on-the-fly-encoding";
140
args << "--v_quality" << QString::number(Settings::__v_quality());
141
args << "--v_bitrate" << QString::number(Settings::__v_bitrate());
142
args << "--s_quality" << QString::number(Settings::__s_quality());
145
if (Settings::__no_wm_check()) {
146
args << "--no-wm-check";
148
if (Settings::__compress_cache()) {
149
args << "--compress-cache";
151
if (Settings::followMouse()) {
152
args << "--follow-mouse";
154
if (!Settings::frame()) {
155
args << "--no-frame";
159
m_recorder = new KProcess(this);
160
m_recorder->setOutputChannelMode(KProcess::MergedChannels);
162
connect(m_recorder, SIGNAL(readyReadStandardOutput()), this, SLOT(newRecorderOutput()));
163
connect(m_recorder, SIGNAL(finished(int)), this, SLOT(recorderFinished(int)));
165
kDebug() << "starting:" << recordMyDesktop << "with:" << args;
167
m_recorder->setProgram(recordMyDesktop, args);
175
void RecordMyDesktopRecorder::pause()
182
if (!m_data.paused) {
183
emit status(i18n("Paused!"));
184
kill(m_recorder->pid(), SIGSTOP);
185
m_data.paused = true;
187
emit status(i18n("Capturing!"));
188
kill(m_recorder->pid(), SIGCONT);
189
m_data.paused = false;
195
void RecordMyDesktopRecorder::stop()
199
kill(m_recorder->pid(), SIGINT);
200
m_data.paused = false;
206
void RecordMyDesktopRecorder::newRecorderOutput()
213
QString output = QString(m_recorder->readAllStandardOutput()).trimmed();
215
if (output.isEmpty()) {
219
foreach (QString line, output.split('\n')) {
220
kDebug() << "New Line:" << line;
221
line = line.trimmed();
224
if (line.startsWith("Cached")) {
225
QString cached = line.remove(0, 7);
226
QString rec = line.remove(0, line.indexOf("from ")+5);
228
cached.remove(cached.indexOf(','), cached.length());
229
rec.remove(rec.indexOf("that"), rec.length());
231
emit status(i18n("Cached: %1", cached));
232
emit status(i18n("Received: %1", rec));
233
} else if (line.startsWith("Saved ")) {
234
QString frames = line.remove("Saved ");
235
frames.remove(frames.indexOf("frames"), frames.length());
236
emit status(i18n("Frames: %1", frames));
237
} else if (line.startsWith("Output file:")) {
238
m_data.tmpFile = line.remove(0, 13);
239
} else if (line.startsWith("[")) {
240
for (int i = 0; i < line.length(); i++) {
241
if (line[i] == '[') {
246
const int percent = line.mid(0, line.indexOf('%', 0)).toInt();
247
line.remove(0, line.indexOf("]"));
249
emit status(i18n("Encoding: %1",
250
QString::number(percent > 100 ? 100 : percent)+'%'));
254
if (line == "Capturing!") {
255
emit status(i18n("Capturing!"));
256
} else if (line == "Shutting down..") {
257
emit status(i18n("Shutting down.."));
258
} else if (line == "Encoding started!") {
259
emit status(i18n("Encoding started!"));
260
} else if (line == "Done!!!") {
261
emit status(i18n("Done!"));
262
} else if (line.startsWith("Cannot open file")) {
263
line = line.remove("Cannot open file ");
264
line = line.remove(" for writting!");
265
emit error(i18n("Cannot open file %1 for writting!", line));
266
} else if (line.startsWith("Could not create temporary directory")) {
267
emit error(i18n("Could not create temporary directory, check your config."));
268
} else if (line.startsWith("recordMyDesktop is not compiled with Jack support!")) {
269
emit error(i18n("recordMyDesktop is not compiled with Jack support."));
270
} else if (line.startsWith("Error while opening/configuring soundcard")) {
271
emit error(i18n("Error while opening/configuring soundcard."));
272
} else if (line.startsWith("Window size specification out of bounds!")) {
273
emit error(i18n("Window size specification out of bounds!"));
280
bool RecordMyDesktopRecorder::remove(const QString &file)
285
emit error(i18nc("%1 = file, %2 = error string", "recordmydesktop: Remove failed: %1.\n"
286
"Reason: %2", file, f.errorString()));
294
bool RecordMyDesktopRecorder::move(const QString &from, const QString &to)
298
if (!file.rename(from, to)) {
299
emit error(i18nc("%1 = source, %1 = destination, %3 = error string",
300
"Move failed: \"%1\" to \"%2\".\n"
301
"Reason: %3", from, to, file.errorString()));
309
void RecordMyDesktopRecorder::clean()
313
m_recorder->disconnect(this);
314
if (m_recorder->state() != KProcess::NotRunning) {
315
m_recorder->terminate();
317
m_recorder->waitForFinished(-1);
318
m_recorder->deleteLater();
325
void RecordMyDesktopRecorder::recorderFinished(const int &ret)
328
const KProcess::ExitStatus status = m_recorder->exitStatus();
329
kDebug() << "status:" << status << "ret:" << ret;
331
if (status == KProcess::CrashExit || ret != 0) {
333
emit finished(Crash);
337
QFile outputFile(m_data.outputFile);
338
if (outputFile.exists()) {
339
if (m_data.overwrite) {
340
if (!remove(m_data.outputFile)) {
345
m_data.outputFile = unique(m_data.outputFile);
346
emit outputFileChanged(m_data.outputFile);
350
if (!move(m_data.tmpFile, m_data.outputFile)) {
357
if (status == KProcess::CrashExit) {
358
emit finished(Crash);
360
emit finished(Normal);
366
#include "recordmydesktoprecorder.moc"