/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
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 3 of the License, or
(at your option) any later version.
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 .
***/
#include "otiodecoder.h"
#include
#include
#include
#include "node/block/clip/clip.h"
#include "node/block/gap/gap.h"
#include "project/item/sequence/sequence.h"
OLIVE_NAMESPACE_ENTER
OTIODecoder::OTIODecoder()
{
}
QString OTIODecoder::id()
{
return QStringLiteral("otio");
}
ItemPtr OTIODecoder::Probe(const QString& filename, const QAtomicInt* cancelled) const
{
if (filename.endsWith(QStringLiteral(".otio"), Qt::CaseInsensitive)) {
opentimelineio::v1_0::ErrorStatus es;
auto timeline = static_cast(opentimelineio::v1_0::SerializableObjectWithMetadata::from_json_file(filename.toStdString(), &es));
if (es != opentimelineio::v1_0::ErrorStatus::OK) {
return nullptr;
}
SequencePtr sequence = std::make_shared();
// FIXME: As far as I know, OTIO doesn't store video/audio parameters?
sequence->set_default_parameters();
sequence->set_name(QString::fromStdString(timeline->name()));
for (auto c : timeline->tracks()->children()) {
auto otio_track = static_cast(c.value);
// Create a new track
TrackOutput* track = nullptr;
// Determine what kind of track it is
if (otio_track->kind() == "Video") {
track = sequence->viewer_output()->track_list(Timeline::kTrackTypeVideo)->AddTrack();
} else if (otio_track->kind() == "Audio") {
track = sequence->viewer_output()->track_list(Timeline::kTrackTypeAudio)->AddTrack();
} else {
qWarning() << "Found unknown track type:" << otio_track->kind().c_str();
continue;
}
// Get clips from track
std::map clip_map = otio_track->range_of_all_children(&es);
if (es != opentimelineio::v1_0::ErrorStatus::OK) {
return nullptr;
}
for (auto it=clip_map.cbegin(); it!=clip_map.cend(); it++) {
Block* block = nullptr;
if (it->first->schema_name() == "Clip") {
block = new ClipBlock();
auto otio_clip = static_cast(it->first);
/*
if (otio_clip->media_reference()->schema_name() == "ExternalReference") {
QString footage_url = QString::fromStdString(static_cast(otio_clip->media_reference())->target_url());
ItemPtr footage = Decoder::ProbeMedia(footage_url, cancelled);
}
*/
} else if (it->first->schema_name() == "Gap") {
block = new GapBlock();
} else {
qWarning() << "Found unknown block type:" << it->first->schema_name().c_str();
}
block->SetLabel(QString::fromStdString(it->first->name()));
block->set_length_and_media_out(rational::fromDouble(it->second.duration().to_seconds()));
sequence->AddNode(block);
track->AppendBlock(block);
}
}
return sequence;
}
return nullptr;
}
OLIVE_NAMESPACE_EXIT