|
|
|
@ -4,17 +4,17 @@ bl_info = {
|
|
|
|
|
"name": "Text to Video", |
|
|
|
|
"author": "tintwotin", |
|
|
|
|
"version": (1, 0), |
|
|
|
|
"blender": (3, 40, 0), |
|
|
|
|
"blender": (3, 4, 0), |
|
|
|
|
"location": "Video Sequence Editor > Sidebar > Text to Video", |
|
|
|
|
"description": "Convert text to video", |
|
|
|
|
"category": "Video Sequence Editor", |
|
|
|
|
"category": "SequenceR", |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
import bpy |
|
|
|
|
from bpy.types import Operator, Panel |
|
|
|
|
import site |
|
|
|
|
import subprocess |
|
|
|
|
import sys |
|
|
|
|
import sys, os |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def import_module(self, module, install_module): |
|
|
|
@ -25,11 +25,12 @@ def import_module(self, module, install_module):
|
|
|
|
|
app_path = site.USER_SITE |
|
|
|
|
if app_path not in sys.path: |
|
|
|
|
sys.path.append(app_path) |
|
|
|
|
pybin = sys.executable # bpy.app.binary_path_python # Use for 2.83 |
|
|
|
|
pybin = sys.executable |
|
|
|
|
|
|
|
|
|
print("Ensuring: pip") |
|
|
|
|
try: |
|
|
|
|
subprocess.call([pybin, "-m", "ensurepip"]) |
|
|
|
|
subprocess.call([pybin, "-m", "pip", "install", "--upgrade","pip"]) |
|
|
|
|
except ImportError: |
|
|
|
|
pass |
|
|
|
|
self.report({"INFO"}, "Installing: " + module + " module.") |
|
|
|
@ -43,18 +44,16 @@ def import_module(self, module, install_module):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SequencerImportMovieOperator(Operator): |
|
|
|
|
"""Import a movie strip into the Sequencer at the current frame""" |
|
|
|
|
"""Text to Video""" |
|
|
|
|
|
|
|
|
|
bl_idname = "sequencer.import_movie" |
|
|
|
|
bl_label = "Prompt" |
|
|
|
|
bl_description = "Import a movie strip into the Sequencer at the current frame" |
|
|
|
|
bl_description = "Convert text to video" |
|
|
|
|
bl_options = {"REGISTER", "UNDO"} |
|
|
|
|
|
|
|
|
|
filename: bpy.props.StringProperty( |
|
|
|
|
name="File Name", default="", description="Name of the movie file to import" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
def execute(self, context): |
|
|
|
|
if not bpy.types.Scene.text_prompt: |
|
|
|
|
return {"CANCELLED"} |
|
|
|
|
scene = context.scene |
|
|
|
|
|
|
|
|
|
app_path = site.USER_SITE |
|
|
|
@ -62,11 +61,20 @@ class SequencerImportMovieOperator(Operator):
|
|
|
|
|
sys.path.append(app_path) |
|
|
|
|
pybin = sys.executable |
|
|
|
|
|
|
|
|
|
import_module(self, "modelscope", "modelscope==1.4.2") #git+https://github.com/modelscope/modelscope.git |
|
|
|
|
import_module(self, "open_clip_torch", "open_clip_torch") |
|
|
|
|
import_module(self, "pytorch_lightning", "pytorch_lightning") |
|
|
|
|
import_module(self, "addict", "addict") |
|
|
|
|
import_module(self, "yapf", "yapf") |
|
|
|
|
import_module(self, "datasets", "datasets") |
|
|
|
|
import_module(self, "einops", "einops") |
|
|
|
|
import_module(self, "jsonplus", "jsonplus") |
|
|
|
|
import_module(self, "oss2", "oss2") |
|
|
|
|
import_module(self, "pyarrow", "pyarrow") |
|
|
|
|
import_module(self, "huggingface_hub", "--upgrade huggingface_hub") |
|
|
|
|
import_module(self, "numpy", "--upgrade numpy") |
|
|
|
|
import_module(self, "gast", "gast") |
|
|
|
|
import_module(self, "tensorflow", "tensorflow") |
|
|
|
|
import_module(self, "modelscope", "modelscope==1.4.2") #git+https://github.com/modelscope/modelscope.git |
|
|
|
|
|
|
|
|
|
from huggingface_hub import snapshot_download |
|
|
|
|
|
|
|
|
@ -74,37 +82,37 @@ class SequencerImportMovieOperator(Operator):
|
|
|
|
|
from modelscope.outputs import OutputKeys |
|
|
|
|
import pathlib |
|
|
|
|
|
|
|
|
|
## model_dir = pathlib.Path('weights') |
|
|
|
|
## snapshot_download('damo-vilab/modelscope-damo-text-to-video-synthesis', |
|
|
|
|
## repo_type='model', local_dir=model_dir) |
|
|
|
|
|
|
|
|
|
# pipe = pipeline('text-to-video-synthesis', "damo/text-to-video-synthesis") |
|
|
|
|
# test_text = { |
|
|
|
|
# 'text': 'A panda eating bamboo on a rock.', |
|
|
|
|
# } |
|
|
|
|
# output_video_path = pipe(test_text,)[OutputKeys.OUTPUT_VIDEO] |
|
|
|
|
# filepath = bpy.path.abspath(output_video_path) |
|
|
|
|
model_dir = pathlib.Path('weights') |
|
|
|
|
if not model_dir.exists(): |
|
|
|
|
model_dir.mkdir() |
|
|
|
|
snapshot_download('damo-vilab/modelscope-damo-text-to-video-synthesis', |
|
|
|
|
script_file = os.path.realpath(__file__) |
|
|
|
|
directory = os.path.dirname(script_file) |
|
|
|
|
model_dir = os.path.join(directory, "model") |
|
|
|
|
check_config = os.path.join(model_dir, "configuration.json") |
|
|
|
|
check_config = pathlib.Path(check_config) |
|
|
|
|
if not os.path.isdir(model_dir): |
|
|
|
|
os.mkdir(model_dir) |
|
|
|
|
if not os.path.isfile(check_config): |
|
|
|
|
snapshot_download(repo_id='damo-vilab/modelscope-damo-text-to-video-synthesis', |
|
|
|
|
repo_type='model', |
|
|
|
|
dir=model_dir) |
|
|
|
|
p = pipeline('text-to-video-synthesis', model_dir.as_posix()) |
|
|
|
|
local_dir=model_dir, |
|
|
|
|
local_dir_use_symlinks=False) |
|
|
|
|
|
|
|
|
|
p = pipeline('text-to-video-synthesis', model_dir) |
|
|
|
|
|
|
|
|
|
#p = pipeline("text-to-video-synthesis", "damo/text-to-video-synthesis") |
|
|
|
|
test_text = {"text": self.filename} |
|
|
|
|
test_text = {"text": self.text_prompt} |
|
|
|
|
output_video_path = p( |
|
|
|
|
test_text, |
|
|
|
|
)[OutputKeys.OUTPUT_VIDEO] |
|
|
|
|
|
|
|
|
|
strip = scene.sequence_editor.sequences.new_movie( |
|
|
|
|
name=self.filename, |
|
|
|
|
filepath=filepath, |
|
|
|
|
channel=1, |
|
|
|
|
frame_start=scene.frame_current, |
|
|
|
|
) |
|
|
|
|
filepath = bpy.path.abspath(output_video_path) |
|
|
|
|
if os.path.isfile(filepath): |
|
|
|
|
strip = scene.sequence_editor.sequences.new_movie( |
|
|
|
|
name=bpy.types.Scene.text_prompt, |
|
|
|
|
filepath=filepath, |
|
|
|
|
channel=1, |
|
|
|
|
frame_start=scene.frame_current, |
|
|
|
|
) |
|
|
|
|
else: |
|
|
|
|
print("Modelscope did not produce a file!") |
|
|
|
|
|
|
|
|
|
return {"FINISHED"} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -121,7 +129,7 @@ class SequencerPanel(Panel):
|
|
|
|
|
layout = self.layout |
|
|
|
|
scene = context.scene |
|
|
|
|
row = layout.row() |
|
|
|
|
row.prop(context.scene, "my_movie_filename", text="") |
|
|
|
|
row.prop(context.scene, "text_prompt", text="") |
|
|
|
|
row = layout.row() |
|
|
|
|
row.operator("sequencer.import_movie", text="Generate Movie") |
|
|
|
|
|
|
|
|
@ -129,15 +137,15 @@ class SequencerPanel(Panel):
|
|
|
|
|
def register(): |
|
|
|
|
bpy.utils.register_class(SequencerImportMovieOperator) |
|
|
|
|
bpy.utils.register_class(SequencerPanel) |
|
|
|
|
bpy.types.Scene.my_movie_filename = bpy.props.StringProperty( |
|
|
|
|
name="My Movie Filename", default="" |
|
|
|
|
bpy.types.Scene.text_prompt = bpy.props.StringProperty( |
|
|
|
|
name="text_prompt", default="" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def unregister(): |
|
|
|
|
bpy.utils.unregister_class(SequencerImportMovieOperator) |
|
|
|
|
bpy.utils.unregister_class(SequencerPanel) |
|
|
|
|
del bpy.types.Scene.my_movie_filename |
|
|
|
|
del bpy.types.Scene.text_prompt |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|