|
13 | 13 | is_overlapping_otio_ranges, |
14 | 14 | frames_to_timecode |
15 | 15 | ) |
16 | | -from ayon_core.pipeline.context_tools import get_current_project_name |
| 16 | +from ayon_core.pipeline.context_tools import ( |
| 17 | + get_current_project_name, |
| 18 | + get_current_task_entity |
| 19 | +) |
17 | 20 | from ayon_core.pipeline.tempdir import create_custom_tempdir |
18 | 21 |
|
19 | 22 | from . import constants |
@@ -1226,3 +1229,162 @@ def export_timeline_otio_native(timeline, filepath): |
1226 | 1229 | log.error(f"Failed to export timeline otio: {e}") |
1227 | 1230 | return False |
1228 | 1231 | return True |
| 1232 | + |
| 1233 | + |
| 1234 | +def detect_project_fps_mismatch(task_entity=None): |
| 1235 | + """ Detect potential fps mismatch between project settings |
| 1236 | + and task entity. Return any mismatch as a information |
| 1237 | + string to be displayed to the user. |
| 1238 | + """ |
| 1239 | + task_entity = task_entity or get_current_task_entity() |
| 1240 | + attributes = task_entity["attrib"] |
| 1241 | + task_fps = attributes["fps"] |
| 1242 | + |
| 1243 | + resolve_project = get_current_resolve_project() |
| 1244 | + resolve_fps = resolve_project.GetSetting("timelineFrameRate") |
| 1245 | + |
| 1246 | + if task_fps != resolve_fps: |
| 1247 | + return ( |
| 1248 | + f"Project current fps is {resolve_fps} " |
| 1249 | + f"while task fps is {task_fps}." |
| 1250 | + ) |
| 1251 | + |
| 1252 | + return None |
| 1253 | + |
| 1254 | + |
| 1255 | +def detect_project_resolution_mismatch(task_entity=None): |
| 1256 | + """ Detect potential resolution mismatch between project settings |
| 1257 | + and task entity. Return any mismatch as a information |
| 1258 | + string to be displayed to the user. |
| 1259 | + """ |
| 1260 | + task_entity = task_entity or get_current_task_entity() |
| 1261 | + attributes = task_entity["attrib"] |
| 1262 | + width = attributes["resolutionWidth"] |
| 1263 | + height = attributes["resolutionHeight"] |
| 1264 | + |
| 1265 | + resolve_project = get_current_resolve_project() |
| 1266 | + resolve_width = resolve_project.GetSetting("timelineResolutionWidth") |
| 1267 | + resolve_height = resolve_project.GetSetting("timelineResolutionHeight") |
| 1268 | + |
| 1269 | + if (str(width), str(height)) != (resolve_width, resolve_height): |
| 1270 | + return ( |
| 1271 | + f"Project current resolution is {resolve_width}x{resolve_height} " |
| 1272 | + f"while task resolution is {width}x{height}." |
| 1273 | + ) |
| 1274 | + |
| 1275 | + return None |
| 1276 | + |
| 1277 | + |
| 1278 | +def set_project_fps(task_entity=None): |
| 1279 | + """ Attempt to set project frame rate from AYON current task. |
| 1280 | + This might not be possible if a timeline already exists within the project. |
| 1281 | + Return a error string if any issue so it can be displayed to the user. |
| 1282 | + """ |
| 1283 | + task_entity = task_entity or get_current_task_entity() |
| 1284 | + attributes = task_entity["attrib"] |
| 1285 | + |
| 1286 | + # Set project frame rate and resolution |
| 1287 | + resolve_project = get_current_resolve_project() |
| 1288 | + project_fps = attributes["fps"] |
| 1289 | + |
| 1290 | + SUPPORTED_FPS = { |
| 1291 | + 16.0: "16", |
| 1292 | + 18.0: "18", |
| 1293 | + 23.976: "23.976", |
| 1294 | + 24.0: "24", |
| 1295 | + 25.0: "25", |
| 1296 | + 29.97: "29.97", |
| 1297 | + 30.0: "30", |
| 1298 | + 47.952: "47.952", |
| 1299 | + 48.0: "48", |
| 1300 | + 50.0: "50" |
| 1301 | + } |
| 1302 | + |
| 1303 | + if float(project_fps) in SUPPORTED_FPS: |
| 1304 | + if not resolve_project.SetSetting( |
| 1305 | + "timelineFrameRate", |
| 1306 | + SUPPORTED_FPS[float(project_fps)] |
| 1307 | + ): |
| 1308 | + # Resolve does not allow to edit timeline fps |
| 1309 | + # project settings once a timeline has been created. |
| 1310 | + return ( |
| 1311 | + "Cannot override Project fps from AYON." |
| 1312 | + " This could be because a timeline already exists." |
| 1313 | + ) |
| 1314 | + |
| 1315 | + return None |
| 1316 | + |
| 1317 | + else: |
| 1318 | + return ( |
| 1319 | + "Fps set in AYON project is not supported by Resolve" |
| 1320 | + f" attempt to set {project_fps}," |
| 1321 | + f" supported are {tuple(SUPPORTED_FPS.keys())}." |
| 1322 | + ) |
| 1323 | + |
| 1324 | + |
| 1325 | +def set_project_resolution(task_entity=None): |
| 1326 | + """ Attempt to set project resolution from AYON current task. |
| 1327 | + Return a error string if any issue so it can be displayed to the user. |
| 1328 | + """ |
| 1329 | + task_entity = task_entity or get_current_task_entity() |
| 1330 | + attributes = task_entity["attrib"] |
| 1331 | + |
| 1332 | + resolve_project = get_current_resolve_project() |
| 1333 | + width = attributes["resolutionWidth"] |
| 1334 | + height = attributes["resolutionHeight"] |
| 1335 | + |
| 1336 | + resolution_params = { |
| 1337 | + "timelineResolutionHeight": height, |
| 1338 | + "timelineResolutionWidth": width, |
| 1339 | + } |
| 1340 | + |
| 1341 | + # In order to set vertical resolution in resolve, |
| 1342 | + # the "Use vertical resolution" option need to be enabled. |
| 1343 | + # This is not exposed from the Python API. |
| 1344 | + if height > width: |
| 1345 | + return ( |
| 1346 | + "Cannot override Project resolution from AYON." |
| 1347 | + f" Vertical resolution {width}x{height}" |
| 1348 | + " is unsupported from the API." |
| 1349 | + ) |
| 1350 | + |
| 1351 | + for resolve_param, value in resolution_params.items(): |
| 1352 | + if not resolve_project.SetSetting( |
| 1353 | + resolve_param, |
| 1354 | + str(int(value)) |
| 1355 | + ): |
| 1356 | + return ( |
| 1357 | + "Cannot override Project resolution from AYON." |
| 1358 | + f" trying to set {resolve_param} = {value}" |
| 1359 | + ) |
| 1360 | + |
| 1361 | + SUPPORTED_PIXEL_ASPECTS = { |
| 1362 | + 1.0: "Square", |
| 1363 | + 16/9: "16:9 anamorphic", |
| 1364 | + 4/3: "4:3 standard definition", |
| 1365 | + 2.0: "Cinemascope", |
| 1366 | + } |
| 1367 | + pixel_aspect_ratio = round(attributes["pixelAspect"], 2) |
| 1368 | + |
| 1369 | + for supported_pa in SUPPORTED_PIXEL_ASPECTS: |
| 1370 | + if round(supported_pa, 2) != pixel_aspect_ratio: |
| 1371 | + continue |
| 1372 | + |
| 1373 | + if not resolve_project.SetSetting( |
| 1374 | + "timelinePixelAspectRatio", |
| 1375 | + SUPPORTED_PIXEL_ASPECTS[supported_pa] |
| 1376 | + ): |
| 1377 | + return ( |
| 1378 | + "Cannot override Project pixel aspect ratio from AYON." |
| 1379 | + " trying to set timelinePixelAspectRatio = " |
| 1380 | + f"{SUPPORTED_PIXEL_ASPECTS[supported_pa]}" |
| 1381 | + ) |
| 1382 | + |
| 1383 | + return None |
| 1384 | + |
| 1385 | + else: |
| 1386 | + return ( |
| 1387 | + "Pixel Aspect Ratio set in AYON project is not supported" |
| 1388 | + f" by Resolve, attempt to set {pixel_aspect_ratio}," |
| 1389 | + f" supported are {tuple(SUPPORTED_PIXEL_ASPECTS.keys())}." |
| 1390 | + ) |
0 commit comments