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:
colorplease 2024-02-07 21:03:11 -08:00
parent a62ce9d1c5
commit 2164d055a9
12 changed files with 2587 additions and 1937 deletions

View file

@ -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++)
{ {

View file

@ -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

View file

@ -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

View file

@ -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);
} }

View file

@ -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();
} }
}); });

View file

@ -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);
}
}
} }
} }

View file

@ -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);
}
}
} }
} }

View file

@ -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