tinyblast/tinyblast.py

161 lines
5.7 KiB
Python
Raw Normal View History

2024-09-13 12:22:04 -04:00
import maya.OpenMaya as om
import maya.OpenMayaMPx as ompx
import maya.OpenMayaUI as omui
2024-09-13 12:22:04 -04:00
import maya.cmds as cmds
import os
import subprocess
import sys
from shiboken6 import wrapInstance
from PySide6 import QtWidgets
playblast_job_id = None
2024-09-13 12:22:04 -04:00
def get_plugin_directory():
# Get the path of the currently loaded plugin
plugin_name = "tinyblast"
plugin_path = cmds.pluginInfo(plugin_name, query=True, path=True)
return os.path.dirname(plugin_path)
def custom_playblast(*args, **kwargs):
print("Running playblast...")
kwargs['format'] = 'avi'
kwargs['percent'] = 100
kwargs['quality'] = 100
kwargs['widthHeight'] = (1920, 1080)
result = cmds.playblast(*args, **kwargs)
2024-09-13 12:22:04 -04:00
print(f"{result}")
if result:
try:
ffmpeg_path = os.path.join(get_plugin_directory(), 'ffmpeg.exe')
print(f"ffmpeg path: {ffmpeg_path}")
if not os.path.exists(ffmpeg_path):
raise FileNotFoundError(f"FFmpeg binary not found at {ffmpeg_path}")
input_file = result # The file output by playblast
#output_directory = os.path.dirname(result) # Get the directory path
output_directory = os.path.dirname(cmds.file(query=True, sceneName=True))
input_filename = os.path.basename(result) # Get the filename with extension
# Change the extension to .mp4
output_filename = os.path.splitext(input_filename)[0] + ".mp4"
# Define the full path for the converted output file
output_file = os.path.join(output_directory, output_filename)
# Run FFmpeg conversion
subprocess.run([ffmpeg_path,
'-i', input_file,
'-vcodec', 'libx264',
'-pix_fmt', 'yuv420p',
'-strict', 'experimental',
'-b:v', '1m',
output_file,
'-y'], check=True, shell=True)
print(f"Video conversion to {output_file} successful!")
# os.remove(input_file) # Running into permission issues trying to delete from AppData
# print(f"Original playblast deleted: {input_file}")
except subprocess.CalledProcessError as e:
print(f"Error during FFmpeg conversion: {e}")
def get_playblast_options_window():
# Check if the Playblast Options window is open
windows = cmds.lsUI(windows=True)
for window in windows:
if cmds.window(window, query=True, title=True) == "Playblast Options": # Exact title match
window_ptr = omui.MQtUtil.findWindow(window)
return wrapInstance(int(window_ptr), QtWidgets.QWidget)
return None
2024-09-13 12:22:04 -04:00
class WindowWatcher:
""" A class to watch for a particular window in Maya """
def __init__(self, window_title, on_open_callback, on_close_callback=None):
self.window_title = window_title
self.on_open_callback = on_open_callback
self.on_close_callback = on_close_callback
self.window_opened = False
def check_for_window_open(self):
if not self.window_opened:
window = get_playblast_options_window()
2024-09-13 12:22:04 -04:00
if window:
self.on_open_callback()
self.window_opened = True
else:
window = get_playblast_options_window()
2024-09-13 12:22:04 -04:00
if not window:
self.window_opened = False
if self.on_close_callback:
self.on_close_callback()
def find_button_by_label(window, label_text):
for widget in window.findChildren(QtWidgets.QPushButton):
if widget.text() == label_text:
return widget
return None
2024-09-13 12:22:04 -04:00
def override_playblast_button():
playblast_window = get_playblast_options_window()
tinyblast_button = find_button_by_label(playblast_window, 'Playblast')
if tinyblast_button:
tinyblast_button.clicked.disconnect()
tinyblast_button.setText('Tinyblast')
tinyblast_button.clicked.connect(custom_playblast)
2024-09-13 12:22:04 -04:00
def setup_script_job():
global playblast_job_id
2024-09-13 12:22:04 -04:00
# Kill any previously running scriptJob
if playblast_job_id is not None and cmds.scriptJob(exists=playblast_job_id):
cmds.scriptJob(kill=playblast_job_id, force=True)
print(f"Killed previous scriptJob with ID: {playblast_job_id}")
print("Created scriptjob")
2024-09-13 12:22:04 -04:00
# Watch for the Playblast Options window by title
playblast_watcher = WindowWatcher(
window_title="Playblast Options", # Exact window title to look for
on_open_callback=override_playblast_button
2024-09-13 12:22:04 -04:00
)
# Set up a new scriptJob
playblast_job_id = cmds.scriptJob(event=["idle", playblast_watcher.check_for_window_open])
class Tinyblast(ompx.MPxCommand):
def __init__(self):
ompx.MPxCommand.__init__(self)
def doIt(selfself, args):
print("So I started blastin'.")
custom_playblast()
2024-09-13 12:22:04 -04:00
def tinyblast_cmd():
return ompx.asMPxPtr(Tinyblast())
2024-09-13 12:22:04 -04:00
def initializePlugin(mobject):
global playblast_job_id
2024-09-13 12:22:04 -04:00
try:
mplugin = ompx.MFnPlugin(mobject, "Jack Christensen", "1.1.0", "Any")
mplugin.registerCommand("tinyblast", tinyblast_cmd)
2024-09-13 12:22:04 -04:00
om.MGlobal.displayInfo("Tinyblast plugin loaded.")
setup_script_job()
2024-09-13 12:22:04 -04:00
except Exception as e:
om.MGlobal.displayError(f"Failed to initialize plugin: {str(e)}")
raise
def uninitializePlugin(mobject):
global playblast_job_id
2024-09-13 12:22:04 -04:00
try:
mplugin = ompx.MFnPlugin(mobject)
mplugin.deregisterCommand("tinyblast")
om.MGlobal.displayInfo("Tinyblast plugin unloaded.")
cmds.scriptJob(kill=playblast_job_id, force=True)
print("Killed script job")
2024-09-13 12:22:04 -04:00
except Exception as e:
om.MGlobal.displayError(f"Failed to uninitialize plugin: {str(e)}")
raise