-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAudioPreviewDocument.cs
More file actions
96 lines (84 loc) · 2.97 KB
/
AudioPreviewDocument.cs
File metadata and controls
96 lines (84 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System.IO;
namespace CFRezManager;
public sealed record AudioPreviewDocument(
string AudioName,
string AudioPath,
string? AudioInfo,
IReadOnlyList<string> TemporaryPaths,
string FormatLabel = "AUDIO");
internal static class AudioPreviewDocumentFactory
{
public const int MaxAudioPreviewBytes = 512 * 1024 * 1024;
public static bool TryCreate(
string fileName,
string? sourcePath,
byte[] data,
bool canUseSourcePath,
out AudioPreviewDocument? document,
out string? errorMessage)
{
document = null;
errorMessage = null;
byte[]? audioData = LzmaAloneDecoder.TryPrepareData(data, MaxAudioPreviewBytes);
if (audioData is null)
{
errorMessage = "Audio compression could not be decoded.";
return false;
}
if (!AudioMetadataDecoder.TryRead(audioData, fileName, out AudioMetadata metadata))
{
errorMessage = "Audio data is not a supported WAVE, MP3, or Ogg stream.";
return false;
}
var temporaryPaths = new List<string>();
string audioPath;
if (AudioMetadataDecoder.IsOggData(audioData))
{
string wavePath = CreateTemporaryAudioPath("wav");
if (!OggVorbisWaveDecoder.TryDecodeToWave(audioData, wavePath, out errorMessage))
{
TryDeleteFile(wavePath);
return false;
}
audioPath = wavePath;
temporaryPaths.Add(wavePath);
}
else if (canUseSourcePath && !string.IsNullOrWhiteSpace(sourcePath) && ReferenceEquals(audioData, data))
{
audioPath = sourcePath;
}
else
{
audioPath = CreateTemporaryAudioPath(metadata.PreferredExtension);
File.WriteAllBytes(audioPath, audioData);
temporaryPaths.Add(audioPath);
}
bool compressed = LzmaAloneDecoder.IsCompressed(data);
string storage = compressed
? $"LZMA-compressed {metadata.Container}, {data.Length:N0} bytes -> {audioData.Length:N0} bytes"
: $"{metadata.Container}, {data.Length:N0} bytes";
string info = $"{storage} - {metadata.Description}";
document = new AudioPreviewDocument(fileName, audioPath, info, temporaryPaths, metadata.Container.ToUpperInvariant());
return true;
}
public static bool IsWaveData(byte[] data)
{
return AudioMetadataDecoder.IsWaveData(data);
}
internal static string CreateTemporaryAudioPath(string extension)
{
string previewDirectory = Path.Combine(Path.GetTempPath(), "CFRezManager", "AudioPreview");
Directory.CreateDirectory(previewDirectory);
return Path.Combine(previewDirectory, $"{Guid.NewGuid():N}.{extension.TrimStart('.')}");
}
internal static void TryDeleteFile(string path)
{
try
{
File.Delete(path);
}
catch
{
}
}
}