7#include "MovieCapture.h" 
    8#include "MarbleDebug.h" 
   11#include <QElapsedTimer> 
   20class MovieCapturePrivate
 
   23    explicit MovieCapturePrivate(MarbleWidget *widget)
 
   24        : marbleWidget(widget)
 
   25        , method(MovieCapture::TimeDriven)
 
   32    void missingToolsWarning()
 
   36                             QObject::tr(
"Marble requires additional software in order to " 
   37                                         "create movies. Please get %1 ")
 
   38                                 .arg(QStringLiteral(
"<a href=\"https://libav.org/" 
   39                                                     "download.html\">avconv</a>")),
 
   44    MarbleWidget *marbleWidget;
 
   46    QString destinationFile;
 
   48    MovieCapture::SnapshotMethod method;
 
   52MovieCapture::MovieCapture(
MarbleWidget *widget, QObject *parent)
 
   54    , d_ptr(new MovieCapturePrivate(widget))
 
   57    if (d->method == MovieCapture::TimeDriven) {
 
   58        d->frameTimer.setInterval(1000 / 30); 
 
   62    MovieFormat avi(QStringLiteral(
"avi"), tr(
"AVI (mpeg4)"), QStringLiteral(
"avi"));
 
   63    MovieFormat flv(QStringLiteral(
"flv"), tr(
"FLV"), QStringLiteral(
"flv"));
 
   64    MovieFormat mkv(QStringLiteral(
"matroska"), tr(
"Matroska (h264)"), QStringLiteral(
"mkv"));
 
   65    MovieFormat mp4(QStringLiteral(
"mp4"), tr(
"MPEG-4"), QStringLiteral(
"mp4"));
 
   66    MovieFormat vob(QStringLiteral(
"vob"), tr(
"MPEG-2 PS (VOB)"), QStringLiteral(
"vob"));
 
   67    MovieFormat ogg(QStringLiteral(
"ogg"), tr(
"OGG"), QStringLiteral(
"ogg"));
 
   68    MovieFormat swf(QStringLiteral(
"swf"), tr(
"SWF"), QStringLiteral(
"swf"));
 
   69    m_supportedFormats << avi << flv << mkv << mp4 << vob << ogg << swf;
 
   72MovieCapture::~MovieCapture()
 
   77void MovieCapture::setFps(
int fps)
 
   80    if (d->method == MovieCapture::TimeDriven) {
 
   81        d->frameTimer.setInterval(1000 / fps);
 
   86void MovieCapture::setFilename(
const QString &path)
 
   89    d->destinationFile = 
path;
 
   92void MovieCapture::setSnapshotMethod(MovieCapture::SnapshotMethod method)
 
   98int MovieCapture::fps()
 const 
  100    Q_D(
const MovieCapture);
 
  104QString MovieCapture::destination()
 const 
  106    Q_D(
const MovieCapture);
 
  107    return d->destinationFile;
 
  114    if (availableFormats.
isEmpty() && checkToolsAvailability()) {
 
  116        for (
const MovieFormat &format : std::as_const(m_supportedFormats)) {
 
  120            encoder.start(d->encoderExec, args);
 
  121            encoder.waitForFinished();
 
  124            if (isFormatAvailable) {
 
  125                availableFormats << format;
 
  129    return availableFormats;
 
  132MovieCapture::SnapshotMethod MovieCapture::snapshotMethod()
 const 
  134    Q_D(
const MovieCapture);
 
  138bool MovieCapture::checkToolsAvailability()
 
  141    static bool toolsAvailable = 
false;
 
  142    if (toolsAvailable == 
false) {
 
  144        encoder.start(QStringLiteral(
"avconv"), 
QStringList() << QStringLiteral(
"-version"));
 
  145        encoder.waitForFinished();
 
  146        if (!encoder.readAll().isEmpty()) { 
 
  147            d->encoderExec = QStringLiteral(
"avconv");
 
  148            toolsAvailable = 
true;
 
  150            encoder.start(QStringLiteral(
"ffmpeg"), 
QStringList() << QStringLiteral(
"-version"));
 
  151            encoder.waitForFinished();
 
  152            if (!encoder.readAll().isEmpty()) {
 
  153                d->encoderExec = QStringLiteral(
"ffmpeg");
 
  154                toolsAvailable = 
true;
 
  158    return toolsAvailable;
 
  161void MovieCapture::recordFrame()
 
  167                                                    << QStringLiteral(
"rawvideo") << QStringLiteral(
"-pix_fmt") << QStringLiteral(
"rgb24")
 
  168                                                    << QStringLiteral(
"-s") << QStringLiteral(
"%1x%2").
arg(screenshot.
width()).
arg(screenshot.
height())
 
  169                                                    << QStringLiteral(
"-i") << QStringLiteral(
"pipe:") << QStringLiteral(
"-b") << QStringLiteral(
"2000k")
 
  170                                                    << d->destinationFile;
 
  171        d->process.start(d->encoderExec, arguments);
 
  172        connect(&d->process, SIGNAL(finished(
int)), 
this, SLOT(processWrittenMovie(
int)));
 
  175    for (
int i = 0; i < 30 && d->process.bytesToWrite() > 0; ++i) {
 
  177        int then = d->process.bytesToWrite();
 
  179        d->process.waitForBytesWritten(100);
 
  181        int now = d->process.bytesToWrite();
 
  182        int bytesWritten = then - now;
 
  183        double rate = (bytesWritten * 1000.0) / (qMax(1, span) * 1024);
 
  184        Q_EMIT rateCalculated(rate);
 
  188bool MovieCapture::startRecording()
 
  192    if (!checkToolsAvailability()) {
 
  193        d->missingToolsWarning();
 
  197    if (d->method == MovieCapture::TimeDriven) {
 
  198        d->frameTimer.start();
 
  204void MovieCapture::stopRecording()
 
  208    d->frameTimer.stop();
 
  209    d->process.closeWriteChannel();
 
  212void MovieCapture::cancelRecording()
 
  216    d->frameTimer.stop();
 
  221void MovieCapture::processWrittenMovie(
int exitCode)
 
  224        mDebug() << 
"[*] avconv finished with" << exitCode;
 
  225        Q_EMIT errorOccured();
 
  231#include "moc_MovieCapture.cpp" 
Type type(const QSqlDatabase &db)
 
QString path(const QString &relativePath)
 
Binds a QML item to a specific geodetic location in screen coordinates.
 
qint64 elapsed() const const
 
qsizetype sizeInBytes() const const
 
bool isEmpty() const const
 
StandardButton warning(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons, StandardButton defaultButton)
 
QString tr(const char *sourceText, const char *disambiguation, int n)
 
QString arg(Args &&... args) const const
 
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
 
QString fromLatin1(QByteArrayView str)
 
QString number(double n, char format, int precision)
 
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)