Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Blackmagic ATEM ISO DaVinci Resolve .drp files #1185

Closed
gilou opened this issue Jan 3, 2022 · 16 comments
Closed

Support for Blackmagic ATEM ISO DaVinci Resolve .drp files #1185

gilou opened this issue Jan 3, 2022 · 16 comments

Comments

@gilou
Copy link

gilou commented Jan 3, 2022

Feature Request

Add an adapter to ingest the .drp / JSON file generated by blackmagic atem iso to be consumed by DaVinci Resolve as a project / timeline.

Description

The file is a simple .JSON timeline to be consumed by Da Vinci as a project. Da Vinci can export to multiple format, but my goal is to get that ingested directly to be able to export as KDEnlive project. Da Vinci => AAF => OTIO => .kdenlive works, I assume it'll work, and won't be too annoying.

Context

The Blackmagic ATEM ISO generates a .drp file that represents the timeline of the live video from the switcher when recorded, linking the media files in HD, allowing to rework the scene switching, or render the video using the HD sources rather than at the stream output for the live. The .drp / JSON file is a simple timeline, indicating timing of camera switches.

I intend on working on it as time allows... I have a few questions about the project management (I understand I need to sign the CLA)... I'm not sure the .drp file will be actual Da Vinci Resolve file, as the blackmagic atem might only be using a subset of it, should we mention that, and what the naming scheme should be for the adapter ? davinci-atem ? or just davinci / .drp, and we'll let contributors improve it if more needs to be done than what the ATEM outputs (I do not need more than that, and probably won't look much further).

I also wonder what the policy is regarding the default behaviours regarding scenes and stacking and all. My first goal is to get a single stack with clips of the n cams as they are put live, so as to get a single video track in KDEnlive (or OTIO, anyway). Then I might allow for options to reset the timecode (it uses the actual time of recording by default), to add one track / camera, but with gapped/padded clips for each, to make it easier to work on multicam in KDEnlive. Or to add effects to mute the un-selected channels...

Guidance would be appreciated, I'm just discovering this project, and I like it a lot. I figured it was worth the effort of going that route instead of doing a quick and dirty .drp => .kdenlive, and the fact that the adapter for .kdenlive kinda already works makes me feel it's the right choice ;)

I also think that given how otio works, it won't be too hard to achieve the first drafts of that adapter!

Cheers.
Gilou

@jminor
Copy link
Collaborator

jminor commented Jan 3, 2022

Hi @gilou, Welcome to the OTIO community :)

Take a look at this plugin which may be useful to you: https://github.com/eric-with-a-c/resolve-otio

Since Resolve already has support for a variety of import/export formats, I suggest experimenting with the FCP 7 XML and AAF formats which already have OTIO adapters. In particular we have found that the FCP 7 XML format tends to be well supported & easier to work with than some of the others. Even if those don't end up being your final solution, you can use them to compare functionality to the adapter you are proposing. If you find that any of those work well, then we would gladly accept some documentation or tutorial on how to import/export via Resolve.

Also, it might be worth reaching out to the Resolve developers. We know that some other members of our OTIO community have asked them to add native OTIO support & more voices could help that effort.

@apetrynet
Copy link
Contributor

Hi @gilou!
If you decide to write an adapter you might also want to look into using this template repo as a starting point. There's a suggested naming convention in the README.
Feedback on using the template is welcome.

@gilou
Copy link
Author

gilou commented Jan 3, 2022

Since Resolve already has support for a variety of import/export formats, I suggest experimenting with the FCP 7 XML and AAF formats which already have OTIO adapters. In particular we have found that the FCP 7 XML format tends to be well supported & easier to work with than some of the others. Even if those don't end up being your final solution, you can use them to compare functionality to the adapter you are proposing. If you find that any of those work well, then we would gladly accept some documentation or tutorial on how to import/export via Resolve.

The way I did it and had the most success was exporting as AAF (I tried random FCP XML versions, maybe not 7, but KDEnlive didn't like the output so much).. But my goal here is to avoid Resolve at all, as the blackmagic atem provides the file, but Resolve is quite painful to use on Linux without a properly supported graphic card and all. Also, I really want to avoid it ;)

Thanks for the otio resolve plugin, that's a nice starting point to undestand the way resolve "sees" all that, yet the .drp file doesn't look too complicated anyway.

Here's what it looks like:

{"version":1,"masterTimecode":"20:58:44:03","videoMode":"1080p25","sources":[{"name":"Black","type":"Color","color":{"h":0.0,"s":0.0,"l":0.0},"_index_":0},{"name":"Camera 1","type":"Video","volume":"ATEM","projectPath":"Javoue_Selen 3","file":"Video ISO Files/Javoue_Selen CAM 1.mp4","startTimecode":"20:58:44:03","_index_":1},{"name":"Camera 2","type":"Video","volume":"ATEM","projectPath":"Javoue_Selen 3","file":"Video ISO Files/Javoue_Selen CAM 2.mp4","startTimecode":"20:58:44:03","_index_":2},{"name":"Camera 3","type":"Video","volume":"ATEM","projectPath":"Javoue_Selen 3","file":"Video ISO Files/Javoue_Selen CAM 3.mp4","startTimecode":"20:58:44:03","_index_":3},{"name":"Camera 4","type":"Video","volume":"ATEM","projectPath":"Javoue_Selen 3","file":"Video ISO Files/Javoue_Selen CAM 4.mp4","startTimecode":"20:58:44:03","_index_":4},{"name":"Color Bars","type":"ColorBars","_index_":5},{"name":"Color 1","type":"Color","color":{"h":0.0,"s":0.0,"l":1.0},"_index_":6},{"name":"Color 2","type":"Color","color":{"h":0.07502083912197832,"s":1.0,"l":0.5},"_index_":7},{"name":"Media Player 1","type":"Still","volume":"ATEM","projectPath":"Javoue_Selen 3","startTimecode":"00:00:00:00","_index_":8}],"mixEffectBlocks":[{"onAir":true,"source":1,"transitionActive":false,"transitionWipeParameters":{"pattern":"DiamondIris","symmetry":0.5,"xOffset":0.5,"yOffset":0.5,"reverse":false,"softness":0.83,"borderWidth":0.0,"borderSource":6},"transitionDVEParameters":{"style":"PushRight","reverse":false,"fillSource":8,"enableKey":true,"keySource":0,"shaped":true,"clip":0.5,"gain":0.7,"invertKey":false},"fadeToBlack":"Inactive","ftbSource":0,"upstreamKeys":[{"keyType":"Luma","onAir":false,"isTied":false,"fillSource":8,"keySource":0,"isFlyKey":false,"isFlying":false,"xSizePercent":0.2,"ySizePercent":0.2,"xPosPercent":12.5,"yPosPercent":7.0,"_index_":0}],"_index_":0}],"downstreamKeys":[{"onAir":false,"isTied":false,"fillSource":8,"keySource":0,"faderState":"Idle","_index_":0}],"recordingId":"00d1320b"}
{"masterTimecode":"21:01:19:14","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:02:08:12","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:03:24:08","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:03:24:24","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:03:38:00","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:03:44:09","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:04:35:19","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:05:09:19","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:05:38:05","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:06:01:05","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:08:22:17","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:09:41:00","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:10:38:06","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:10:47:03","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:11:09:24","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:11:12:02","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:11:13:12","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:11:18:09","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:12:46:24","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:12:51:00","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:12:52:09","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:13:00:14","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:13:01:20","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:13:50:20","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:13:52:00","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:14:03:22","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:14:22:08","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:15:42:21","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:16:02:01","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:16:07:14","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:16:09:24","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:17:24:18","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:17:25:11","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:17:38:13","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:17:39:05","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:19:57:23","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:20:56:09","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:22:53:03","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:23:43:23","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:24:16:07","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:28:02:18","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:28:11:21","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:29:54:14","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:29:58:04","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:31:05:07","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:31:06:14","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:31:09:00","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:31:18:06","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:31:21:16","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:31:22:16","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:31:24:02","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:31:38:14","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:34:54:05","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:34:56:01","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:36:20:01","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:36:25:00","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:37:30:01","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:37:34:17","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:42:46:13","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:45:10:01","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:45:41:14","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:51:48:05","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:51:49:05","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:55:18:03","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"21:59:47:13","mixEffectBlocks":[{"source":3,"_index_":0}]}
{"masterTimecode":"21:59:48:21","mixEffectBlocks":[{"source":2,"_index_":0}]}
{"masterTimecode":"21:59:49:11","mixEffectBlocks":[{"source":1,"_index_":0}]}
{"masterTimecode":"22:00:30:03","mixEffectBlocks":[{"onAir":false,"_index_":0}]}

@gilou
Copy link
Author

gilou commented Jan 3, 2022

If you decide to write an adapter you might also want to look into using this template repo as a starting point. There's a suggested naming convention in the README.
Feedback on using the template is welcome.

Perfect, somehow I didn't see the naming part in the template. That should get me nicely started. I'm assuming otio-drp-adapter might be good, assuming it doesn't matter if I tackle the whole .drp "spec" (I assume there is one) or not.. or maybe otio-blackmagicdrp-adapter... Will ponder haha, that's not the most important part, but let's start with a nice name..

Also the template and example is nice. as this format is already in JSON, though I'll have to translate switch events to clips, but that sounds easy enough.

Thanks a lot for the input!

@gilou
Copy link
Author

gilou commented Jan 11, 2022

And, work has started on my side, https://github.com/gilou/otio-drp-adapter is live, and already can eat a simple .drp file (and have it output using the .kdenlive format, which is my goal). I'll work a bit more on getting the ingestion work, then I guess I can start making it better or add features there..

@gilou
Copy link
Author

gilou commented Jan 11, 2022

And I realized there already was a otio.opentime.from_timecode(tc, rate) by tweaking my IDE… shame.. I'll see how we can document that, as it's obviously helpful to know about it beforehand ;)

I think the template repos might be over-engineering for what I had in mind, I'd say a simple drp.py file would have worked, but at least I'll be able to make some feedback around it. And at least it can nicely be packaged separately, we'll see if that helps, especially for inclusion in say, KDEnlive…

@apetrynet
Copy link
Contributor

I was about to mention the otio.opentime methods earlier, but it looked like you had a valid reason for creating your own time code class and I didn't want to step on any toes :)

Thanks for feedback on the template. I can understand it feels a bit over-engineered for a simple adapter. It's designed to be an entry point for all the plugin types OTIO supports (adapters, hooks, schemadefs and medialinkers) and hopefully eased the process of getting the adapter registered properly.

Looks like you did a nice job customizing it to your needs and cleaning out all the redundant files and information.
Did you find the process of cleaning out the repo difficult without breaking anything?

@gilou
Copy link
Author

gilou commented Jan 11, 2022

Looks like you did a nice job customizing it to your needs and cleaning out all the redundant files and information. Did you find the process of cleaning out the repo difficult without breaking anything?

It's quite straight forward, I'd say I had a harder time dealing with the tests, and pypi settings (that I don't use for now), but that's more because I'm not familiar with all aspects and how it fits in with OTIO (manifest, blah)... I blindly kept the CI stuff, which seems happy, and is quite welcome for most:

  • it made me avoid doing Python3-only compatibility, and had me set up a py2 venv.. Not sure that's a good point, but at least your platform LTS thingy should enjoy it :P
  • it helped making sure my test was actually covering my code...

Maybe we could use something like cookiecutter or any templating, with the risk of making it a bit harder to clone, it would avoid all the renaming / search-replace'ing upon creation ;)

@gilou
Copy link
Author

gilou commented Jan 11, 2022

Also question... Since I'm quite wary of this being used by SaaS services without much contribution / attribution, would an AGPL license make sense, and be compatible with the rest of OTIO, without hindering proper distribution once this is worth including (if .. :P) ?

I didn't think much of the proposed choice (Apache/MIT), but this crossed my mind.

@meshula
Copy link
Collaborator

meshula commented Jan 11, 2022

With regards to the license, I'd just want to point out that in the US, at least, the AGPL is incompatible with many studio environments, so you'd run the risk of users hesitating to use the plug in, under some circumstances. It's also incompatible with the Apache license we use in OTIO, which means it wouldn't be incorporated in the OTIO distribution itself due to that incompatibility.

On the other hand, if that's the native license of the app where the plug in is being used, it would make sense to adopt the license that is most compatible license with the hosting application.

If you are hosting the project independently, you're welcome to use whatever license you like of course!

We are considering more of an ecosystem approach moving forward; in other words, we'd host a page of resources pointing to plug ins, rather than every plugin needing to be in the OTIO repo subject to our review and so on.

That would put the power of maintaining plugins with the people who understand them best, which does sound like a win.

@gilou
Copy link
Author

gilou commented Jan 12, 2022

And the adapter is live @ https://pypi.org/project/otio-drp-adapter/ !

Thanks for the help, let's see if that one is of any interest, and if it thrives. I mentioned it on BMD forum there: https://forum.blackmagicdesign.com/viewtopic.php?f=4&t=153644

As for the license, I'll just let it as Apache to avoid any issue, and I think it's good too have them in separate repos / responsability, it just makes it a bit harder to get a proper distribution scheme. I'm guessing there could be a OTIO label @ pypi in addition to the dependency...

Any feedback on the adapter "as is" is welcome, and I'm curious about how useful it can be to others… The intersection between users of Blackmagic ATEM ISO users and KDEnlive (well, in fact, any other NLE which is not DaVinci :P) might be small enough for this to get un-noticed, but we'll see!

@JeanChristopheMorinPerso
Copy link
Member

JeanChristopheMorinPerso commented Jan 12, 2022

I'm guessing there could be a OTIO label @ pypi in addition to the dependency...

If you are talking about something similar to Framework :: OTIO, yes it could be possible to request a new one just for OTIO, but it would require 10 or more packages using it at least, and a the classifier would need to be "notable". To quote members of PyPA:

Because removing classifiers is very difficult, and the longer the classifier list gets the harder it is to browse, the bar to add new ones is relatively high. Currently, PyPI moderators primarily examine two guidelines for Framework classifiers:

  • New Framework classifiers should be created if they are "notable" and
  • They will be of immediate use to existing projects (in other words, no creating classifiers simply in anticipation of future uses)

We understand that "notability" is subjective and we'd appreciate help judging that.

(cf pypa/trove-classifiers#20 (comment))

Note that we cannot randomly add new trove classifiers to packages that we upload to PyPI. The list of valid classifiers can be seen at https://pypi.org/classifiers/. If you upload a package version that contains an invalid classifier, PyPI will reject the upload.

@gilou
Copy link
Author

gilou commented Jan 12, 2022

Ah, indeed.. well, simplest is a list or a script to install external adapters, or we could do something like otio-core and have a distribution package OpenTimelineIO that includes all the "official" plugins (either through dependency, or manual install), similar to how ansible does it…I guess this would fit in an issue of its own, and I don't feel too competent and knowlegeable to actually imagine a clean solution here ;)

@apetrynet
Copy link
Contributor

Congratulations with your release!
Make sure to add your adapter to the list in the wiki

@gilou
Copy link
Author

gilou commented Jan 12, 2022

Congratulations with your release! Make sure to add your adapter to the list in the wiki

Done!

@gilou
Copy link
Author

gilou commented Jan 17, 2022

Well, I'm happy with the result with .drp files, and KDEnlive will support read- (and write-)only adapters soon, there are things to improve on that adapter, but it works, so I'll close that issue. I'll follow whatever discussions may happen about the "future" of plugins, and how they're distributed or not with OTIO…

@gilou gilou closed this as completed Jan 17, 2022
@jminor jminor added this to the Public Beta 15 milestone May 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants