mirror of
https://github.com/LinoSchmidt/StickExporterTX.git
synced 2026-03-21 01:51:15 +01:00
Added other video formats
This commit is contained in:
106
dependencies/blenderScript.py
vendored
106
dependencies/blenderScript.py
vendored
@@ -55,14 +55,15 @@ while True:
|
||||
else:
|
||||
StickMode = 1
|
||||
|
||||
fps = int(settingsRoot[0].text)
|
||||
width = int(settingsRoot[1].text)
|
||||
StickDistance = _map(int(settingsRoot[2].text), 0, 100, 5, 105)
|
||||
|
||||
if(command == "startRendering"):
|
||||
|
||||
logs = settingsRoot[4].text[1:][:-1].split("\"\"")
|
||||
output = settingsRoot[5].text
|
||||
fps = int(settingsRoot[0].text)
|
||||
videoFormat = settingsRoot[4].text
|
||||
logs = settingsRoot[5].text[1:][:-1].split("\"\"")
|
||||
output = settingsRoot[6].text
|
||||
|
||||
logCount = len(logs)
|
||||
logNumber = 1
|
||||
@@ -105,8 +106,27 @@ while True:
|
||||
logger.error("Can't read Log: " + (Str)(e))
|
||||
|
||||
bpy.context.scene.render.image_settings.file_format = 'FFMPEG'
|
||||
bpy.context.scene.render.ffmpeg.format = "QUICKTIME"
|
||||
bpy.context.scene.render.ffmpeg.codec = "QTRLE"
|
||||
|
||||
if(videoFormat == "mp4"):
|
||||
bpy.context.scene.render.ffmpeg.format = 'MPEG4'
|
||||
bpy.context.scene.render.ffmpeg.codec = 'H264'
|
||||
bpy.context.scene.render.image_settings.color_mode = 'RGB'
|
||||
elif(videoFormat == "mov"):
|
||||
bpy.context.scene.render.ffmpeg.format = 'QUICKTIME'
|
||||
bpy.context.scene.render.ffmpeg.codec = 'QTRLE'
|
||||
bpy.context.scene.render.image_settings.color_mode = 'RGBA'
|
||||
elif(videoFormat == "avi"):
|
||||
bpy.context.scene.render.ffmpeg.format = 'AVI'
|
||||
bpy.context.scene.render.ffmpeg.codec = 'FFV1'
|
||||
bpy.context.scene.render.image_settings.color_mode = 'RGBA'
|
||||
elif(videoFormat == "webm"):
|
||||
bpy.context.scene.render.ffmpeg.format = 'WEBM'
|
||||
bpy.context.scene.render.ffmpeg.codec = 'WEBM'
|
||||
bpy.context.scene.render.image_settings.color_mode = 'RGBA'
|
||||
elif(videoFormat == "mkv"):
|
||||
bpy.context.scene.render.ffmpeg.format = 'MKV'
|
||||
bpy.context.scene.render.ffmpeg.codec = 'WEBM'
|
||||
bpy.context.scene.render.image_settings.color_mode = 'RGBA'
|
||||
|
||||
scn.render.resolution_x = width
|
||||
GimbalCoverR.location[0] = StickDistance
|
||||
@@ -116,7 +136,7 @@ while True:
|
||||
Camera.location[0] = StickDistance/2
|
||||
Camera.data.ortho_scale = StickDistance+5
|
||||
scn.render.resolution_y = int(width/_map(StickDistance, 5, 105, 2, 21.6))
|
||||
bpy.context.scene.render.filepath = output + "\\" + log.split("/")[-1].split("\\")[-1].replace(".csv", ".mov")
|
||||
bpy.context.scene.render.filepath = output + "\\" + log.split("/")[-1].split("\\")[-1].replace(".csv", "."+videoFormat)
|
||||
|
||||
scn.render.fps = 1000
|
||||
scn.render.fps_base = FPSxxx
|
||||
@@ -143,31 +163,25 @@ while True:
|
||||
|
||||
bpy.context.scene.frame_set(frame)
|
||||
|
||||
StickL.rotation_euler=[0,0,0]
|
||||
GimbalL.rotation_euler=[0,0,0]
|
||||
StickR.rotation_euler=[0,0,0]
|
||||
GimbalR.rotation_euler=[0,0,0]
|
||||
|
||||
if StickMode == "1":
|
||||
StickL.rotation_euler=[0,0,0]
|
||||
StickL.rotation_euler.rotate_axis("Y", ailP)
|
||||
StickL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalL.rotation_euler=[0,0,0]
|
||||
GimbalL.rotation_euler.rotate_axis("X", eleP)
|
||||
GimbalL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
StickR.rotation_euler=[0,0,0]
|
||||
StickR.rotation_euler.rotate_axis("Y", rudP)
|
||||
StickR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalR.rotation_euler=[0,0,0]
|
||||
GimbalR.rotation_euler.rotate_axis("X", thrP)
|
||||
GimbalR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
else:
|
||||
StickL.rotation_euler=[0,0,0]
|
||||
StickL.rotation_euler.rotate_axis("Y", rudP)
|
||||
StickL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalL.rotation_euler=[0,0,0]
|
||||
GimbalL.rotation_euler.rotate_axis("X", thrP)
|
||||
GimbalL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
StickR.rotation_euler=[0,0,0]
|
||||
StickR.rotation_euler.rotate_axis("Y", ailP)
|
||||
StickR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalR.rotation_euler=[0,0,0]
|
||||
GimbalR.rotation_euler.rotate_axis("X", eleP)
|
||||
|
||||
StickL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
StickR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
|
||||
logger.info("Init:" + ((str)(frame)) + ":")
|
||||
@@ -183,7 +197,6 @@ while True:
|
||||
elif(command == "getRender"):
|
||||
|
||||
bpy.context.scene.render.image_settings.file_format = 'PNG'
|
||||
bpy.context.scene.frame_set(0)
|
||||
bpy.context.scene.render.filepath = argv[0] + "\\render.png"
|
||||
|
||||
scn.render.resolution_x = width
|
||||
@@ -195,17 +208,52 @@ while True:
|
||||
Camera.data.ortho_scale = StickDistance+5
|
||||
scn.render.resolution_y = int(width/_map(StickDistance, 5, 105, 2, 21.6))
|
||||
|
||||
bpy.context.scene.frame_set(0)
|
||||
|
||||
StickL.rotation_euler=[0,0,0]
|
||||
StickL.rotation_euler.rotate_axis("Y", 0.436)
|
||||
StickL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalL.rotation_euler=[0,0,0]
|
||||
GimbalL.rotation_euler.rotate_axis("X", 0.236)
|
||||
GimbalL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
StickR.rotation_euler=[0,0,0]
|
||||
StickR.rotation_euler.rotate_axis("Y", -0.056)
|
||||
StickR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalR.rotation_euler=[0,0,0]
|
||||
GimbalR.rotation_euler.rotate_axis("X", -0.436)
|
||||
|
||||
if(StickMode == 2):
|
||||
StickL.rotation_euler.rotate_axis("Y", 0)
|
||||
GimbalL.rotation_euler.rotate_axis("X", 0.436)
|
||||
StickR.rotation_euler.rotate_axis("Y", 0)
|
||||
GimbalR.rotation_euler.rotate_axis("X", 0)
|
||||
else:
|
||||
StickL.rotation_euler.rotate_axis("Y", 0)
|
||||
GimbalL.rotation_euler.rotate_axis("X", 0)
|
||||
StickR.rotation_euler.rotate_axis("Y", 0)
|
||||
GimbalR.rotation_euler.rotate_axis("X", 0.436)
|
||||
|
||||
StickL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
StickR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
|
||||
bpy.context.scene.frame_set(1)
|
||||
|
||||
StickL.rotation_euler=[0,0,0]
|
||||
GimbalL.rotation_euler=[0,0,0]
|
||||
StickR.rotation_euler=[0,0,0]
|
||||
GimbalR.rotation_euler=[0,0,0]
|
||||
|
||||
if(StickMode == 2):
|
||||
StickL.rotation_euler.rotate_axis("Y", 0)
|
||||
GimbalL.rotation_euler.rotate_axis("X", 0.436)
|
||||
StickR.rotation_euler.rotate_axis("Y", 0)
|
||||
GimbalR.rotation_euler.rotate_axis("X", 0)
|
||||
else:
|
||||
StickL.rotation_euler.rotate_axis("Y", 0)
|
||||
GimbalL.rotation_euler.rotate_axis("X", 0)
|
||||
StickR.rotation_euler.rotate_axis("Y", 0)
|
||||
GimbalR.rotation_euler.rotate_axis("X", 0.436)
|
||||
|
||||
StickL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalL.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
StickR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
GimbalR.keyframe_insert(data_path="rotation_euler", index=-1)
|
||||
|
||||
bpy.context.scene.frame_set(0)
|
||||
|
||||
bpy.ops.render.render(write_still=True)
|
||||
@@ -7,11 +7,20 @@ function getXMLChild(doc:Document, child:string) {
|
||||
return String(doc.getElementsByTagName(child)[0].childNodes[0].nodeValue);
|
||||
}
|
||||
|
||||
enum VideoFormat {
|
||||
mp4="mp4",
|
||||
mov="mov",
|
||||
webm="webm",
|
||||
avi="avi",
|
||||
mkv="mkv",
|
||||
}
|
||||
|
||||
const defaultSettings = {
|
||||
fps: 30,
|
||||
width: 540,
|
||||
stickDistance: 5,
|
||||
stickMode2: true,
|
||||
videoFormat: VideoFormat.webm,
|
||||
log: '',
|
||||
output: defaultOutputPath
|
||||
}
|
||||
@@ -29,6 +38,7 @@ const settingList = await fetch(SettingPath).then(function(response) {
|
||||
width: parseInt(getXMLChild(xmlDoc, "width")),
|
||||
stickDistance: parseInt(getXMLChild(xmlDoc, "stickDistance")),
|
||||
stickMode2: (getXMLChild(xmlDoc, "stickMode2") === "true"),
|
||||
videoFormat: getXMLChild(xmlDoc, "videoFormat") as unknown as VideoFormat,
|
||||
log: (getXMLChild(xmlDoc, "log") === "None")? "":getXMLChild(xmlDoc, "log"),
|
||||
output: getXMLChild(xmlDoc, "output")
|
||||
}
|
||||
@@ -38,7 +48,7 @@ const settingList = await fetch(SettingPath).then(function(response) {
|
||||
});
|
||||
if(!loadedSuccessfully) updateSettings({});
|
||||
|
||||
function updateSettings(optiones:{fps?:number, width?:number, stickDistance?:number, stickMode2?:boolean, log?:string, output?:string}) {
|
||||
function updateSettings(optiones:{fps?:number, width?:number, stickDistance?:number, stickMode2?:boolean, videoFormat?:VideoFormat, log?:string, output?:string}) {
|
||||
if(optiones.fps === undefined) {
|
||||
optiones.fps = settingList.fps;
|
||||
} else {
|
||||
@@ -59,6 +69,11 @@ function updateSettings(optiones:{fps?:number, width?:number, stickDistance?:num
|
||||
} else {
|
||||
settingList.stickMode2 = optiones.stickMode2;
|
||||
}
|
||||
if(optiones.videoFormat === undefined) {
|
||||
optiones.videoFormat = settingList.videoFormat;
|
||||
} else {
|
||||
settingList.videoFormat = optiones.videoFormat;
|
||||
}
|
||||
if(optiones.log === undefined) {
|
||||
optiones.log = settingList.log;
|
||||
} else {
|
||||
@@ -70,13 +85,18 @@ function updateSettings(optiones:{fps?:number, width?:number, stickDistance?:num
|
||||
settingList.output = optiones.output;
|
||||
}
|
||||
|
||||
const xmlStr = '<?xml version="1.0"?><settings><fps>' + optiones.fps +
|
||||
'</fps><width>' + optiones.width +
|
||||
'</width><stickDistance>' + optiones.stickDistance +
|
||||
'</stickDistance><stickMode2>' + ((optiones.stickMode2)?"true":"false") +
|
||||
'</stickMode2><log>' + ((optiones.log === "")? "None":optiones.log) +
|
||||
'</log><output>' + optiones.output +
|
||||
'</output></settings>';
|
||||
const xmlStr = `
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<settings>
|
||||
<fps>${optiones.fps}</fps>
|
||||
<width>${optiones.width}</width>
|
||||
<stickDistance>${optiones.stickDistance}</stickDistance>
|
||||
<stickMode2>${optiones.stickMode2}</stickMode2>
|
||||
<videoFormat>${optiones.videoFormat}</videoFormat>
|
||||
<log>${(optiones.log === "")?"None":optiones.log}</log>
|
||||
<output>${optiones.output}</output>
|
||||
</settings>
|
||||
`;
|
||||
|
||||
fs.writeFile(SettingPath, formatXML(xmlStr, {collapseContent: true}), function(err) {
|
||||
if(err) {
|
||||
@@ -90,7 +110,8 @@ function settingListLoadDefault() {
|
||||
fps:defaultSettings.fps,
|
||||
width:defaultSettings.width,
|
||||
stickDistance:defaultSettings.stickDistance,
|
||||
stickMode2:defaultSettings.stickMode2
|
||||
stickMode2:defaultSettings.stickMode2,
|
||||
videoFormat:defaultSettings.videoFormat,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -109,5 +130,6 @@ export {
|
||||
settingListLoadDefault,
|
||||
settingList,
|
||||
getLogList,
|
||||
getLogSize
|
||||
getLogSize,
|
||||
VideoFormat
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, {useState, useEffect} from "react";
|
||||
import { settingList, updateSettings, settingListLoadDefault } from "../settings";
|
||||
import React, {useState, useEffect, CSSProperties} from "react";
|
||||
import { settingList, updateSettings, settingListLoadDefault, VideoFormat } from "../settings";
|
||||
import {blender, blenderCmd, renderingPicture} from "../blenderController";
|
||||
import {dataPath} from "../paths";
|
||||
import path from "path";
|
||||
@@ -21,12 +21,49 @@ const RenderLoadingSpinner = () => (
|
||||
</div>
|
||||
);
|
||||
|
||||
function VideoFormatWarning({videoFormat}:{videoFormat:VideoFormat}) {
|
||||
let message = "";
|
||||
|
||||
switch(videoFormat) {
|
||||
case VideoFormat.mp4:
|
||||
message = "mp4 has no support for alpha channel and the background will be black.";
|
||||
break;
|
||||
case VideoFormat.avi:
|
||||
message = "avi can't be played in the preview of this app.";
|
||||
break;
|
||||
case VideoFormat.mkv:
|
||||
message = "mkv can't be played in the preview of this app.";
|
||||
break;
|
||||
case VideoFormat.mov:
|
||||
message = "mov can't be played in the preview of this app.";
|
||||
break;
|
||||
}
|
||||
|
||||
const style:CSSProperties = {
|
||||
height: "30px",
|
||||
width: "30px",
|
||||
fill: "orange",
|
||||
paddingLeft: "5px",
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="videoFormatWarning" title={message} style={style}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
{/* <!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --> */}
|
||||
<path d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SettingsSide() {
|
||||
|
||||
const [fps, setFps] = useState(settingList.fps);
|
||||
const [width, setWidth] = useState(settingList.width);
|
||||
const [stickDistance, setStickDistance] = useState(settingList.stickDistance);
|
||||
const [stickMode2, setStickMode2] = useState(settingList.stickMode2);
|
||||
const [videoFormat, setVideoFormat] = useState(settingList.videoFormat);
|
||||
const [renderImg, setRenderImgInner] = useState(picturePath());
|
||||
setRenderImg = setRenderImgInner;
|
||||
const [renderLoading, setRenderLoadingInner] = useState(renderingPicture);
|
||||
@@ -34,15 +71,27 @@ function SettingsSide() {
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
updateSettings({fps, width, stickDistance, stickMode2});
|
||||
updateSettings({width, stickDistance, stickMode2});
|
||||
blender(blenderCmd.getRender);
|
||||
}, 500);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [fps, width, stickDistance, stickMode2]);
|
||||
}, [width, stickDistance, stickMode2]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
updateSettings({fps, videoFormat});
|
||||
}, 500);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [fps, videoFormat]);
|
||||
|
||||
sideLoaded = true;
|
||||
|
||||
const VideoFormatOptions = Object.keys(VideoFormat).filter((el) => { return isNaN(Number(el)) }).map(key => {
|
||||
return <option key={key} value={key}>{key}</option>;
|
||||
});
|
||||
|
||||
return (
|
||||
<div id="content">
|
||||
<div id="settingRow">
|
||||
@@ -53,13 +102,13 @@ function SettingsSide() {
|
||||
}}/>
|
||||
</span>
|
||||
<span className="inputSpan">
|
||||
<label>Width: </label>
|
||||
<label>Width</label>
|
||||
<input id="widthInput" type="number" value={width.toString()} min="1" step="1" onChange={e => {
|
||||
if(e.target.value.trim().length !== 0) setWidth(parseInt(e.target.value));
|
||||
}}/>
|
||||
</span>
|
||||
<span className="inputSpan">
|
||||
<label>Stick Distance: </label>
|
||||
<label>Stick Distance</label>
|
||||
<input id="stickDistanceInput" type="number" value={stickDistance.toString()} min="0" step="1" onChange={e => {
|
||||
if(e.target.value.trim().length !== 0) setStickDistance(parseInt(e.target.value));
|
||||
}}/>
|
||||
@@ -67,7 +116,7 @@ function SettingsSide() {
|
||||
</div>
|
||||
<div id="settingRow">
|
||||
<div className="dataDiv">
|
||||
<p>Stick Mode:</p>
|
||||
<p>Stick Mode</p>
|
||||
<label htmlFor="stickMode" className="toggle-switchy" data-style="rounded" data-text="12">
|
||||
<input checked={stickMode2} type="checkbox" id="stickMode" onChange={e => {
|
||||
setStickMode2(e.target.checked);
|
||||
@@ -77,6 +126,19 @@ function SettingsSide() {
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<span className="selectSpan">
|
||||
<label className="selectSpanLabel">Format</label>
|
||||
<label className="selectSpanSelect" htmlFor="slct">
|
||||
<select id="slct" required={true} value={videoFormat} onChange={e => {
|
||||
setVideoFormat(e.target.value as unknown as VideoFormat);
|
||||
}}>
|
||||
{VideoFormatOptions}
|
||||
</select>
|
||||
</label>
|
||||
{videoFormat === VideoFormat.mov? <VideoFormatWarning videoFormat={videoFormat}/> : null}
|
||||
{videoFormat === VideoFormat.mp4? <VideoFormatWarning videoFormat={videoFormat}/> : null}
|
||||
{videoFormat === VideoFormat.avi? <VideoFormatWarning videoFormat={videoFormat}/> : null}
|
||||
</span>
|
||||
<button id="resetSettingsButton" onClick={() => {
|
||||
settingListLoadDefault();
|
||||
|
||||
@@ -84,6 +146,7 @@ function SettingsSide() {
|
||||
setWidth(settingList.width);
|
||||
setStickDistance(settingList.stickDistance);
|
||||
setStickMode2(settingList.stickMode2);
|
||||
setVideoFormat(settingList.videoFormat);
|
||||
}}>Reset Settings</button>
|
||||
</div>
|
||||
<div id="renderImgDiv">
|
||||
|
||||
@@ -405,3 +405,27 @@ button:hover {
|
||||
align-items: center;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.selectSpan {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.selectSpanSelect select {
|
||||
padding: 8px 0;
|
||||
border: 0;
|
||||
border-top-right-radius: 18px;
|
||||
border-bottom-right-radius: 18px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
font-size: large;
|
||||
}
|
||||
.selectSpanLabel {
|
||||
padding: 10px 10px;
|
||||
background: #00c24a;
|
||||
border-top-left-radius: 18px;
|
||||
border-bottom-left-radius: 18px;
|
||||
font-weight: bolder;
|
||||
}
|
||||
#videoFormatWarning:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
Reference in New Issue
Block a user