Пример #1
0
QDomElement LayerCamera::createDomElement( QDomDocument& doc )
{
    QDomElement layerTag = doc.createElement("layer");
    
    layerTag.setAttribute("name", mName);
    layerTag.setAttribute("visibility", visible);
    layerTag.setAttribute("type", type());
    layerTag.setAttribute("width", viewRect.width());
    layerTag.setAttribute("height", viewRect.height());

    foreachKeyFrame( [&]( KeyFrame* pKeyFrame )
    {
        Camera* camera = static_cast< Camera* >( pKeyFrame );
        QDomElement keyTag = doc.createElement("camera");
        keyTag.setAttribute( "frame", camera->pos() );

        keyTag.setAttribute( "m11", camera->view.m11() );
        keyTag.setAttribute( "m12", camera->view.m12() );
        keyTag.setAttribute( "m21", camera->view.m21() );
        keyTag.setAttribute( "m22", camera->view.m22() );
        keyTag.setAttribute( "dx",  camera->view.dx() );
        keyTag.setAttribute( "dy",  camera->view.dy() );
        layerTag.appendChild( keyTag );
    } );
    
    return layerTag;
}
Пример #2
0
void LayerVector::removeColour( int colorIndex )
{
    foreachKeyFrame( [=]( KeyFrame* pKeyFrame )
    {
        auto pVecImage = static_cast< VectorImage* >( pKeyFrame );
        pVecImage->removeColour( colorIndex );
    } );
}
Пример #3
0
bool LayerVector::usesColour(int colorIndex)
{
    bool bUseColor = false;
    foreachKeyFrame( [&] ( KeyFrame* pKeyFrame )
    {
        auto pVecImage = static_cast< VectorImage* >( pKeyFrame );

        bUseColor = bUseColor || pVecImage->usesColour( colorIndex );
    } );

    return bUseColor;
}
Пример #4
0
QDomElement LayerVector::createDomElement(QDomDocument& doc)
{
    QDomElement layerTag = doc.createElement("layer");

    layerTag.setAttribute( "id", id() );
    layerTag.setAttribute( "name", mName );
    layerTag.setAttribute( "visibility", mVisible );
    layerTag.setAttribute( "type", type() );

    foreachKeyFrame( [&] ( KeyFrame* pKeyFrame )
    {
        VectorImage* pImg = static_cast< VectorImage* >( pKeyFrame );
        //QDomElement imageTag = framesVector[index]->createDomElement(doc); // if we want to embed the data
        QDomElement imageTag = doc.createElement( "image" );
        imageTag.setAttribute( "frame", pKeyFrame->pos() );
        imageTag.setAttribute( "src", fileName( pKeyFrame->pos() ) );
        layerTag.appendChild( imageTag );
    } );

    return layerTag;
}
Пример #5
0
QDomElement LayerSound::createDomElement( QDomDocument& doc )
{
    QDomElement layerTag = doc.createElement( "layer" );
    
    layerTag.setAttribute( "id", id() );
    layerTag.setAttribute( "name", name() );
    layerTag.setAttribute( "visibility", visible() );
    layerTag.setAttribute( "type", type() );

    foreachKeyFrame( [ &doc, &layerTag ]( KeyFrame* pKeyFrame )
    {
        QDomElement imageTag = doc.createElement( "sound" );
        imageTag.setAttribute( "frame", pKeyFrame->pos() );

        QFileInfo info( pKeyFrame->fileName() );
        qDebug() << "Save=" << info.fileName();
        imageTag.setAttribute( "src", info.fileName() );
        layerTag.appendChild( imageTag );
    } );
    
    return layerTag;
}
Пример #6
0
// added parameter exportFps -> frame rate of exported video
// added parameter exportFormat -> to set ffmpeg parameters
bool Object::exportMovie( ExportMovieParameters parameters )
{
    int startFrame = parameters.startFrame;
    int endFrame = parameters.endFrame;
    QTransform view = parameters.view;
    Layer* currentLayer = parameters.currentLayer;
    QSize exportSize = parameters.exportSize;
    QString filePath = parameters.filePath;
    int fps = parameters.fps;
    int exportFps = parameters.exportFps;
    QString exportFormat = parameters.exportFormat;

    if(!filePath.endsWith(".avi", Qt::CaseInsensitive))
    {
        filePath = filePath + ".avi";
    }

    //  additional parameters for ffmpeg
    QString ffmpegParameter = "";
    if(filePath.endsWith(".avi", Qt::CaseInsensitive))
    {ffmpegParameter = " -vcodec msmpeg4 ";}
    if(filePath.endsWith(".mov", Qt::CaseInsensitive))
    {ffmpegParameter = "";}
    if(filePath.endsWith(".mp4", Qt::CaseInsensitive))
    {ffmpegParameter = "";}

    qDebug() << "-------VIDEO------";
    // --------- Export all the temporary frames ----------
    QDir::temp().mkdir("pencil");
    QString tempPath = QDir::temp().absolutePath()+"/pencil/";
    QProgressDialog progress("Exporting movie...", "Abort", 0, 100, NULL);
    progress.setWindowModality(Qt::WindowModal);
    progress.show();

    QDir dir2(filePath);
    if (QFile::exists(filePath) == true) { dir2.remove(filePath); }

    const char* format = "png";

    ExportFrames1Parameters par;

    par.frameStart = startFrame;
    par.frameEnd = endFrame;
    par.view = view;
    par.currentLayer = currentLayer;
    par.exportSize = exportSize;
    par.filePath = tempPath + "tmp";
    par.format = format;
    par.quality = 100;
    par.background = true;
    par.antialiasing = true;
    par.progress = &progress;
    par.progressMax = 50;
    par.fps = fps;
    par.exportFps = exportFps;

    exportFrames1( par );

    // --------- Quicktime assemble call ----------
    QDir sampledir;
    qDebug() << "testmic:" << sampledir.filePath(filePath);

    QProcess ffmpeg;

    qDebug() << "Trying to export VIDEO";
    quint32 audioDataSize = 44100*2*2*(endFrame-1)/fps;
    qint16* audioData =(qint16*) malloc(audioDataSize);
    for (uint i = 0; i < audioDataSize/2; i++ ) audioData[i] = 0;
    quint16 header1[22];
    bool audioDataValid = false;
    for(int i = 0; i < this->getLayerCount() ; i++)
    {
        Layer* layer = this->getLayer(i);
        if(layer->type() == Layer::SOUND)
        {
            auto pSoundLayer = static_cast< LayerSound* >( layer );
            pSoundLayer->foreachKeyFrame( [&] ( KeyFrame* key )
            {
                int l = 0; // FIXME: export sound
                // convert audio file: 44100Hz sampling rate, stereo, signed 16 bit little endian
                // supported audio file types: wav, mp3, ogg... ( all file types supported by ffmpeg )
                qDebug() << "ffmpeg -i \"" + ((LayerSound*)layer)->getSoundFilepathAt(l) + "\" -ar 44100 -acodec pcm_s16le -ac 2 -y \"" + tempPath + "tmpaudio0.wav\"";
                ffmpeg.start("ffmpeg -i \"" + ((LayerSound*)layer)->getSoundFilepathAt(l) + "\" -ar 44100 -acodec pcm_s16le -ac 2 -y \"" + tempPath + "tmpaudio0.wav\"");
                if (ffmpeg.waitForStarted() == true)
                {
                    if (ffmpeg.waitForFinished() == true)
                    {
                        QByteArray sErr = ffmpeg.readAllStandardError();
                        if (sErr == "")
                        {
                            qDebug() << "ERROR: Could not execute FFmpeg.";
                        }
                        else
                        {
                            qDebug() << "stdout: " << ffmpeg.readAllStandardOutput();
                            qDebug() << "stderr: " << sErr;
                            qDebug() << "AUDIO conversion done. ( file: " << ((LayerSound*)layer)->getSoundFilepathAt(l) << ")";
                        }
                    }
                    else
                    {
                        qDebug() << "ERROR: FFmpeg did not finish executing.";
                    }
                }
                else
                {
                    qDebug() << "ERROR: Could not execute FFmpeg.";
                }
                int frame = key->pos() - 1;
                float fframe = (float)frame/(float)fps;
                QFile file(tempPath+"tmpaudio0.wav");
                qDebug() << "audio file " + tempPath+"tmpaudio0.wav";
                file.open(QIODevice::ReadOnly);
                file.read((char*)header1,sizeof(header1));
                quint32 audioSize = header1[21];
                audioSize = audioSize * 65536 + header1[20];
                qDebug() << "audio len " << audioSize;
                // before calling malloc should check: audioSize < max credible value
                qint16* data = (qint16*) malloc(audioSize);
                file.read((char*)data,audioSize);
                audioDataValid = true;
                int delta = fframe*44100*2;
                qDebug() << "audio delta " << delta;
                int indexMax = MIN(audioSize/2,audioDataSize/2-delta);
                // audio files 'mixing': 'higher' sound layers overwrite 'lower' sound layers
                for (int index = 0; index < indexMax; index++)
                {
                    audioData[index+delta] = safeSum(audioData[index+delta],data[index]);
                }
                free(data);
                file.close();
            } );
        }
    }
    if ( audioDataValid )
    {
        // save mixed audio file ( will be used as audio stream )
        QFile file(tempPath+"tmpaudio.wav");
        file.open(QIODevice::WriteOnly);
        header1[20] = audioDataSize % 65536;
        header1[21] = audioDataSize / 65536;
        file.write((char*)header1,sizeof(header1));
        file.write((char*)audioData,audioDataSize);
        file.close();
    }


    // video input:  frame sequence ( -i tmp%03d.png )
    //               frame rate     ( -r fps )
    // audio input:                 ( -i tmpaudio.wav )
    // movie output:                ( filePath )
    //               frame rate     ( -r 25 )
    if ( audioDataValid )
    {
        qDebug() << "ffmpeg -r " + QString::number(exportFps) + " -i " + tempPath + "tmp%4d.png -i " + tempPath + "tmpaudio.wav -r " + QString::number(exportFps) + " -y " + ffmpegParameter + "\"" + filePath + "\"";
        ffmpeg.start("ffmpeg -r " + QString::number(exportFps) + " -i " + tempPath + "tmp%4d.png -i " + tempPath + "tmpaudio.wav -r " + QString::number(exportFps) + " -y " + ffmpegParameter + "\"" + filePath + "\"");
    }
    else
    {
        qDebug() << "ffmpeg -r " + QString::number(exportFps) + " -i " + tempPath + "tmp%4d.png -r " + QString::number(exportFps) + " -y " + ffmpegParameter + "\"" + filePath + "\"";
        ffmpeg.start("ffmpeg -r " + QString::number(exportFps) + " -i " + tempPath + "tmp%4d.png -r " + QString::number(exportFps) + " -y " + ffmpegParameter + "\"" + filePath + "\"");
    }
    if (ffmpeg.waitForStarted() == true)
    {
        if (ffmpeg.waitForFinished() == true)
        {
            QByteArray sErr = ffmpeg.readAllStandardError();
            if (sErr == "")
            {
                qDebug() << "ERROR: Could not execute FFmpeg.";
            }
            else
            {
                qDebug() << "stdout: " << ffmpeg.readAllStandardOutput();
                qDebug() << "stderr: " << sErr;

                qDebug() << "dbg:" << QDir::current().currentPath() +"/plugins/";
                qDebug() << ":" << tempPath + "tmp%03d.png";
                qDebug() << ":\"" + filePath + "\"";
                qDebug() << "VIDEO export done.";
            }
        }
        else
        {
            qDebug() << "ERROR: FFmpeg did not finish executing.";
        }
    }
    else
    {
        qDebug() << "Please install FFMPEG: sudo apt-get install ffmpeg";
    }

    progress.setValue(100);
    free(audioData);


    // --------- Clean up temp directory ---------
    QDir dir(tempPath);
    QStringList filtername("*.*");
    QStringList entries = dir.entryList(filtername,QDir::Files,QDir::Type);
    for(int i=0; i<entries.size(); i++)
        dir.remove(entries[i]);
    qDebug() << "-----";

    return true;
}