Commit fb82eabe authored by Vincent Pinon's avatar Vincent Pinon

Integrate OTIO convertions

parent 3d26bd55
Pipeline #14717 passed with stage
in 16 minutes and 40 seconds
......@@ -4,6 +4,8 @@
<Menu name="file" >
<Action name="dvd_wizard" />
<Action name="transcode_clip" />
<Action name="export_project" />
<Action name="import_project" />
</Menu>
<Menu name="edit" >
<Action name="paste_effects" />
......
......@@ -64,6 +64,7 @@
#include "transitions/transitionsrepository.hpp"
#include "utils/resourcewidget.h"
#include "utils/thememanager.h"
#include "utils/otioconvertions.h"
#include "profiles/profilerepository.hpp"
#include "widgets/progressbutton.h"
......@@ -428,6 +429,7 @@ void MainWindow::init()
new HideTitleBars(this);
m_extraFactory = new KXMLGUIClient(this);
buildDynamicActions();
m_otioConvertions.getOtioConverters();
// Create Effect Basket (dropdown list of favorites)
m_effectBasket = new EffectBasket(this);
......@@ -1291,6 +1293,15 @@ void MainWindow::setupActions()
addAction(QStringLiteral("dvd_wizard"), i18n("DVD Wizard"), this, SLOT(slotDvdWizard()), QIcon::fromTheme(QStringLiteral("media-optical")));
addAction(QStringLiteral("transcode_clip"), i18n("Transcode Clips"), this, SLOT(slotTranscodeClip()), QIcon::fromTheme(QStringLiteral("edit-copy")));
QAction *exportAction = new QAction(QIcon::fromTheme(QStringLiteral("document-export")), i18n("E&xport project"), this);
connect(exportAction, &QAction::triggered, &m_otioConvertions, &OtioConvertions::slotExportProject);
exportAction->setEnabled(false);
addAction(QStringLiteral("export_project"), exportAction);
QAction *importAction = new QAction(QIcon::fromTheme(QStringLiteral("document-import")), i18n("&Import project"), this);
connect(importAction, &QAction::triggered, &m_otioConvertions, &OtioConvertions::slotImportProject);
importAction->setEnabled(false);
addAction(QStringLiteral("import_project"), importAction);
addAction(QStringLiteral("archive_project"), i18n("Archive Project"), this, SLOT(slotArchiveProject()),
QIcon::fromTheme(QStringLiteral("document-save-all")));
addAction(QStringLiteral("switch_monitor"), i18n("Switch monitor"), this, SLOT(slotSwitchMonitors()), QIcon(), Qt::Key_T);
......
......@@ -44,6 +44,7 @@
#include "kdenlive_debug.h"
#include "kdenlivecore_export.h"
#include "statusbarmessagelabel.h"
#include "utils/otioconvertions.h"
class AssetPanel;
class AudioGraphSpectrum;
......@@ -153,6 +154,7 @@ private:
/** @brief Sets up all the actions and attaches them to the collection. */
void setupActions();
OtioConvertions m_otioConvertions;
KColorSchemeManager *m_colorschemes;
QDockWidget *m_projectBinDock;
......
......@@ -7,6 +7,7 @@ set(kdenlive_SRCS
utils/flowlayout.cpp
utils/freesound.cpp
utils/openclipart.cpp
utils/otioconvertions.cpp
utils/resourcewidget.cpp
utils/thememanager.cpp
utils/thumbnailcache.cpp
......
/*
* this file is part of Kdenlive, the Libre Video Editor by KDE
* Copyright 2019 Vincent Pinon <vpinon@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "otioconvertions.h"
#include "mainwindow.h"
#include "core.h"
#include "doc/kdenlivedoc.h"
#include "project/projectmanager.h"
#include <KMessageBox>
OtioConvertions::OtioConvertions()
{
}
void OtioConvertions::getOtioConverters()
{
connect(&m_otioProcess, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &OtioConvertions::slotGotOtioConverters);
m_otioProcess.start(QStringLiteral("python3"));
m_otioProcess.write(QStringLiteral(
"from opentimelineio import *\n"
"for a in plugins.ActiveManifest().adapters:\n"
" if a.has_feature('read') and a.has_feature('write'):\n"
" print('*.'+' *.'.join(a.suffixes), end=' ')"
).toUtf8());
m_otioProcess.closeWriteChannel();
}
void OtioConvertions::slotGotOtioConverters(int exitCode, QProcess::ExitStatus exitStatus)
{
m_otioProcess.disconnect();
if(exitStatus != QProcess::NormalExit || exitCode != 0) {
qInfo("OpenTimelineIO python module is not available");
return;
}
m_adapters = m_otioProcess.readAll();
if (!m_adapters.contains("kdenlive")) {
qInfo() << "Kdenlive not supported by OTIO: " << m_adapters;
return;
}
QAction *exportAction = pCore->window()->actionCollection()->action("export_project");
QAction *importAction = pCore->window()->actionCollection()->action("import_project");
exportAction->setEnabled(true);
importAction->setEnabled(true);
}
void OtioConvertions::slotExportProject()
{
auto exportFile = QFileDialog::getSaveFileName(
pCore->window(), i18n("Export Project"),
pCore->currentDoc()->projectDataFolder(),
i18n("OpenTimelineIO adapters (%1)", m_adapters));
if (exportFile.isNull()) {
return;
}
QByteArray xml = pCore->projectManager()->projectSceneList("").toUtf8();
if (xml.isNull()) {
KMessageBox::error(pCore->window(), i18n("Project file could not be saved for export."));
return;
}
m_otioTempFile.setFileTemplate(QStringLiteral("XXXXXX.kdenlive"));
if (!m_otioTempFile.open() || !(m_otioTempFile.write(xml) > 0)) {
pCore->displayMessage(i18n("Unable to write to temporary kdenlive file for export: %1",
m_otioTempFile.fileName()), ErrorMessage);
return;
}
connect(&m_otioProcess, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
this, &OtioConvertions::slotProjectExported);
m_otioProcess.start(QStringLiteral("otioconvert"), {"-i", m_otioTempFile.fileName(), "-o", exportFile});
}
void OtioConvertions::slotImportProject()
{
// Select foreign project to import
auto importFile = QFileDialog::getOpenFileName(
pCore->window(), i18n("Project to import"),
pCore->currentDoc()->projectDataFolder(),
i18n("OpenTimelineIO adapters (%1)", m_adapters));
if (importFile.isNull() || !QFile::exists(importFile)) {
return;
}
// Select converted project file
m_importedFile = QFileDialog::getSaveFileName(
pCore->window(), i18n("Imported Project"),
pCore->currentDoc()->projectDataFolder(),
i18n("Kdenlive project (*.kdenlive)"));
if (m_importedFile.isNull()) {
return;
}
// Start convertion process
connect(&m_otioProcess, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
this, &OtioConvertions::slotProjectImported);
m_otioProcess.start(QStringLiteral("otioconvert"), {"-i", importFile, "-o", m_importedFile});
}
void OtioConvertions::slotProjectExported(int exitCode, QProcess::ExitStatus exitStatus)
{
m_otioProcess.disconnect();
m_otioTempFile.remove();
if(exitStatus != QProcess::NormalExit || exitCode != 0) {
pCore->displayMessage(i18n("Project convertion failed"), ErrorMessage);
qWarning() << exitCode << exitStatus << QString(m_otioProcess.readAllStandardError());
return;
}
pCore->displayMessage(i18n("Project convertion complete"), InformationMessage);
}
void OtioConvertions::slotProjectImported(int exitCode, QProcess::ExitStatus exitStatus)
{
m_otioProcess.disconnect();
if(exitStatus != QProcess::NormalExit || exitCode != 0 || !QFile::exists(m_importedFile)) {
pCore->displayMessage(i18n("Project convertion failed"), ErrorMessage);
qWarning() << exitCode << exitStatus << QString(m_otioProcess.readAllStandardError());
return;
}
pCore->displayMessage(i18n("Project convertion complete"), InformationMessage);
// Verify current project can be closed
if (pCore->currentDoc()->isModified() &&
KMessageBox::warningContinueCancel(pCore->window(), i18n(
"The current project has not been saved\n"
"Do you want to load imported project abandoning latest changes?")
) != KMessageBox::Continue) {
return;
}
pCore->projectManager()->openFile(QUrl::fromLocalFile(m_importedFile));
}
/*
* this file is part of Kdenlive, the Libre Video Editor by KDE
* Copyright 2019 Vincent Pinon <vpinon@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OTIOCONVERTIONS_H
#define OTIOCONVERTIONS_H
#include <QObject>
#include <QProcess>
#include <QTemporaryFile>
class OtioConvertions: public QObject
{
Q_OBJECT
public:
OtioConvertions();
void getOtioConverters();
private:
QProcess m_otioProcess;
QString m_adapters;
QTemporaryFile m_otioTempFile;
QString m_importedFile;
public slots:
void slotExportProject();
void slotImportProject();
private slots:
void slotGotOtioConverters(int exitCode, QProcess::ExitStatus exitStatus);
void slotProjectExported(int exitCode, QProcess::ExitStatus exitStatus);
void slotProjectImported(int exitCode, QProcess::ExitStatus exitStatus);
};
#endif // OTIOCONVERTIONS_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment