301 lines
13 KiB
C#
301 lines
13 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using UnityEditor.Timeline;
|
||
using UnityEngine;
|
||
using UnityEngine.AddressableAssets;
|
||
using UnityEngine.Timeline;
|
||
using UnityEngine.Video;
|
||
|
||
namespace UnityEditor
|
||
{
|
||
[Serializable]
|
||
public class KeyCodeDefine
|
||
{
|
||
public KeyCode keyCode;
|
||
//public string audioName;
|
||
public int maxCount;
|
||
//public float duration;
|
||
[Tooltip("存在资源取资源名和时间")]
|
||
public AssetReferenceT<AudioClip> audioAsset;
|
||
}
|
||
[Serializable]
|
||
public class KeyCodeDefineStrint
|
||
{
|
||
public KeyCode keyCode;
|
||
//public string audioName;
|
||
public int maxCount;
|
||
//public float duration;
|
||
public string audioAsset;
|
||
}
|
||
[Serializable]
|
||
public class AudioDefine
|
||
{
|
||
public string audioName;
|
||
public int index;
|
||
public List<double> time = new List<double>();
|
||
}
|
||
[Serializable]
|
||
public class TimelineAudioDefine
|
||
{
|
||
[Tooltip("自动生成or手动修改")]
|
||
public List<AudioDefine> audioDefines = new List<AudioDefine>();
|
||
}
|
||
public class TimelineAudioEditor : EditorWindow
|
||
{
|
||
[MenuItem("Tools/Timeline Audio Editor", false, 120)]
|
||
public static void ShowWindow()
|
||
{
|
||
EditorWindow thisWindow = GetWindow(typeof(TimelineAudioEditor));
|
||
thisWindow.titleContent = new GUIContent("Timeline Audio Editor");
|
||
thisWindow.position = new Rect(Screen.width / 2, Screen.height / 2, 600, 800);
|
||
}
|
||
//视频播放编辑器
|
||
VideoPlayer videoPlayer;
|
||
GameObject videoPlayerGo;
|
||
VideoClip videoClip;
|
||
[Tooltip("按键==》音效name")]
|
||
public KeyCodeDefine[] keyCodeDefines = new KeyCodeDefine[1];
|
||
[Tooltip("自动生成or手动修改")]
|
||
public List<AudioDefine> audioDefines = new List<AudioDefine>();
|
||
[Tooltip("保存文件名")]
|
||
string saveJsonName;
|
||
[Tooltip("自动生成or手动选取读到上方列表然后修改")]
|
||
TextAsset jsonAsset;
|
||
string audioPath = "Assets/ABPackage/pkgFirstPackage/Audio/building/{0}.mp3";
|
||
TimelineAsset timelineAsset;
|
||
|
||
private SerializedObject serObj;
|
||
//private SerializedProperty videoClipPty;
|
||
private SerializedProperty gosPty;
|
||
private SerializedProperty audioDefinesPty;
|
||
//private SerializedProperty jsonAssetPty;
|
||
//private SerializedProperty timelineAssetPty;
|
||
|
||
|
||
//输出json文本
|
||
private string jsonText;
|
||
private string jsonPath = "Assets/Editor/VideoTool/{0}.json";
|
||
float sliderValue;
|
||
Vector2 scrollPosition;
|
||
private void OnEnable()
|
||
{
|
||
videoPlayerGo = new GameObject("VideoPlayer");
|
||
videoPlayer = videoPlayerGo.AddComponent<VideoPlayer>();
|
||
//切换场景
|
||
videoPlayer.playOnAwake = false;
|
||
videoPlayer.renderMode = VideoRenderMode.CameraNearPlane;
|
||
videoPlayer.targetCamera = videoPlayerGo.AddComponent<Camera>();
|
||
videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
|
||
videoPlayer.EnableAudioTrack(0, true);
|
||
videoPlayer.SetTargetAudioSource(0, videoPlayerGo.AddComponent<AudioSource>());
|
||
serObj = new SerializedObject(this);
|
||
//videoClipPty = serObj.FindProperty("videoClip");
|
||
gosPty = serObj.FindProperty("keyCodeDefines");
|
||
audioDefinesPty = serObj.FindProperty("audioDefines");
|
||
//jsonAssetPty = serObj.FindProperty("jsonAsset");
|
||
//timelineAssetPty = serObj.FindProperty("timelineAsset");
|
||
var keyCodeDefinesAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(string.Format(jsonPath, "keyCodeDefinesstring"));
|
||
if (keyCodeDefinesAsset != null)
|
||
{
|
||
KeyCodeDefineStrint[] keyCodeDefineStrints = Newtonsoft.Json.JsonConvert.DeserializeObject<KeyCodeDefineStrint[]>(keyCodeDefinesAsset.text);
|
||
keyCodeDefines = keyCodeDefineStrints.Select(c => new KeyCodeDefine() { keyCode = c.keyCode, maxCount = c.maxCount, audioAsset = new AssetReferenceT<AudioClip>(c.audioAsset) }).ToArray();
|
||
}
|
||
serObj.Update();
|
||
serObj.ApplyModifiedProperties();
|
||
}
|
||
|
||
void OnGUI()
|
||
{
|
||
Event e = Event.current;
|
||
if (e.type == EventType.KeyDown && e.keyCode == KeyCode.Space)
|
||
{
|
||
//停止所有输入框的输入
|
||
GUI.FocusControl(null);
|
||
if (videoPlayer.isPlaying)
|
||
{
|
||
videoPlayer.Pause();
|
||
}
|
||
else
|
||
{
|
||
videoPlayer.Play();
|
||
}
|
||
}
|
||
//视频剪辑
|
||
videoClip = EditorGUILayout.ObjectField("VideoClip", videoClip, typeof(VideoClip), false) as VideoClip;
|
||
//当videoClip修改时,将其赋值给videoPlayer.clip
|
||
//EditorGUILayout.PropertyField(videoClipPty, true);
|
||
if (videoClip != null)
|
||
{
|
||
videoPlayer.clip = videoClip;
|
||
if (!videoPlayer.isPlaying)
|
||
{
|
||
sliderValue = EditorGUILayout.Slider(sliderValue, 0, (float)videoClip.length);
|
||
//滑动条控制视频播放进度
|
||
videoPlayer.time = sliderValue;
|
||
}
|
||
else
|
||
{
|
||
sliderValue = (float)videoPlayer.time;
|
||
sliderValue = EditorGUILayout.Slider(sliderValue, 0, (float)videoClip.length);
|
||
}
|
||
}
|
||
|
||
// videoPlayer 可拖动进度条
|
||
|
||
//当点击keyCodeDefines.keyCode 记录视频播放时间
|
||
if (keyCodeDefines != null && e.type == EventType.KeyDown && videoPlayer.isPlaying)
|
||
{
|
||
var item = keyCodeDefines.FirstOrDefault(c => c.keyCode == e.keyCode);
|
||
if (item != null)
|
||
{
|
||
if (item.audioAsset.editorAsset != null)
|
||
{
|
||
string audioName = item.audioAsset.editorAsset.name;
|
||
float duration = item.audioAsset.editorAsset.length;
|
||
var curAudioDefines = audioDefines.Where(c => c.audioName == audioName).ToArray();
|
||
int index = curAudioDefines.Length;
|
||
|
||
var audioDefine = index < item.maxCount ? null : curAudioDefines[0];
|
||
foreach (var audioDefineItem in curAudioDefines)
|
||
{
|
||
if (audioDefineItem.time[^1] < videoPlayer.time - (double)duration)
|
||
{
|
||
audioDefine = audioDefineItem;
|
||
break;
|
||
}
|
||
}
|
||
if (audioDefine == null)
|
||
{
|
||
audioDefine = new AudioDefine() { audioName = audioName, index = index };
|
||
audioDefines.Add(audioDefine);
|
||
}
|
||
audioDefine.time.Add(videoPlayer.time);
|
||
//刷新timelinePty
|
||
serObj.Update();
|
||
SystemSoundsPlay();
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("音频不存在");
|
||
}
|
||
}
|
||
}
|
||
|
||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||
EditorGUILayout.PropertyField(gosPty, true);
|
||
saveJsonName = EditorGUILayout.TextField("SaveJsonName", saveJsonName);
|
||
EditorGUILayout.PropertyField(audioDefinesPty, true);
|
||
EditorGUILayout.EndScrollView();
|
||
serObj.ApplyModifiedProperties();
|
||
if (GUILayout.Button("Save"))
|
||
{
|
||
Save();
|
||
jsonAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(string.Format(jsonPath, saveJsonName));
|
||
serObj.Update();
|
||
}
|
||
if (GUILayout.Button("Read"))
|
||
{
|
||
if (jsonAsset != null)
|
||
{
|
||
jsonText = jsonAsset.text;
|
||
audioDefines = Newtonsoft.Json.JsonConvert.DeserializeObject<List<AudioDefine>>(jsonText);
|
||
serObj.Update();
|
||
}
|
||
}
|
||
jsonAsset = EditorGUILayout.ObjectField("JsonAsset", jsonAsset, typeof(TextAsset), false) as TextAsset;
|
||
//EditorGUILayout.PropertyField(jsonAssetPty, true);
|
||
if (GUILayout.Button("Change"))
|
||
{
|
||
if (jsonAsset != null)
|
||
{
|
||
jsonText = jsonAsset.text;
|
||
audioDefines = Newtonsoft.Json.JsonConvert.DeserializeObject<List<AudioDefine>>(jsonText);
|
||
//获取所有的音频轨道
|
||
var audioTracks = timelineAsset.GetOutputTracks().ToList();
|
||
//List<AudioDefine> audioDefines = audioDefines;
|
||
foreach (var item in audioDefines)
|
||
{
|
||
AudioTrack audioTrack = (AudioTrack)audioTracks.FirstOrDefault(c => c.name == item.audioName + item.index && c is AudioTrack);
|
||
if (audioTrack != null)
|
||
{
|
||
var audioClip = audioTrack.GetClips();
|
||
foreach (var clip in audioClip)
|
||
{
|
||
audioTrack.DeleteClip(clip);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
audioTrack = timelineAsset.CreateTrack<AudioTrack>(null, item.audioName + item.index);
|
||
}
|
||
foreach (var time in item.time)
|
||
{
|
||
//在time时间点创建一个音频片段
|
||
AudioClip audioClip1 = AssetDatabase.LoadAssetAtPath<AudioClip>(string.Format(audioPath, item.audioName));
|
||
if (audioClip1 != null)
|
||
{
|
||
var audioClip = audioTrack.CreateClip(audioClip1);
|
||
audioClip.start = time;
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("音频不存在:" + item.audioName);
|
||
}
|
||
}
|
||
}
|
||
EditorUtility.SetDirty(timelineAsset);
|
||
AssetDatabase.SaveAssets();
|
||
// Timeline窗口刷新
|
||
TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
|
||
}
|
||
}
|
||
audioPath = EditorGUILayout.TextField("AudioPath", audioPath);
|
||
timelineAsset = EditorGUILayout.ObjectField("TimelineAsset", timelineAsset, typeof(TimelineAsset), false) as TimelineAsset;
|
||
//EditorGUILayout.PropertyField(timelineAssetPty, true);
|
||
// 刷新界面
|
||
Repaint();
|
||
//按按钮响应各种系统提示音
|
||
//if (GUILayout.Button("Beep"))
|
||
//{
|
||
// System.Media.SystemSounds.Beep.Play();
|
||
//}
|
||
//if (GUILayout.Button("Asterisk"))
|
||
//{
|
||
// System.Media.SystemSounds.Asterisk.Play();
|
||
//}
|
||
//if (GUILayout.Button("Exclamation"))
|
||
//{
|
||
// System.Media.SystemSounds.Exclamation.Play();
|
||
//}
|
||
//if (GUILayout.Button("Hand"))
|
||
//{
|
||
// System.Media.SystemSounds.Hand.Play();
|
||
//}
|
||
//if (GUILayout.Button("Question"))
|
||
//{
|
||
// System.Media.SystemSounds.Question.Play();
|
||
//}
|
||
}
|
||
void SystemSoundsPlay()
|
||
{
|
||
System.Media.SystemSounds.Exclamation.Play();
|
||
}
|
||
void Save()
|
||
{
|
||
jsonText = Newtonsoft.Json.JsonConvert.SerializeObject(audioDefines);
|
||
string path = string.Format(jsonPath, saveJsonName);
|
||
System.IO.File.WriteAllText(path, jsonText);
|
||
KeyCodeDefineStrint[] keyCodeDefineStrints = keyCodeDefines.Select(c => new KeyCodeDefineStrint() { keyCode = c.keyCode, maxCount = c.maxCount, audioAsset = c.audioAsset.AssetGUID }).ToArray();
|
||
string keyCodeDefinesstring = Newtonsoft.Json.JsonConvert.SerializeObject(keyCodeDefineStrints);
|
||
path = string.Format(jsonPath, "keyCodeDefinesstring");
|
||
System.IO.File.WriteAllText(path, keyCodeDefinesstring);
|
||
AssetDatabase.Refresh();
|
||
}
|
||
private void OnDisable()
|
||
{
|
||
DestroyImmediate(videoPlayerGo);
|
||
}
|
||
}
|
||
}
|