File indexing completed on 2024-05-12 16:23:36

0001 /***************************************************************************
0002  *   Copyright (C) 2005-2014 by Linuxstopmotion contributors;              *
0003  *   see the AUTHORS file for details.                                     *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 
0021 #include "videofactory.h"
0022 
0023 #include "src/domain/animation/animationimpl.h"
0024 #include "src/technical/util.h"
0025 #include "src/technical/video/videoencoder.h"
0026 #include "src/domain/filenamevisitor.h"
0027 #include "src/foundation/logger.h"
0028 #include "src/application/externalcommandwithtemporarydirectory.h"
0029 
0030 #include <unistd.h>
0031 #include <cstddef>
0032 #include <cstring>
0033 #include <string>
0034 #include <sstream>
0035 #include <iomanip>
0036 #include <memory>
0037 
0038 #include <QString>
0039 
0040 using namespace std;
0041 
0042 VideoFactory::VideoFactory(const AnimationImpl *animation)
0043         : anim(animation) {
0044 }
0045 
0046 
0047 VideoFactory::~VideoFactory() {
0048 }
0049 
0050 class FileCopier : public FileNameVisitor {
0051     int index;
0052     const char* dir;
0053 public:
0054     FileCopier(const char* dirPath) : index(0), dir(dirPath) {
0055     }
0056     ~FileCopier() {
0057     }
0058     void visitImage(const char* p) {
0059         std::ostringstream ss;
0060         ss << dir << "/" << std::setw(6) << std::setfill('0') << index;
0061         std::string path = ss.str();
0062         const char* ext = strrchr(p, '.');
0063         if (ext)
0064             path.append(ext);
0065         Util::linkOrCopyFile(path.c_str(), p);
0066         ++index;
0067     }
0068     void visitSound(const char*) {
0069     }
0070 };
0071 
0072 bool replaceText(string& text, const char* searchFor, const char* replaceWith) {
0073     int index = text.find(searchFor);
0074     if (index < 0)
0075         return false;
0076     int replaceLength = strlen(replaceWith);
0077     while (0 <= index) {
0078         text.replace(index, strlen(searchFor), replaceWith);
0079         index = text.find(searchFor, index + replaceLength);
0080     }
0081     return true;
0082 }
0083 
0084 std::string integerToString(int n) {
0085     std::stringstream stream;
0086     stream << n;
0087     return stream.str();
0088 }
0089 
0090 const char* VideoFactory::createVideoFile(VideoEncoder *encoder,
0091         int playbackSpeed) {
0092     std::string startCommand = encoder->getStartCommand();
0093     std::unique_ptr<ExternalCommandWithTemporaryDirectory> ec(
0094             new ExternalCommandWithTemporaryDirectory());
0095     const char* tmpDir = ec->getTemporaryDirectoryPath();
0096     if ( !startCommand.empty() ) {
0097         replaceText(startCommand, "$IMAGEPATH", tmpDir);
0098         if (!replaceText(startCommand, "$VIDEOFILE", encoder->getOutputFile())) {
0099             return NULL;
0100         }
0101         replaceText(startCommand, "$opt", "");
0102         std::string playbackSpeedString = integerToString(playbackSpeed);
0103         replaceText(startCommand, "$FRAMERATE", playbackSpeedString.c_str());
0104         Logger::get().logDebug("Copying frames into temporary directory %s",
0105                 tmpDir);
0106         FileCopier copier(tmpDir);
0107         anim->accept(copier);
0108         sync();
0109         ec->show();
0110         ec->run(QString::fromLocal8Bit(startCommand.c_str()));
0111         ec.release();
0112         return encoder->getOutputFile();
0113     }
0114     return NULL;
0115 }