Skip to content

Commit f833b29

Browse files
Dominique LerouxDominique Leroux
authored andcommitted
First version of MovieRecorder.
This is meant to be used with the Unity video/recorder_with_audio branch. It introduces an audio input, which is quite simple for now (enable/disable audio capture). There is disabled functionality in there that we still need to discuss: it allows capturing the output of arbitrary mixers at the same time as the main output. The movie recorder allows to record video and audio into a mp4 or webm file. Because Unity imports these video files very quickly (no transcoding by default), the default output path is inside the Assets folder so users can immediately see and browse their recorded videos using Unity.
1 parent 3230fb6 commit f833b29

18 files changed

+800
-0
lines changed

source/FrameRecorder/Inputs/Audio.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/FrameRecorder/Inputs/Audio/Editor.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using UnityEditorInternal;
2+
using UnityEngine;
3+
using UnityEngine.FrameRecorder;
4+
using UnityEngine.FrameRecorder.Input;
5+
6+
namespace UnityEditor.FrameRecorder.Input
7+
{
8+
[CustomEditor(typeof(AudioInputSettings))]
9+
public class AudioInputSettingsEditor : Editor
10+
{
11+
SerializedProperty m_PreserveAudio;
12+
#if RECORD_AUDIO_MIXERS
13+
SerializedProperty m_AudioMixerGroups;
14+
ReorderableList m_AudioMixerGroupsList;
15+
#endif
16+
17+
protected void OnEnable()
18+
{
19+
if (target == null)
20+
return;
21+
22+
var pf = new PropertyFinder<AudioInputSettings>(serializedObject);
23+
m_PreserveAudio = pf.Find(w => w.m_PreserveAudio);
24+
25+
#if RECORD_AUDIO_MIXERS
26+
m_AudioMixerGroups = serializedObject.FindProperty<AudioInputSettings>(x => x.m_AudioMixerGroups);
27+
m_AudioMixerGroupsList = new ReorderableList(serializedObject, m_AudioMixerGroups, true, true, true, true);
28+
m_AudioMixerGroupsList.drawElementCallback =
29+
(Rect rect, int index, bool isActive, bool isFocused) =>
30+
{
31+
var element = m_AudioMixerGroupsList.serializedProperty.GetArrayElementAtIndex(index);
32+
rect.y += 2;
33+
EditorGUI.PropertyField(
34+
new Rect(rect.x - 25, rect.y, rect.width - 90, EditorGUIUtility.singleLineHeight),
35+
element.FindPropertyRelative("m_MixerGroup"), GUIContent.none);
36+
EditorGUI.PropertyField(
37+
new Rect(rect.x + rect.width - 85, rect.y, 20, EditorGUIUtility.singleLineHeight),
38+
element.FindPropertyRelative("m_Isolate"), GUIContent.none);
39+
EditorGUI.LabelField(
40+
new Rect(rect.x + rect.width - 65, rect.y, 60, EditorGUIUtility.singleLineHeight),
41+
new GUIContent ("Isolate", "Isolate group from mix"));
42+
};
43+
44+
m_AudioMixerGroupsList.drawHeaderCallback = (Rect rect) =>
45+
{
46+
EditorGUI.LabelField(rect, "Audio Mixer Groups");
47+
};
48+
#endif
49+
}
50+
51+
public override void OnInspectorGUI()
52+
{
53+
EditorGUILayout.PropertyField(m_PreserveAudio, new GUIContent("Preserve audio"));
54+
55+
#if RECORD_AUDIO_MIXERS
56+
if (m_AudioMixerGroups != null)
57+
{
58+
serializedObject.Update();
59+
m_AudioMixerGroupsList.DoLayoutList();
60+
}
61+
#endif
62+
63+
serializedObject.ApplyModifiedProperties();
64+
65+
if (!(target as AudioInputSettings).isValid)
66+
EditorGUILayout.HelpBox("Incomplete/Invalid settings", MessageType.Warning);
67+
}
68+
}
69+
}

source/FrameRecorder/Inputs/Audio/Editor/AudioInputSettingsEditor.cs.meta

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/FrameRecorder/Inputs/Audio/Engine.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using System;
2+
#if UNITY_EDITOR
3+
using UnityEditor;
4+
using UnityEditorInternal;
5+
6+
#endif
7+
using UnityEngine.Collections;
8+
using UnityEngine.FrameRecorder.Input;
9+
10+
namespace UnityEngine.FrameRecorder
11+
{
12+
public class AudioInput : RecorderInput
13+
{
14+
private class BufferManager : IDisposable
15+
{
16+
NativeArray<float>[] buffers;
17+
uint m_Length;
18+
ushort m_ChannelCount;
19+
20+
public BufferManager(ushort numBuffers, uint length, ushort channelCount)
21+
{
22+
buffers = new NativeArray<float>[numBuffers];
23+
m_ChannelCount = channelCount;
24+
m_Length = length;
25+
}
26+
27+
public NativeArray<float> GetBuffer(int index)
28+
{
29+
if (buffers[index].Length == 0)
30+
buffers[index] = new NativeArray<float>(
31+
(int)m_Length * (int)m_ChannelCount, Allocator.Temp);
32+
return buffers[index];
33+
}
34+
35+
public void Dispose()
36+
{
37+
foreach (var a in buffers)
38+
a.Dispose();
39+
}
40+
}
41+
42+
public ushort channelCount { get { return m_ChannelCount; } }
43+
private ushort m_ChannelCount;
44+
public int sampleRate { get { return AudioSettings.outputSampleRate; } }
45+
public NativeArray<float> mainBuffer { get { return m_BufferManager.GetBuffer(0); } }
46+
public NativeArray<float> GetMixerGroupBuffer(int n)
47+
{ return m_BufferManager.GetBuffer(n + 1); }
48+
49+
private BufferManager m_BufferManager;
50+
51+
public AudioInputSettings audioSettings
52+
{ get { return (AudioInputSettings)settings; } }
53+
54+
public override void BeginRecording(RecordingSession session)
55+
{
56+
m_ChannelCount = new Func<ushort>(() => {
57+
switch (AudioSettings.speakerMode)
58+
{
59+
case AudioSpeakerMode.Mono: return 1;
60+
case AudioSpeakerMode.Stereo: return 2;
61+
case AudioSpeakerMode.Quad: return 4;
62+
case AudioSpeakerMode.Surround: return 5;
63+
case AudioSpeakerMode.Mode5point1: return 6;
64+
case AudioSpeakerMode.Mode7point1: return 7;
65+
case AudioSpeakerMode.Prologic: return 2;
66+
default: return 1;
67+
}
68+
})();
69+
70+
if (session.settings.m_Verbose)
71+
Debug.Log(string.Format(
72+
"AudioInput.BeginRecording for capture frame rate {0}", Time.captureFramerate));
73+
74+
if (audioSettings.m_PreserveAudio)
75+
AudioRecorder.StartOutputRecording();
76+
}
77+
78+
public override void NewFrameReady(RecordingSession session)
79+
{
80+
if (!audioSettings.m_PreserveAudio)
81+
return;
82+
83+
var sampleFrameCount = (uint)AudioRecorder.GetRecordSamplesAvailable();
84+
if (session.settings.m_Verbose)
85+
Debug.Log(string.Format("AudioInput.NewFrameReady {0} audio sample frames @ {1} ch",
86+
sampleFrameCount, m_ChannelCount));
87+
88+
ushort bufferCount =
89+
#if RECORD_AUDIO_MIXERS
90+
(ushort)(audioSettings.m_AudioMixerGroups.Length + 1)
91+
#else
92+
1
93+
#endif
94+
;
95+
96+
m_BufferManager = new BufferManager(bufferCount, sampleFrameCount, m_ChannelCount);
97+
var mainBuffer = m_BufferManager.GetBuffer(0);
98+
99+
#if RECORD_AUDIO_MIXERS
100+
for (int n = 1; n < bufferCount; n++)
101+
{
102+
var group = audioSettings.m_AudioMixerGroups[n - 1];
103+
if (group.m_MixerGroup == null)
104+
continue;
105+
106+
var buffer = m_BufferManager.GetBuffer(n);
107+
AudioRecorder.AddMixerGroupRecorder(group.m_MixerGroup, buffer, group.m_Isolate);
108+
}
109+
#endif
110+
111+
AudioRecorder.RecordOutput(mainBuffer);
112+
}
113+
114+
public override void FrameDone(RecordingSession session)
115+
{
116+
if (!audioSettings.m_PreserveAudio)
117+
return;
118+
119+
m_BufferManager.Dispose();
120+
m_BufferManager = null;
121+
}
122+
123+
public override void EndRecording(RecordingSession session)
124+
{
125+
if (audioSettings.m_PreserveAudio)
126+
AudioRecorder.StopOutputRecording();
127+
}
128+
}
129+
}
130+

source/FrameRecorder/Inputs/Audio/Engine/AudioInput.cs.meta

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using UnityEngine.Audio;
2+
3+
namespace UnityEngine.FrameRecorder.Input
4+
{
5+
public class AudioInputSettings : InputSettings<AudioInput>
6+
{
7+
public bool m_PreserveAudio = true;
8+
9+
#if RECORD_AUDIO_MIXERS
10+
[System.Serializable]
11+
public struct MixerGroupRecorderListItem
12+
{
13+
[SerializeField]
14+
public AudioMixerGroup m_MixerGroup;
15+
16+
[SerializeField]
17+
public bool m_Isolate;
18+
}
19+
public MixerGroupRecorderListItem[] m_AudioMixerGroups;
20+
#endif
21+
22+
public override bool isValid { get { return true; } }
23+
}
24+
}

source/FrameRecorder/Inputs/Audio/Engine/AudioInputSettings.cs.meta

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/FrameRecorder/Recorders/MediaRecorder.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/FrameRecorder/Recorders/MediaRecorder/Editor.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)