release 1 :3
*Video Recording of your remixes ! (obviously) *”Beat to Beat” functionality, clip parts of your remixes and send them anywhere ! *Quality Settings, want more size? Turn it Down! Want more quality? Turn it Up! *I’m still Gold in Fortnite.
This commit is contained in:
parent
a62ce9d1c5
commit
2164d055a9
|
|
@ -1,6 +1,7 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using FFmpegOut;
|
||||||
|
|
||||||
public class AudioRenderer : MonoBehaviour
|
public class AudioRenderer : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
|
@ -10,6 +11,9 @@ public class AudioRenderer : MonoBehaviour
|
||||||
private const short BITS_PER_SAMPLE = 16;
|
private const short BITS_PER_SAMPLE = 16;
|
||||||
private const int SAMPLE_RATE = 44100;
|
private const int SAMPLE_RATE = 44100;
|
||||||
|
|
||||||
|
//the video recorder
|
||||||
|
public bool recorderBegin;
|
||||||
|
|
||||||
// the number of audio channels in the output file
|
// the number of audio channels in the output file
|
||||||
private int channels = 2;
|
private int channels = 2;
|
||||||
|
|
||||||
|
|
@ -58,6 +62,10 @@ public class AudioRenderer : MonoBehaviour
|
||||||
/// Write a chunk of data to the output stream.
|
/// Write a chunk of data to the output stream.
|
||||||
public void Write(float[] audioData)
|
public void Write(float[] audioData)
|
||||||
{
|
{
|
||||||
|
if(!recorderBegin)
|
||||||
|
{
|
||||||
|
recorderBegin = true;
|
||||||
|
}
|
||||||
// Convert numeric audio data to bytes
|
// Convert numeric audio data to bytes
|
||||||
for (int i = 0; i < audioData.Length; i++)
|
for (int i = 0; i < audioData.Length; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ namespace FFmpegOut
|
||||||
}
|
}
|
||||||
|
|
||||||
public int bitRate;
|
public int bitRate;
|
||||||
|
public string path;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
@ -150,7 +151,7 @@ namespace FFmpegOut
|
||||||
// Start an FFmpeg session.
|
// Start an FFmpeg session.
|
||||||
Debug.Log("i'm not" + bitRate);
|
Debug.Log("i'm not" + bitRate);
|
||||||
_session = FFmpegSession.Create(
|
_session = FFmpegSession.Create(
|
||||||
gameObject.name,
|
path,
|
||||||
camera.targetTexture.width,
|
camera.targetTexture.width,
|
||||||
camera.targetTexture.height,
|
camera.targetTexture.height,
|
||||||
_frameRate, bitRate, preset
|
_frameRate, bitRate, preset
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,7 @@ namespace FFmpegOut
|
||||||
FFmpegPreset preset
|
FFmpegPreset preset
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
name += System.DateTime.Now.ToString(" yyyy MMdd HHmmss");
|
return CreateWithOutputPath(name, width, height, frameRate, bitRate, preset);
|
||||||
var path = name.Replace(" ", "_") + preset.GetSuffix();
|
|
||||||
return CreateWithOutputPath(path, width, height, frameRate, bitRate, preset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FFmpegSession CreateWithOutputPath(
|
public static FFmpegSession CreateWithOutputPath(
|
||||||
|
|
@ -28,7 +26,6 @@ namespace FFmpegOut
|
||||||
FFmpegPreset preset
|
FFmpegPreset preset
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Debug.Log("I'm" + bitRate);
|
|
||||||
return new FFmpegSession(
|
return new FFmpegSession(
|
||||||
"-y -f rawvideo -vcodec rawvideo -pixel_format rgba"
|
"-y -f rawvideo -vcodec rawvideo -pixel_format rgba"
|
||||||
+ " -colorspace bt709"
|
+ " -colorspace bt709"
|
||||||
|
|
@ -36,7 +33,7 @@ namespace FFmpegOut
|
||||||
+ " -framerate " + frameRate
|
+ " -framerate " + frameRate
|
||||||
+ " -loglevel warning -i - " + preset.GetOptions()
|
+ " -loglevel warning -i - " + preset.GetOptions()
|
||||||
+ " -b:v " + (bitRate * 75) + "k"
|
+ " -b:v " + (bitRate * 75) + "k"
|
||||||
+ " \"" + "C:/Users/pikmi/Downloads/temp.mp4" + "\"" //hijacked this. basically i dont want some fancy output file name (which is what the old code did) so it's just temp now lol
|
+ " \"" + outputPath + "\"" //hijacked this. basically i dont want some fancy output file name (which is what the old code did) so it's just temp now lol
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
public static class AppInfo {
|
public static class AppInfo {
|
||||||
public const string Version = "1.0.9";
|
public const string Version = "1.0.11";
|
||||||
public static readonly DateTime Date = new DateTime(2024, 02, 01, 06, 05, 21, 727, DateTimeKind.Utc);
|
public static readonly DateTime Date = new DateTime(2024, 02, 08, 04, 50, 47, 856, DateTimeKind.Utc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -396,6 +396,7 @@ namespace HeavenStudio.Editor
|
||||||
if (path != String.Empty)
|
if (path != String.Empty)
|
||||||
{
|
{
|
||||||
heavenRecorder.pathHeavenRecorder = path;
|
heavenRecorder.pathHeavenRecorder = path;
|
||||||
|
heavenRecorder.WritePathToDialogue();
|
||||||
heavenRecorder.GetUsablePath();
|
heavenRecorder.GetUsablePath();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ using UnityEngine;
|
||||||
using FFmpegOut;
|
using FFmpegOut;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using HeavenStudio.Editor;
|
using HeavenStudio.Editor;
|
||||||
|
using HeavenStudio;
|
||||||
|
using HeavenStudio.Editor.Track;
|
||||||
|
|
||||||
namespace FFmpegOut
|
namespace FFmpegOut
|
||||||
{
|
{
|
||||||
|
|
@ -14,10 +16,15 @@ public class HeavenRecorderController : MonoBehaviour
|
||||||
public AudioRenderer audioRenderer;
|
public AudioRenderer audioRenderer;
|
||||||
|
|
||||||
public string pathHeavenRecorder;
|
public string pathHeavenRecorder;
|
||||||
|
public string actualDirectory;
|
||||||
|
|
||||||
[SerializeField]HeavenRecorderDialog dialog;
|
[SerializeField]HeavenRecorderDialog dialog;
|
||||||
|
[SerializeField]Timeline timeline;
|
||||||
|
|
||||||
bool exporting = true;
|
bool exporting = true;
|
||||||
|
float endBeatRecorder;
|
||||||
|
float startBeatRecorder;
|
||||||
|
float prevStartBeat;
|
||||||
// Start is called before the first frame update
|
// Start is called before the first frame update
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
|
|
@ -27,35 +34,13 @@ public class HeavenRecorderController : MonoBehaviour
|
||||||
// Update is called once per frame
|
// Update is called once per frame
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
if(Input.GetKeyDown(KeyCode.L))
|
if((Conductor.instance.songPositionInBeats > endBeatRecorder) || Input.GetKeyDown(KeyCode.Escape))
|
||||||
{
|
{
|
||||||
if(recorder.enabled)
|
StopRecording();
|
||||||
{
|
}
|
||||||
print("recording stopped!");
|
if(audioRenderer.recorderBegin && !recorder.enabled)
|
||||||
recorder.enabled = false;
|
{
|
||||||
audioRenderer.Rendering = false;
|
recorder.enabled = true;
|
||||||
if(audioRenderer.Save("C:/Users/pikmi/Downloads/temp.wav").State == AudioRenderer.Status.SUCCESS && exporting == true)
|
|
||||||
{
|
|
||||||
Merge();
|
|
||||||
audioRenderer.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(File.Exists("C:/Users/pikmi/Downloads/temp.wav"))
|
|
||||||
{
|
|
||||||
File.Delete("C:/Users/pikmi/Downloads/temp.wav");
|
|
||||||
}
|
|
||||||
if(File.Exists("C:/Users/pikmi/Downloads/temp.mp4"))
|
|
||||||
{
|
|
||||||
File.Delete("C:/Users/pikmi/Downloads/temp.mp4");
|
|
||||||
}
|
|
||||||
audioRenderer.Clear();
|
|
||||||
audioRenderer.Rendering = true;
|
|
||||||
print("recording started!");
|
|
||||||
recorder.enabled = true;
|
|
||||||
exporting = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,16 +48,22 @@ public class HeavenRecorderController : MonoBehaviour
|
||||||
{
|
{
|
||||||
exporting = false;
|
exporting = false;
|
||||||
FFmpegSession _session;
|
FFmpegSession _session;
|
||||||
_session = FFmpegSession.CreateWithArguments("-y -i C:/Users/pikmi/Downloads/temp.mp4 -i C:/Users/pikmi/Downloads/temp.wav -c:v copy -c:a aac C:/Users/pikmi/Downloads/output.mp4");
|
_session = FFmpegSession.CreateWithArguments("-y -i "+ pathHeavenRecorder + "temp.mp4 -i "+ pathHeavenRecorder + "temp.wav -c:v copy -c:a aac " + actualDirectory);
|
||||||
_session.Close();
|
_session.Close();
|
||||||
_session.Dispose();
|
_session.Dispose();
|
||||||
_session = null;
|
_session = null;
|
||||||
File.Delete("C:/Users/pikmi/Downloads/temp.wav");
|
File.Delete(pathHeavenRecorder + "temp.wav");
|
||||||
File.Delete("C:/Users/pikmi/Downloads/temp.mp4");
|
File.Delete(pathHeavenRecorder + "temp.mp4");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetUsablePath()
|
public void GetUsablePath()
|
||||||
{
|
{
|
||||||
|
actualDirectory = pathHeavenRecorder;
|
||||||
|
actualDirectory = actualDirectory.Replace("\\", "/");
|
||||||
|
if(actualDirectory.Contains(".mp4") == false)
|
||||||
|
{
|
||||||
|
actualDirectory += ".mp4";
|
||||||
|
}
|
||||||
int numberOfSlashes = 0;
|
int numberOfSlashes = 0;
|
||||||
int tempNumberOfSlashes = 0;
|
int tempNumberOfSlashes = 0;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
@ -103,13 +94,14 @@ public class HeavenRecorderController : MonoBehaviour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pathHeavenRecorder = pathHeavenRecorder.Remove(index+1,charsAfterSlash-1);
|
pathHeavenRecorder = pathHeavenRecorder.Remove(index+1,charsAfterSlash-1);
|
||||||
pathHeavenRecorder = pathHeavenRecorder.Replace("\\", "\\\\");
|
pathHeavenRecorder = pathHeavenRecorder.Replace("\\", "/");
|
||||||
WritePathToDialogue();
|
WritePathToDialogue();
|
||||||
|
recorder.path = pathHeavenRecorder + "temp.mp4";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WritePathToDialogue()
|
public void WritePathToDialogue()
|
||||||
{
|
{
|
||||||
dialog.pathDialog = pathHeavenRecorder;
|
dialog.pathDialog = actualDirectory;
|
||||||
dialog.SetPathText();
|
dialog.SetPathText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,5 +110,56 @@ public class HeavenRecorderController : MonoBehaviour
|
||||||
recorder.bitRate = bitrate;
|
recorder.bitRate = bitrate;
|
||||||
// print(recorder.bitRate);
|
// print(recorder.bitRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetBeatData(float startBeat, float endBeat)
|
||||||
|
{
|
||||||
|
prevStartBeat = timeline.PlaybackBeat;
|
||||||
|
startBeatRecorder = startBeat;
|
||||||
|
endBeatRecorder = endBeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BeginRecording()
|
||||||
|
{
|
||||||
|
dialog.RecordingIndicator(true);
|
||||||
|
if(!recorder.enabled)
|
||||||
|
{
|
||||||
|
if(File.Exists(pathHeavenRecorder + "temp.wav"))
|
||||||
|
{
|
||||||
|
File.Delete(pathHeavenRecorder + "temp.wav");
|
||||||
|
}
|
||||||
|
if(File.Exists(pathHeavenRecorder + "temp.mp4"))
|
||||||
|
{
|
||||||
|
File.Delete(pathHeavenRecorder + "temp.mp4");
|
||||||
|
}
|
||||||
|
audioRenderer.Clear();
|
||||||
|
audioRenderer.Rendering = true;
|
||||||
|
print("recording started!");
|
||||||
|
// recorder.enabled = true;
|
||||||
|
exporting = true;
|
||||||
|
timeline.PlaybackBeat = startBeatRecorder;
|
||||||
|
Conductor.instance.SetBeat(startBeatRecorder);
|
||||||
|
timeline.PlayCheck(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StopRecording()
|
||||||
|
{
|
||||||
|
if(recorder.enabled && audioRenderer.Rendering)
|
||||||
|
{
|
||||||
|
print("recording stopped!");
|
||||||
|
audioRenderer.Rendering = false;
|
||||||
|
if(audioRenderer.Save(pathHeavenRecorder + "temp.wav").State == AudioRenderer.Status.SUCCESS && exporting == true)
|
||||||
|
{
|
||||||
|
audioRenderer.recorderBegin = false;
|
||||||
|
recorder.enabled = false;
|
||||||
|
Merge();
|
||||||
|
audioRenderer.Clear();
|
||||||
|
}
|
||||||
|
timeline.PlayCheck(false);
|
||||||
|
timeline.PlaybackBeat = endBeatRecorder;
|
||||||
|
Conductor.instance.SetBeat(prevStartBeat);
|
||||||
|
dialog.RecordingIndicator(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,65 @@ public class HeavenRecorderDialog : Dialog
|
||||||
[SerializeField]HeavenRecorderController heavenRecorder;
|
[SerializeField]HeavenRecorderController heavenRecorder;
|
||||||
[SerializeField]TextMeshProUGUI directoryText;
|
[SerializeField]TextMeshProUGUI directoryText;
|
||||||
[SerializeField]TextMeshProUGUI qualityNum;
|
[SerializeField]TextMeshProUGUI qualityNum;
|
||||||
|
[SerializeField]TextMeshProUGUI beatNumError;
|
||||||
|
[SerializeField]TextMeshProUGUI exportButtonText;
|
||||||
[SerializeField]Slider qualitySlide;
|
[SerializeField]Slider qualitySlide;
|
||||||
|
[SerializeField]TMP_InputField startBeat;
|
||||||
|
[SerializeField]TMP_InputField endBeat;
|
||||||
|
[SerializeField]Button exportButton;
|
||||||
|
[SerializeField]Color exportButtonColorReady;
|
||||||
|
|
||||||
|
[SerializeField]bool checkPathSet = false;
|
||||||
|
[SerializeField]bool checkBeatNumsSet;
|
||||||
|
|
||||||
|
[SerializeField]float startBeatValue;
|
||||||
|
[SerializeField]float endBeatValue;
|
||||||
|
|
||||||
|
[SerializeField]GameObject ExportUI;
|
||||||
|
[SerializeField]GameObject RecordingUI;
|
||||||
|
[SerializeField]GameObject exitButton;
|
||||||
|
|
||||||
// Start is called before the first frame update
|
// Start is called before the first frame update
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
UpdateQualityNum();
|
UpdateQualityNum();
|
||||||
|
beatNumError.SetText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update is called once per frame
|
string BeatError()
|
||||||
void Update()
|
|
||||||
{
|
{
|
||||||
|
//error #1: beats are equal, so nothing would even be recorded
|
||||||
|
if(startBeatValue == endBeatValue)
|
||||||
|
{
|
||||||
|
checkBeatNumsSet = false;
|
||||||
|
return "ERROR: START AND END BEAT EQUAL (are you trying to record nothing??)";
|
||||||
|
}
|
||||||
|
//error #2: endbeat - startbeat = negative number, so the recording would never end
|
||||||
|
if(endBeatValue - startBeatValue < 0)
|
||||||
|
{
|
||||||
|
checkBeatNumsSet = false;
|
||||||
|
return "ERROR: END BEAT BEHIND START BEAT (might wanna swap them idk)";
|
||||||
|
}
|
||||||
|
checkBeatNumsSet = true;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetBeat(bool isStart)
|
||||||
|
{
|
||||||
|
if(isStart)
|
||||||
|
{
|
||||||
|
startBeatValue = float.Parse(startBeat.text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endBeatValue = float.Parse(endBeat.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(startBeatValue != null && endBeatValue != null)
|
||||||
|
{
|
||||||
|
beatNumError.SetText(BeatError());
|
||||||
|
PreFlightCheckSendOff();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SwitchTempoDialog()
|
public void SwitchTempoDialog()
|
||||||
|
|
@ -42,7 +90,9 @@ public class HeavenRecorderDialog : Dialog
|
||||||
}
|
}
|
||||||
public void SetPathText()
|
public void SetPathText()
|
||||||
{
|
{
|
||||||
|
checkPathSet = true;
|
||||||
directoryText.SetText("Directory: " + pathDialog);
|
directoryText.SetText("Directory: " + pathDialog);
|
||||||
|
PreFlightCheckSendOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateQualityNum()
|
public void UpdateQualityNum()
|
||||||
|
|
@ -50,5 +100,32 @@ public class HeavenRecorderDialog : Dialog
|
||||||
qualityNum.SetText(" " + qualitySlide.value.ToString());
|
qualityNum.SetText(" " + qualitySlide.value.ToString());
|
||||||
heavenRecorder.SetBitRate((int)qualitySlide.value);
|
heavenRecorder.SetBitRate((int)qualitySlide.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PreFlightCheckSendOff()
|
||||||
|
{
|
||||||
|
//check two bools and send off all of the beat data to heavenrecordercontroller
|
||||||
|
if(checkBeatNumsSet && checkPathSet)
|
||||||
|
{
|
||||||
|
heavenRecorder.SetBeatData(startBeatValue, endBeatValue);
|
||||||
|
exportButton.interactable = true;
|
||||||
|
exportButtonText.color = exportButtonColorReady;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordingIndicator(bool isRecording)
|
||||||
|
{
|
||||||
|
if(isRecording)
|
||||||
|
{
|
||||||
|
ExportUI.SetActive(false);
|
||||||
|
RecordingUI.SetActive(true);
|
||||||
|
exitButton.SetActive(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExportUI.SetActive(true);
|
||||||
|
RecordingUI.SetActive(false);
|
||||||
|
exitButton.SetActive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ PlayerSettings:
|
||||||
16:10: 1
|
16:10: 1
|
||||||
16:9: 1
|
16:9: 1
|
||||||
Others: 1
|
Others: 1
|
||||||
bundleVersion: 1.0.9
|
bundleVersion: 1.0.11
|
||||||
preloadedAssets:
|
preloadedAssets:
|
||||||
- {fileID: 102900000, guid: 5348c08b82446e0478cee8bda6c02cfc, type: 3}
|
- {fileID: 102900000, guid: 5348c08b82446e0478cee8bda6c02cfc, type: 3}
|
||||||
metroInputSource: 0
|
metroInputSource: 0
|
||||||
|
|
@ -158,11 +158,11 @@ PlayerSettings:
|
||||||
applicationIdentifier:
|
applicationIdentifier:
|
||||||
Standalone: com.RHeavenStudio.Heaven-Studio
|
Standalone: com.RHeavenStudio.Heaven-Studio
|
||||||
buildNumber:
|
buildNumber:
|
||||||
Standalone: 100009
|
Standalone: 100011
|
||||||
iPhone: 0
|
iPhone: 0
|
||||||
tvOS: 0
|
tvOS: 0
|
||||||
overrideDefaultApplicationIdentifier: 0
|
overrideDefaultApplicationIdentifier: 0
|
||||||
AndroidBundleVersionCode: 100009
|
AndroidBundleVersionCode: 100011
|
||||||
AndroidMinSdkVersion: 22
|
AndroidMinSdkVersion: 22
|
||||||
AndroidTargetSdkVersion: 0
|
AndroidTargetSdkVersion: 0
|
||||||
AndroidPreferredInstallLocation: 1
|
AndroidPreferredInstallLocation: 1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue