otio: added ability to export a whole project rather than a single sequence
This commit is contained in:
+3
-3
@@ -273,9 +273,9 @@ void Core::CreateNewProject()
|
||||
#ifdef USE_OTIO
|
||||
void Core::ExportActiveSequenceAsOTIO()
|
||||
{
|
||||
ViewerOutput* sequence = GetSequenceToExport();
|
||||
ProjectPtr project = GetActiveProject();
|
||||
|
||||
if (sequence) {
|
||||
if (project) {
|
||||
QString fn = QFileDialog::getSaveFileName(main_window_,
|
||||
tr("Export as OpenTimelineIO"),
|
||||
QString(),
|
||||
@@ -284,7 +284,7 @@ void Core::ExportActiveSequenceAsOTIO()
|
||||
if (!fn.isEmpty()) {
|
||||
fn = FileFunctions::EnsureFilenameExtension(fn, QStringLiteral("otio"));
|
||||
|
||||
ExportOTIOTask* task = new ExportOTIOTask(sequence, fn);
|
||||
ExportOTIOTask* task = new ExportOTIOTask(project, fn);
|
||||
TaskDialog* dialog = new TaskDialog(task, tr("Export Sequence"), main_window_);
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <opentimelineio/clip.h>
|
||||
#include <opentimelineio/externalReference.h>
|
||||
#include <opentimelineio/gap.h>
|
||||
#include <opentimelineio/serializableCollection.h>
|
||||
#include <opentimelineio/transition.h>
|
||||
|
||||
#include "node/block/transition/transition.h"
|
||||
@@ -30,29 +31,80 @@
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
ExportOTIOTask::ExportOTIOTask(ViewerOutput *sequence, const QString &filename) :
|
||||
sequence_(sequence),
|
||||
ExportOTIOTask::ExportOTIOTask(ProjectPtr project, const QString &filename) :
|
||||
project_(project),
|
||||
filename_(filename)
|
||||
{
|
||||
SetTitle(tr("Saving '%1' as OpenTimelineIO").arg(sequence_->media_name()));
|
||||
SetTitle(tr("Exporting project to OpenTimelineIO"));
|
||||
}
|
||||
|
||||
bool ExportOTIOTask::Run()
|
||||
{
|
||||
auto otio_timeline = new opentimelineio::v1_0::Timeline();
|
||||
QList<ItemPtr> sequences = project_->get_items_of_type(Item::kSequence);
|
||||
|
||||
opentimelineio::v1_0::ErrorStatus es;
|
||||
|
||||
if (!SerializeTrackList(sequence_->track_list(Timeline::kTrackTypeVideo), otio_timeline)
|
||||
|| !SerializeTrackList(sequence_->track_list(Timeline::kTrackTypeAudio), otio_timeline)) {
|
||||
if (sequences.isEmpty()) {
|
||||
SetError(tr("Project contains no sequences to export."));
|
||||
return false;
|
||||
}
|
||||
|
||||
otio_timeline->to_json_file(filename_.toStdString(), &es);
|
||||
std::vector<opentimelineio::v1_0::SerializableObject*> serialized;
|
||||
|
||||
foreach (ItemPtr item, sequences) {
|
||||
SequencePtr seq = std::static_pointer_cast<Sequence>(sequences.first());
|
||||
|
||||
auto otio_timeline = SerializeTimeline(seq);
|
||||
|
||||
if (otio_timeline) {
|
||||
// Append to list
|
||||
serialized.push_back(otio_timeline);
|
||||
} else {
|
||||
// Delete all existing timelines
|
||||
foreach (auto s, serialized) {
|
||||
s->possibly_delete();
|
||||
}
|
||||
|
||||
// Error out of function
|
||||
SetError(tr("Failed to serialize sequence \"%1\"").arg(seq->name()));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
opentimelineio::v1_0::ErrorStatus es;
|
||||
|
||||
if (serialized.size() == 1) {
|
||||
// Serialize timeline on its own
|
||||
auto t = serialized.front();
|
||||
t->to_json_file(filename_.toStdString(), &es);
|
||||
t->possibly_delete();
|
||||
} else {
|
||||
// Serialize all into a SerializableCollection
|
||||
auto collection = new opentimelineio::v1_0::SerializableCollection("Sequences", serialized);
|
||||
collection->to_json_file(filename_.toStdString(), &es);
|
||||
collection->possibly_delete();
|
||||
|
||||
// Delete all existing timelines
|
||||
foreach (auto s, serialized) {
|
||||
s->possibly_delete();
|
||||
}
|
||||
}
|
||||
|
||||
return (es == opentimelineio::v1_0::ErrorStatus::OK);
|
||||
}
|
||||
|
||||
opentimelineio::v1_0::Timeline *ExportOTIOTask::SerializeTimeline(SequencePtr sequence)
|
||||
{
|
||||
auto otio_timeline = new opentimelineio::v1_0::Timeline(sequence->name().toStdString());
|
||||
|
||||
if (!SerializeTrackList(sequence->viewer_output()->track_list(Timeline::kTrackTypeVideo), otio_timeline)
|
||||
|| !SerializeTrackList(sequence->viewer_output()->track_list(Timeline::kTrackTypeAudio), otio_timeline)) {
|
||||
otio_timeline->possibly_delete();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return otio_timeline;
|
||||
}
|
||||
|
||||
opentimelineio::v1_0::Track *ExportOTIOTask::SerializeTrack(TrackOutput *track)
|
||||
{
|
||||
auto otio_track = new opentimelineio::v1_0::Track();
|
||||
@@ -77,7 +129,7 @@ opentimelineio::v1_0::Track *ExportOTIOTask::SerializeTrack(TrackOutput *track)
|
||||
switch (block->type()) {
|
||||
case Block::kClip:
|
||||
{
|
||||
auto otio_clip = new opentimelineio::v1_0::Clip();
|
||||
auto otio_clip = new opentimelineio::v1_0::Clip(block->GetLabel().toStdString());
|
||||
|
||||
otio_clip->set_source_range(opentimelineio::v1_0::TimeRange(block->in().toRationalTime(),
|
||||
block->length().toRationalTime()));
|
||||
@@ -93,17 +145,15 @@ opentimelineio::v1_0::Track *ExportOTIOTask::SerializeTrack(TrackOutput *track)
|
||||
}
|
||||
case Block::kGap:
|
||||
{
|
||||
auto otio_gap = new opentimelineio::v1_0::Gap();
|
||||
|
||||
otio_gap->set_source_range(opentimelineio::v1_0::TimeRange(block->in().toRationalTime(),
|
||||
block->length().toRationalTime()));
|
||||
|
||||
otio_block = otio_gap;
|
||||
otio_block = new opentimelineio::v1_0::Gap(
|
||||
opentimelineio::v1_0::TimeRange(block->in().toRationalTime(), block->length().toRationalTime()),
|
||||
block->GetLabel().toStdString()
|
||||
);
|
||||
break;
|
||||
}
|
||||
case Block::kTransition:
|
||||
{
|
||||
auto otio_transition = new opentimelineio::v1_0::Transition();
|
||||
auto otio_transition = new opentimelineio::v1_0::Transition(block->GetLabel().toStdString());
|
||||
|
||||
TransitionBlock* our_transition = static_cast<TransitionBlock*>(block);
|
||||
|
||||
@@ -149,6 +199,7 @@ bool ExportOTIOTask::SerializeTrackList(TrackList *list, opentimelineio::v1_0::T
|
||||
otio_timeline->tracks()->append_child(otio_track, &es);
|
||||
|
||||
if (es != opentimelineio::v1_0::ErrorStatus::OK) {
|
||||
otio_track->possibly_delete();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <opentimelineio/timeline.h>
|
||||
#include <opentimelineio/track.h>
|
||||
|
||||
#include "project/item/sequence/sequence.h"
|
||||
#include "project/project.h"
|
||||
#include "task/task.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
@@ -33,17 +33,19 @@ class ExportOTIOTask : public Task
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportOTIOTask(ViewerOutput* sequence, const QString& filename);
|
||||
ExportOTIOTask(ProjectPtr project, const QString& filename);
|
||||
|
||||
protected:
|
||||
virtual bool Run() override;
|
||||
|
||||
private:
|
||||
opentimelineio::v1_0::Timeline* SerializeTimeline(SequencePtr sequence);
|
||||
|
||||
opentimelineio::v1_0::Track* SerializeTrack(TrackOutput* track);
|
||||
|
||||
bool SerializeTrackList(TrackList* list, opentimelineio::v1_0::Timeline *otio_timeline);
|
||||
|
||||
ViewerOutput* sequence_;
|
||||
ProjectPtr project_;
|
||||
|
||||
QString filename_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user