220 lines
7.8 KiB
C#
220 lines
7.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using JD.Audio.Annotations;
|
|
using JD.Audio.Sound;
|
|
using JD.Collections.Extensions;
|
|
using JD.Kernel.Classes;
|
|
using TeaBox;
|
|
|
|
namespace TempoBlaster.View
|
|
{
|
|
/// <summary>
|
|
/// Exports a json file according to after effect importer.
|
|
/// </summary>
|
|
public class ExportToAfterEffectFormatHandler : ExportToFileHandler
|
|
{
|
|
public string GetJsonContent(Wave wave, CustomJsomOptions customOpts = null )
|
|
{
|
|
return GetFileContent(wave, customOpts);
|
|
}
|
|
|
|
protected override string GetFileContent(Wave wave, CustomJsomOptions customJsonOptions = null )
|
|
{
|
|
var trkDocument = TeaBox.ObjectModel.Application.Main.Documents.OfType<TempoBlaster.Model.TrackDocument>().First();
|
|
var timeConverter = trkDocument.Wave.UnitConverter;
|
|
|
|
var writer = new JsonWriter();
|
|
|
|
using (writer.AppendBlock(breakLines: true))
|
|
{
|
|
writer.AppendProperty("VersionTRK", 1);
|
|
writer.AppendText(",\n");
|
|
|
|
writer.AppendProperty("VersionJSON", 1);
|
|
writer.AppendText(",\n");
|
|
|
|
writer.AppendProperty("VideoStartTime", wave.Annotations.VideoStartTime.TotalSeconds);
|
|
writer.AppendText(",\n");
|
|
|
|
writer.AppendProperty("BeatStart", wave.Annotations.StartBeat.Value);
|
|
writer.AppendText(",\n");
|
|
|
|
var nbBeats = (wave.Annotations.EndBeat - wave.Annotations.StartBeat).Value;
|
|
var endSecond = timeConverter.TimeFromBeat(wave.Annotations.EndBeat).TotalSeconds;
|
|
var startSecond = timeConverter.TimeFromBeat(wave.Annotations.StartBeat).TotalSeconds;
|
|
var bpm = nbBeats / ((endSecond - startSecond) / 60.0);
|
|
writer.AppendProperty("Bpm", bpm);
|
|
writer.AppendText(",\n");
|
|
|
|
writer.AppendProperty("MapFullLength", endSecond - startSecond);
|
|
writer.AppendText(",\n");
|
|
|
|
WriteCustomOptionsToJson(customJsonOptions, writer);
|
|
|
|
writer.AppendProperty("Markers");
|
|
using (writer.AppendBlock(breakLines: true))
|
|
{
|
|
writer.AppendProperty("Sections");
|
|
writer.AppendArray(wave.Annotations.SongSections, section => ToJson(wave, section, writer));
|
|
|
|
foreach (var group in wave.Annotations.Comments.GroupBy(comment => comment.Type))
|
|
{
|
|
writer.AppendText(",\n");
|
|
writer.AppendProperty(group.Key + "Comments");
|
|
writer.AppendArray(group, section => ToJson(wave, section, writer));
|
|
}
|
|
|
|
writer.AppendText(",\n");
|
|
writer.AppendProperty("Beats");
|
|
writer.AppendArray(wave.Annotations.Markers, marker => ToJson(marker, writer));
|
|
}
|
|
}
|
|
return writer.ToString();
|
|
}
|
|
|
|
private static void WriteCustomOptionsToJson(CustomJsomOptions customJsonOptions, JsonWriter writer)
|
|
{
|
|
customJsonOptions?.ForEach(entry =>
|
|
{
|
|
writer.AppendProperty(entry.Key, entry.Value);
|
|
writer.AppendText(",\n");
|
|
});
|
|
}
|
|
|
|
private void ToJson(Beat beat, JsonWriter writer)
|
|
{
|
|
using (writer.AppendBlock())
|
|
{
|
|
writer.AppendProperty("time", beat.Time.TotalSeconds);
|
|
writer.AppendText(", ");
|
|
writer.AppendProperty("comment", beat.Index.EntireValue, quoteValue: true);
|
|
}
|
|
}
|
|
|
|
private void ToJson(Wave wave, EditableAnnotation annotation, JsonWriter writer)
|
|
{
|
|
using (writer.AppendBlock())
|
|
{
|
|
writer.AppendProperty("time", wave.UnitConverter.TimeFromBeat(annotation.Time).TotalSeconds);
|
|
writer.AppendText(", ");
|
|
writer.AppendProperty("comment", annotation.Comment, quoteValue: true);
|
|
|
|
var songSection = annotation as SongSection;
|
|
if (songSection != null)
|
|
{
|
|
var color = songSection.Type.Color();
|
|
writer.AppendText(", ");
|
|
writer.AppendProperty("color", $"[{color.R}, {color.G}, {color.B}]");
|
|
|
|
writer.AppendText(", ");
|
|
writer.AppendProperty("type", songSection.Type, quoteValue: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override string Extension
|
|
{
|
|
get { return "json"; }
|
|
}
|
|
}
|
|
|
|
internal static class JSonExtensions
|
|
{
|
|
private static readonly char[] CharactersToEscape = new char[] { '\\', '"' };
|
|
private static readonly char[] WhitespaceCharacters = new char[] { '\n', '\t', '\r' };
|
|
|
|
public static string Quoted(this string value)
|
|
{
|
|
// Make sure the string value does not contain any "
|
|
if (value.IndexOfAny(CharactersToEscape) != -1)
|
|
{
|
|
foreach (var toEscape in CharactersToEscape)
|
|
{
|
|
value = value.Replace(toEscape.ToString(), @"\" + toEscape.ToString());
|
|
}
|
|
}
|
|
|
|
if (value.IndexOfAny(WhitespaceCharacters) != -1)
|
|
{
|
|
foreach (var specialCharacter in WhitespaceCharacters)
|
|
{
|
|
value = value.Replace(specialCharacter, ' ');
|
|
}
|
|
}
|
|
|
|
return "\"" + value + "\"";
|
|
}
|
|
|
|
public static void AppendText(this JsonWriter writer, string text)
|
|
{
|
|
for (var i = 0; i < writer.IndentationDepth; i++)
|
|
{
|
|
text = text.Replace("\n", "\n ");
|
|
}
|
|
writer.StringBuilder.Append(text);
|
|
}
|
|
|
|
public static void AppendArray<T>(this JsonWriter writer, IEnumerable<T> array, Action<T> writeValue)
|
|
{
|
|
using (writer.AppendBlock("[", "]", breakLines: true))
|
|
{
|
|
var toWrite = array.ToArray();
|
|
|
|
for (int i = 0; i < toWrite.Length; i++)
|
|
{
|
|
writeValue(toWrite[i]);
|
|
if (i != toWrite.Length - 1)
|
|
{
|
|
writer.AppendText(",\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void AppendProperty(this JsonWriter writer, string propertyName, object propertyValue = null, bool quoteValue = false)
|
|
{
|
|
writer.AppendText(propertyName.Quoted() + ":");
|
|
if (propertyValue != null)
|
|
{
|
|
string value = propertyValue.ToString();
|
|
if (quoteValue)
|
|
{
|
|
value = value.Quoted();
|
|
}
|
|
|
|
writer.AppendText(value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indent with a { } block
|
|
/// </summary>
|
|
public static IDisposable AppendBlock(this JsonWriter writer, string startChar = "{", string endChar = "}", bool breakLines = false)
|
|
{
|
|
if (breakLines)
|
|
{
|
|
startChar = startChar + "\n";
|
|
endChar = "\n" + endChar;
|
|
}
|
|
|
|
writer.IndentationDepth++;
|
|
writer.AppendText(startChar);
|
|
return new DisposableHelper(() => { writer.IndentationDepth--; writer.AppendText(endChar); });
|
|
}
|
|
}
|
|
|
|
internal class JsonWriter
|
|
{
|
|
private readonly StringBuilder _stringBuilder = new StringBuilder();
|
|
|
|
public StringBuilder StringBuilder { get { return _stringBuilder; } }
|
|
public int IndentationDepth { get; set; }
|
|
|
|
public override string ToString()
|
|
{
|
|
return StringBuilder.ToString();
|
|
}
|
|
}
|
|
}
|