Merge branch 'plugin_migration' into react_migration

This commit is contained in:
michalcourson
2026-02-22 13:11:40 -05:00
13 changed files with 258 additions and 60 deletions

View File

@ -16,7 +16,7 @@
{
"endTime": 30,
"filename": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\audio-service\\recordings\\audio_capture_20260220_193822.wav",
"name": "Pee pee poo poo",
"name": "Pee pee\npoo poo",
"playbackType": "playStop",
"startTime": 27.587412587412587,
"volume": 1

View File

@ -42,3 +42,12 @@ def recording_delete():
return jsonify({'status': 'success'})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 400
@recording_bp.route('/playback/start', methods=['POST'])
def playback_start():
print('HTTP: Starting audio playback')
try:
# os.remove(filename)
return jsonify({'status': 'success'})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 400

View File

@ -301,18 +301,15 @@ export default function AudioTrimmer({
>
<DialogTitle>Edit Clip Name</DialogTitle>
<DialogContent>
<input
// eslint-disable-next-line jsx-a11y/no-autofocus
<textarea
autoFocus
className="font-bold text-lg bg-transparent outline-none border-b border-plum focus:border-plumDark text-white mb-1 w-full text-center"
type="text"
className="font-bold text-lg bg-transparent outline-none border-b border-plum focus:border-plumDark text-white mb-1 w-full text-center resize-y"
value={nameInput}
onChange={(e) => setNameInput(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') handleDialogSave();
}}
rows={3}
onFocus={(event) => event.target.select()}
aria-label="Edit clip name"
style={{ minHeight: '3em' }}
/>
</DialogContent>
<DialogActions>

View File

@ -0,0 +1,42 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClipTrimDotNet.Client
{
public enum PlaybackType
{
playStop,
playOverlap
}
public class ClipMetadata
{
[JsonProperty(PropertyName = "filename")]
public string Filename { get; set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "volume")]
public double Volume { get; set; } = 1.0;
[JsonProperty(PropertyName = "startTime")]
public double StartTime { get; set; } = 0.0;
[JsonProperty(PropertyName = "endTime")]
public double EndTime { get; set; } = 0.0;
[JsonProperty(PropertyName = "playbackType")]
[JsonConverter(typeof(StringEnumConverter))]
public PlaybackType PlaybackType { get; set; } = PlaybackType.playStop;
}
}

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace ClipTrimDotNet.Client
{
public class ClipTrimClient
{
private static ClipTrimClient? instance;
public static ClipTrimClient Instance
{
get
{
if (instance == null)
{
instance = new ClipTrimClient();
}
return instance;
}
}
private HttpClient httpClient;
public ClipTrimClient()
{
httpClient = new HttpClient()
{
BaseAddress = new Uri("http://localhost:5010/"),
Timeout = TimeSpan.FromSeconds(10)
};
Task.Run(ShortPoll);
}
public async Task ShortPoll()
{
while (true)
{
await GetMetadata();
await Task.Delay(TimeSpan.FromSeconds(5)); await Task.Delay(TimeSpan.FromSeconds(5));
}
}
public List<CollectionMetaData> Collections { get; private set; } = new List<CollectionMetaData>();
public CollectionMetaData? SelectedCollection { get; private set; }
public int PageIndex { get; private set; } = 0;
private async Task GetMetadata()
{
try
{
var response = await httpClient.GetAsync("meta");
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
dynamic collections = JsonConvert.DeserializeObject(json);
collections = collections.collections;
Collections = JsonConvert.DeserializeObject<List<CollectionMetaData>>(collections.ToString());
}
}
catch (Exception ex)
{
//Logger.Instance.LogMessage(TracingLevel.INFO, $"Error pinging ClipTrim API: {ex.Message}");
return;
}
}
public List<string> GetCollectionNames()
{
//await GetMetadata();
return Collections.Select(x => x.Name).ToList();
}
public void SetSelectedCollectionByName(string name)
{
var collection = Collections.FirstOrDefault(x => x.Name == name);
if (collection != null)
{
SelectedCollection = collection;
PageIndex = 0;
}
}
public ClipMetadata? GetClipByPagedIndex(int index)
{
if (SelectedCollection == null) return null;
int clipIndex = PageIndex * 10 + index;
if (clipIndex >= 0 && clipIndex < SelectedCollection.Clips.Count)
{
return SelectedCollection.Clips[clipIndex];
}
return null;
}
public async void PlayClip(ClipMetadata? metadata)
{
if (metadata == null) return;
var response = await httpClient.PostAsync("playback/start", new StringContent(JsonConvert.SerializeObject(metadata), Encoding.UTF8, "application/json"));
if (!response.IsSuccessStatusCode)
{
//Logger.Instance.LogMessage(TracingLevel.INFO, $"Error playing clip: {response.ReasonPhrase}");
}
}
}
}

View File

@ -0,0 +1,23 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClipTrimDotNet.Client
{
public class CollectionMetaData
{
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "clips")]
public List<ClipMetadata> Clips { get; set; } = new List<ClipMetadata>();
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
}
}

View File

@ -13,6 +13,7 @@
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<Nullable>enable</Nullable>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -63,20 +64,20 @@
<HintPath>..\packages\NAudio.WinMM.2.2.1\lib\netstandard2.0\NAudio.WinMM.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.5.2.8\lib\net46\NLog.dll</HintPath>
<Reference Include="NLog, Version=6.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.6.0.5\lib\net46\NLog.dll</HintPath>
</Reference>
<Reference Include="StreamDeckTools, Version=6.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\StreamDeck-Tools.6.2.0\lib\netstandard2.0\StreamDeckTools.dll</HintPath>
<Reference Include="StreamDeckTools, Version=6.3.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\StreamDeck-Tools.6.3.2\lib\netstandard2.0\StreamDeckTools.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Drawing.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Drawing.Common.8.0.1\lib\net462\System.Drawing.Common.dll</HintPath>
<Reference Include="System.Drawing.Common, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Drawing.Common.9.0.10\lib\net462\System.Drawing.Common.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression" />
<Reference Include="System.Runtime.Serialization" />
@ -97,6 +98,9 @@
</ItemGroup>
<ItemGroup>
<Compile Include="BaseTest.cs" />
<Compile Include="Client\ClipMetadata.cs" />
<Compile Include="Client\ClipTrimClient.cs" />
<Compile Include="Client\CollectionMetaData.cs" />
<Compile Include="GlobalSettings.cs" />
<Compile Include="Player.cs" />
<Compile Include="ProfileSwitcher.cs" />
@ -150,8 +154,7 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>npm run stop
timeout /t 1 /nobreak</PreBuildEvent>
<PreBuildEvent>npm run stop</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>npm run start</PostBuildEvent>

View File

@ -1,5 +1,6 @@
using BarRaider.SdTools;
using BarRaider.SdTools.Wrappers;
using ClipTrimDotNet.Client;
using NAudio.CoreAudioApi.Interfaces;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -18,9 +19,8 @@ namespace ClipTrimDotNet
public class Player : KeypadBase
{
private TitleParameters? titleParameters = null;
private string userTitle;
private static int counter = 0;
private ClipMetadata? metadata;
private KeyCoordinates coordinates;
private class PluginSettings
{
public static PluginSettings CreateDefaultSettings()
@ -62,6 +62,7 @@ namespace ClipTrimDotNet
{
this.settings = payload.Settings.ToObject<PluginSettings>();
}
this.coordinates = payload.Coordinates;
GlobalSettingsManager.Instance.RequestGlobalSettings();
CheckFile();
}
@ -71,34 +72,43 @@ namespace ClipTrimDotNet
Tools.AutoPopulateSettings(GlobalSettings.Instance, e.Settings);
}
public int GetIndex()
{
return Math.Max((coordinates.Row - 1) * 5 + coordinates.Column, 0);
}
private async void CheckFile()
{
if (settings == null || GlobalSettings.Instance.BasePath == null || GlobalSettings.Instance.ProfileName ==null) return;
//if (settings == null || GlobalSettings.Instance.ProfileName ==null) return;
metadata = ClipTrimClient.Instance.GetClipByPagedIndex(GetIndex());
await Connection.SetTitleAsync($"{metadata?.Name ?? ""}");
var files = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(GlobalSettings.Instance.BasePath), GlobalSettings.Instance.ProfileName), "*.wav", SearchOption.TopDirectoryOnly)
.OrderBy(file => File.GetCreationTime(file))
.ToArray();
int? i = this.settings.Index;
string new_path = "";
if (i != null && i >= 0 && i < files.Length)
{
new_path = files[i ?? 0];
}
return;
//var files = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(GlobalSettings.Instance.BasePath), GlobalSettings.Instance.ProfileName), "*.wav", SearchOption.TopDirectoryOnly)
// .OrderBy(file => File.GetCreationTime(file))
// .ToArray();
//int? i = this.settings.Index;
//string new_path = "";
//if (i != null && i >= 0 && i < files.Length)
//{
// new_path = files[i ?? 0];
//}
await Connection.SetTitleAsync(Path.GetFileNameWithoutExtension(new_path));
if (new_path != settings.Path)
{
settings.Path = new_path;
if(new_path != "")
{
FileEntry opts = GlobalSettings.Instance.GetFileOptionsInCurrentProfile(new_path);
settings.Volume = opts.Volume;
settings.PlayType = opts.Playtype;
}
await SaveSettings();
}
//await Connection.SetTitleAsync(Path.GetFileNameWithoutExtension(new_path));
//if (new_path != settings.Path)
//{
// settings.Path = new_path;
// if(new_path != "")
// {
// FileEntry opts = GlobalSettings.Instance.GetFileOptionsInCurrentProfile(new_path);
// settings.Volume = opts.Volume;
// settings.PlayType = opts.Playtype;
// }
// await SaveSettings();
//}
}
@ -109,8 +119,8 @@ namespace ClipTrimDotNet
private void Connection_OnTitleParametersDidChange(object sender, SDEventReceivedEventArgs<BarRaider.SdTools.Events.TitleParametersDidChange> e)
{
titleParameters = e.Event?.Payload?.TitleParameters;
userTitle = e.Event?.Payload?.Title;
//titleParameters = e.Event?.Payload?.TitleParameters;
//userTitle = e.Event?.Payload?.Title;
}
public override void Dispose()
@ -124,15 +134,16 @@ namespace ClipTrimDotNet
{
//Logger.Instance.LogMessage(TracingLevel.INFO, "Key Pressedd");
Tools.AutoPopulateSettings(settings, payload.Settings);
// Logger.Instance.LogMessage(TracingLevel.INFO, JsonConvert.SerializeObject(settings));
try
{
WavPlayer.Instance.Play(settings.Path, GlobalSettings.Instance.OutputDevice, settings.Volume, settings.PlayType == "Play/Overlap" ? WavPlayer.PlayMode.PlayOverlap : WavPlayer.PlayMode.PlayStop);
}
catch
{
// Logger.Instance.LogMessage(TracingLevel.INFO, JsonConvert.SerializeObject(settings));
ClipTrimClient.Instance.PlayClip(metadata);
//try
//{
// WavPlayer.Instance.Play(settings.Path, GlobalSettings.Instance.OutputDevice, settings.Volume, settings.PlayType == "Play/Overlap" ? WavPlayer.PlayMode.PlayOverlap : WavPlayer.PlayMode.PlayStop);
//}
//catch
//{
}
//}
}

View File

@ -1,5 +1,6 @@
using BarRaider.SdTools;
using BarRaider.SdTools.Wrappers;
using ClipTrimDotNet.Client;
using NAudio.CoreAudioApi.Interfaces;
using NAudio.Wave;
using Newtonsoft.Json;
@ -60,7 +61,7 @@ namespace ClipTrimDotNet
private async void SetTitle()
{
await Connection.SetTitleAsync(settings.ProfileName);
await Connection.SetTitleAsync(settings.ProfileName + " A");
}
private async void Connection_OnSendToPlugin(object sender, SDEventReceivedEventArgs<BarRaider.SdTools.Events.SendToPlugin> e)
@ -68,8 +69,9 @@ namespace ClipTrimDotNet
//Logger.Instance.LogMessage(TracingLevel.INFO, "get profiles");
if (e.Event.Payload["event"].ToString() == "getProfiles")
{
string basePath = "C:\\Users\\mickl\\Music\\clips";
var files = Directory.GetDirectories(basePath, "*", SearchOption.TopDirectoryOnly).Select(x => Path.GetFileNameWithoutExtension(x)).Where(x => x != "original");
//string basePath = "C:\\Users\\mickl\\Music\\clips";
//var files = Directory.GetDirectories(basePath, "*", SearchOption.TopDirectoryOnly).Select(x => Path.GetFileNameWithoutExtension(x)).Where(x => x != "original");
var files = ClipTrimClient.Instance.GetCollectionNames();
var items = files.Select(x => new DataSourceItem { label = x, value = x});
var obj = new JObject();
obj["event"] = "getProfiles";
@ -110,6 +112,7 @@ namespace ClipTrimDotNet
//Logger.Instance.LogMessage(TracingLevel.INFO, "KeyPressed");
//Logger.Instance.LogMessage(TracingLevel.INFO, JsonConvert.SerializeObject(settings));
//Logger.Instance.LogMessage(TracingLevel.INFO, JsonConvert.SerializeObject(GlobalSettings.Instance));
ClipTrimClient.Instance.SetSelectedCollectionByName(settings.ProfileName);
GlobalSettings.Instance.SetCurrentProfile(settings.ProfileName);
Logger.Instance.LogMessage(TracingLevel.INFO, JsonConvert.SerializeObject(GlobalSettings.Instance));

View File

@ -9,10 +9,10 @@
<package id="NAudio.Wasapi" version="2.2.1" targetFramework="net48" />
<package id="NAudio.WinForms" version="2.2.1" targetFramework="net48" />
<package id="NAudio.WinMM" version="2.2.1" targetFramework="net48" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
<package id="NLog" version="5.2.8" targetFramework="net472" />
<package id="StreamDeck-Tools" version="6.2.0" targetFramework="net472" />
<package id="System.Drawing.Common" version="8.0.1" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net48" />
<package id="NLog" version="6.0.5" targetFramework="net48" />
<package id="StreamDeck-Tools" version="6.3.2" targetFramework="net48" />
<package id="System.Drawing.Common" version="9.0.10" targetFramework="net48" />
<package id="System.Security.AccessControl" version="4.7.0" targetFramework="net48" />
<package id="System.Security.Principal.Windows" version="4.7.0" targetFramework="net48" />
</packages>