diff --git a/stream_deck_plugin/.gitignore b/stream_deck_plugin/.gitignore
new file mode 100644
index 0000000..728bf9a
--- /dev/null
+++ b/stream_deck_plugin/.gitignore
@@ -0,0 +1,7 @@
+packages/
+*.log
+*.tmp
+ClipTrimDotNet/bin/
+ClipTrimDotNet/obj/
+ClipTrimDotNet/dist/
+ClipTrimDotNet/node_modules/
\ No newline at end of file
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/CopilotIndices/17.14.1431.25910/CodeChunks.db b/stream_deck_plugin/.vs/ClipTrimDotNet/CopilotIndices/17.14.1431.25910/CodeChunks.db
new file mode 100644
index 0000000..f9b7b51
Binary files /dev/null and b/stream_deck_plugin/.vs/ClipTrimDotNet/CopilotIndices/17.14.1431.25910/CodeChunks.db differ
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/CopilotIndices/17.14.1431.25910/SemanticSymbols.db b/stream_deck_plugin/.vs/ClipTrimDotNet/CopilotIndices/17.14.1431.25910/SemanticSymbols.db
new file mode 100644
index 0000000..c61eb71
Binary files /dev/null and b/stream_deck_plugin/.vs/ClipTrimDotNet/CopilotIndices/17.14.1431.25910/SemanticSymbols.db differ
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/21295af7-5d3b-4d32-9833-a3f5ca60df10.vsidx b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/21295af7-5d3b-4d32-9833-a3f5ca60df10.vsidx
new file mode 100644
index 0000000..5e80e32
Binary files /dev/null and b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/21295af7-5d3b-4d32-9833-a3f5ca60df10.vsidx differ
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/298d1b91-00fc-43f4-b254-bc10321ae63d.vsidx b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/298d1b91-00fc-43f4-b254-bc10321ae63d.vsidx
new file mode 100644
index 0000000..84bccf8
Binary files /dev/null and b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/298d1b91-00fc-43f4-b254-bc10321ae63d.vsidx differ
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/2f52a0fc-cf0c-40ec-b60f-31babb5d2447.vsidx b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/2f52a0fc-cf0c-40ec-b60f-31babb5d2447.vsidx
new file mode 100644
index 0000000..a7ab071
Binary files /dev/null and b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/2f52a0fc-cf0c-40ec-b60f-31babb5d2447.vsidx differ
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/6f1a9052-dd3b-4187-b3d0-5afd6bae4e3b.vsidx b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/6f1a9052-dd3b-4187-b3d0-5afd6bae4e3b.vsidx
new file mode 100644
index 0000000..8afcdce
Binary files /dev/null and b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/6f1a9052-dd3b-4187-b3d0-5afd6bae4e3b.vsidx differ
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/a8dad959-ac64-4736-bdc5-471e07fae227.vsidx b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/a8dad959-ac64-4736-bdc5-471e07fae227.vsidx
new file mode 100644
index 0000000..10eab9d
Binary files /dev/null and b/stream_deck_plugin/.vs/ClipTrimDotNet/FileContentIndex/a8dad959-ac64-4736-bdc5-471e07fae227.vsidx differ
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/config/applicationhost.config b/stream_deck_plugin/.vs/ClipTrimDotNet/config/applicationhost.config
new file mode 100644
index 0000000..cdd2df8
--- /dev/null
+++ b/stream_deck_plugin/.vs/ClipTrimDotNet/config/applicationhost.config
@@ -0,0 +1,1026 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/v17/.suo b/stream_deck_plugin/.vs/ClipTrimDotNet/v17/.suo
new file mode 100644
index 0000000..8c8c5a5
Binary files /dev/null and b/stream_deck_plugin/.vs/ClipTrimDotNet/v17/.suo differ
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/v17/DocumentLayout.backup.json b/stream_deck_plugin/.vs/ClipTrimDotNet/v17/DocumentLayout.backup.json
new file mode 100644
index 0000000..41e7b31
--- /dev/null
+++ b/stream_deck_plugin/.vs/ClipTrimDotNet/v17/DocumentLayout.backup.json
@@ -0,0 +1,271 @@
+{
+ "Version": 1,
+ "WorkspaceRootPath": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\",
+ "Documents": [
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\profileswitcher.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\profileswitcher.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\wavplayer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\wavplayer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\player.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\player.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|c:\\users\\mickl\\source\\repos\\cliptrimdotnet\\cliptrimdotnet\\manifest.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\manifest.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\package.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\package.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\globalsettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\globalsettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{00000000-0000-0000-0000-000000000000}|\u003CSolution\u003E|ClipTrimDotNet||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\packages.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\packages.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\basetest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\basetest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\properties\\assemblyinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\properties\\assemblyinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\propertyinspector\\file_player.html||{40D31677-CBC0-4297-A9EF-89D907823A98}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\propertyinspector\\file_player.html||{40D31677-CBC0-4297-A9EF-89D907823A98}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\propertyinspector\\profile_swticher.html||{40D31677-CBC0-4297-A9EF-89D907823A98}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\propertyinspector\\profile_swticher.html||{40D31677-CBC0-4297-A9EF-89D907823A98}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\app.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\app.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\cliptrimdotnet\\!!readme!!.txt||{8B382828-6202-11D1-8870-0000F87579D2}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\!!readme!!.txt||{8B382828-6202-11D1-8870-0000F87579D2}"
+ }
+ ],
+ "DocumentGroupContainers": [
+ {
+ "Orientation": 0,
+ "VerticalTabListWidth": 256,
+ "DocumentGroups": [
+ {
+ "DockedWidth": 297,
+ "SelectedChildIndex": 3,
+ "Children": [
+ {
+ "$type": "Bookmark",
+ "Name": "ST:0:0:{57d563b6-44a5-47df-85be-f4199ad6b651}"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 3,
+ "Title": "manifest.json",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\manifest.json",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\manifest.json",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\manifest.json",
+ "RelativeToolTip": "ClipTrimDotNet\\manifest.json",
+ "ViewState": "AgIAAA8AAAAAAAAAAAAAABUAAAARAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
+ "WhenOpened": "2025-01-07T22:25:36.017Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Bookmark",
+ "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 0,
+ "Title": "ProfileSwitcher.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\ProfileSwitcher.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\ProfileSwitcher.cs",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\ProfileSwitcher.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\ProfileSwitcher.cs",
+ "ViewState": "AgIAAHMAAAAAAAAAAAAAAHMAAABhAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-07T22:30:21.707Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 2,
+ "Title": "Player.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\Player.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\Player.cs",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\Player.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\Player.cs",
+ "ViewState": "AgIAAGYAAAAAAAAAAAAYwIEAAAAiAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-07T22:30:17.917Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 5,
+ "Title": "GlobalSettings.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\GlobalSettings.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\GlobalSettings.cs",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\GlobalSettings.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\GlobalSettings.cs",
+ "ViewState": "AQIAAEcAAAAAAAAAAAAAwGQAAAANAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-08T00:01:58.381Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 4,
+ "Title": "package.json",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\package.json",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\package.json",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\package.json",
+ "RelativeToolTip": "ClipTrimDotNet\\package.json",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAA4AAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
+ "WhenOpened": "2025-01-08T02:08:12.8Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 1,
+ "Title": "WavPlayer.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\WavPlayer.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\WavPlayer.cs",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\WavPlayer.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\WavPlayer.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-08T01:15:28.724Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 6,
+ "Title": "Program.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\Program.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\Program.cs",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\Program.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\Program.cs",
+ "ViewState": "AQIAAAMAAAAAAAAAAAAAAA4AAABlAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-07T23:57:50.996Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 11,
+ "Title": "file_player.html",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\PropertyInspector\\file_player.html",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\PropertyInspector\\file_player.html",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\PropertyInspector\\file_player.html",
+ "RelativeToolTip": "ClipTrimDotNet\\PropertyInspector\\file_player.html",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAACYAAAAQAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001512|",
+ "WhenOpened": "2025-01-07T22:27:38.985Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 12,
+ "Title": "profile_swticher.html",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\PropertyInspector\\profile_swticher.html",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\PropertyInspector\\profile_swticher.html",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\PropertyInspector\\profile_swticher.html",
+ "RelativeToolTip": "ClipTrimDotNet\\PropertyInspector\\profile_swticher.html",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAABwAAAAxAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001512|",
+ "WhenOpened": "2025-01-07T22:28:04.751Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 8,
+ "Title": "packages.config",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\packages.config",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\packages.config",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\packages.config",
+ "RelativeToolTip": "ClipTrimDotNet\\packages.config",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000601|",
+ "WhenOpened": "2025-01-08T21:38:49.029Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 7,
+ "Title": "ClipTrimDotNet",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\ClipTrimDotNet.csproj",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\ClipTrimDotNet.csproj",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\ClipTrimDotNet.csproj",
+ "RelativeToolTip": "ClipTrimDotNet\\ClipTrimDotNet.csproj",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|",
+ "WhenOpened": "2025-01-08T00:06:38.575Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 9,
+ "Title": "BaseTest.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\BaseTest.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\BaseTest.cs",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\BaseTest.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\BaseTest.cs",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-08T00:39:45.341Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 13,
+ "Title": "App.config",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\App.config",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\App.config",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\App.config",
+ "RelativeToolTip": "ClipTrimDotNet\\App.config",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAABYAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000601|",
+ "WhenOpened": "2025-01-08T00:13:00.841Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 10,
+ "Title": "AssemblyInfo.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\Properties\\AssemblyInfo.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\Properties\\AssemblyInfo.cs",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\Properties\\AssemblyInfo.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\Properties\\AssemblyInfo.cs",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-08T00:12:33.926Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 14,
+ "Title": "!!README!!.txt",
+ "DocumentMoniker": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\!!README!!.txt",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\!!README!!.txt",
+ "ToolTip": "C:\\Users\\mickl\\source\\repos\\ClipTrimDotNet\\ClipTrimDotNet\\!!README!!.txt",
+ "RelativeToolTip": "ClipTrimDotNet\\!!README!!.txt",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAA4AAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|",
+ "WhenOpened": "2025-01-07T22:31:00.77Z"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/stream_deck_plugin/.vs/ClipTrimDotNet/v17/DocumentLayout.json b/stream_deck_plugin/.vs/ClipTrimDotNet/v17/DocumentLayout.json
new file mode 100644
index 0000000..6ab4293
--- /dev/null
+++ b/stream_deck_plugin/.vs/ClipTrimDotNet/v17/DocumentLayout.json
@@ -0,0 +1,271 @@
+{
+ "Version": 1,
+ "WorkspaceRootPath": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\",
+ "Documents": [
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|c:\\users\\mickl\\desktop\\cliptrim-ui\\cliptrimapp\\stream_deck_plugin\\cliptrimdotnet\\profileswitcher.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\profileswitcher.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\wavplayer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\wavplayer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\player.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\player.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\manifest.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\manifest.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\package.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\package.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\globalsettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\globalsettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{00000000-0000-0000-0000-000000000000}|\u003CSolution\u003E|ClipTrimDotNet||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\packages.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\packages.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\basetest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\basetest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\properties\\assemblyinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\properties\\assemblyinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\propertyinspector\\file_player.html||{40D31677-CBC0-4297-A9EF-89D907823A98}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\propertyinspector\\file_player.html||{40D31677-CBC0-4297-A9EF-89D907823A98}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\propertyinspector\\profile_swticher.html||{40D31677-CBC0-4297-A9EF-89D907823A98}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\propertyinspector\\profile_swticher.html||{40D31677-CBC0-4297-A9EF-89D907823A98}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\app.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\app.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\cliptrimdotnet\\!!readme!!.txt||{8B382828-6202-11D1-8870-0000F87579D2}",
+ "RelativeMoniker": "D:0:0:{4635D874-69C0-4010-BE46-77EF92EB1553}|ClipTrimDotNet\\ClipTrimDotNet.csproj|solutionrelative:cliptrimdotnet\\!!readme!!.txt||{8B382828-6202-11D1-8870-0000F87579D2}"
+ }
+ ],
+ "DocumentGroupContainers": [
+ {
+ "Orientation": 0,
+ "VerticalTabListWidth": 256,
+ "DocumentGroups": [
+ {
+ "DockedWidth": 297,
+ "SelectedChildIndex": 4,
+ "Children": [
+ {
+ "$type": "Bookmark",
+ "Name": "ST:0:0:{57d563b6-44a5-47df-85be-f4199ad6b651}"
+ },
+ {
+ "$type": "Bookmark",
+ "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
+ },
+ {
+ "$type": "Bookmark",
+ "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 3,
+ "Title": "manifest.json",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\manifest.json",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\manifest.json",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\manifest.json",
+ "RelativeToolTip": "ClipTrimDotNet\\manifest.json",
+ "ViewState": "AgIAAA8AAAAAAAAAAAAAABUAAAARAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
+ "WhenOpened": "2025-01-07T22:25:36.017Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 0,
+ "Title": "ProfileSwitcher.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\ProfileSwitcher.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\ProfileSwitcher.cs",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\ProfileSwitcher.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\ProfileSwitcher.cs",
+ "ViewState": "AgIAAFcAAAAAAAAAAAAgwF8AAAAJAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-07T22:30:21.707Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 2,
+ "Title": "Player.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\Player.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\Player.cs",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\Player.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\Player.cs",
+ "ViewState": "AgIAAGYAAAAAAAAAAAAYwIEAAAAiAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-07T22:30:17.917Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 5,
+ "Title": "GlobalSettings.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\GlobalSettings.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\GlobalSettings.cs",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\GlobalSettings.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\GlobalSettings.cs",
+ "ViewState": "AQIAAEcAAAAAAAAAAAAAwGQAAAANAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-08T00:01:58.381Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 4,
+ "Title": "package.json",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\package.json",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\package.json",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\package.json",
+ "RelativeToolTip": "ClipTrimDotNet\\package.json",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAA4AAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
+ "WhenOpened": "2025-01-08T02:08:12.8Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 1,
+ "Title": "WavPlayer.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\WavPlayer.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\WavPlayer.cs",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\WavPlayer.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\WavPlayer.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-08T01:15:28.724Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 6,
+ "Title": "Program.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\Program.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\Program.cs",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\Program.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\Program.cs",
+ "ViewState": "AQIAAAMAAAAAAAAAAAAAAA4AAABlAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-07T23:57:50.996Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 11,
+ "Title": "file_player.html",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\PropertyInspector\\file_player.html",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\PropertyInspector\\file_player.html",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\PropertyInspector\\file_player.html",
+ "RelativeToolTip": "ClipTrimDotNet\\PropertyInspector\\file_player.html",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAACYAAAAQAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001512|",
+ "WhenOpened": "2025-01-07T22:27:38.985Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 12,
+ "Title": "profile_swticher.html",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\PropertyInspector\\profile_swticher.html",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\PropertyInspector\\profile_swticher.html",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\PropertyInspector\\profile_swticher.html",
+ "RelativeToolTip": "ClipTrimDotNet\\PropertyInspector\\profile_swticher.html",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAABwAAAAxAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001512|",
+ "WhenOpened": "2025-01-07T22:28:04.751Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 8,
+ "Title": "packages.config",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\packages.config",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\packages.config",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\packages.config",
+ "RelativeToolTip": "ClipTrimDotNet\\packages.config",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000601|",
+ "WhenOpened": "2025-01-08T21:38:49.029Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 7,
+ "Title": "ClipTrimDotNet",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\ClipTrimDotNet.csproj",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\ClipTrimDotNet.csproj",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\ClipTrimDotNet.csproj",
+ "RelativeToolTip": "ClipTrimDotNet\\ClipTrimDotNet.csproj",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|",
+ "WhenOpened": "2025-01-08T00:06:38.575Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 9,
+ "Title": "BaseTest.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\BaseTest.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\BaseTest.cs",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\BaseTest.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\BaseTest.cs",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-08T00:39:45.341Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 13,
+ "Title": "App.config",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\App.config",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\App.config",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\App.config",
+ "RelativeToolTip": "ClipTrimDotNet\\App.config",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAABYAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000601|",
+ "WhenOpened": "2025-01-08T00:13:00.841Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 10,
+ "Title": "AssemblyInfo.cs",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\Properties\\AssemblyInfo.cs",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\Properties\\AssemblyInfo.cs",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\Properties\\AssemblyInfo.cs",
+ "RelativeToolTip": "ClipTrimDotNet\\Properties\\AssemblyInfo.cs",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-01-08T00:12:33.926Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 14,
+ "Title": "!!README!!.txt",
+ "DocumentMoniker": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\!!README!!.txt",
+ "RelativeDocumentMoniker": "ClipTrimDotNet\\!!README!!.txt",
+ "ToolTip": "C:\\Users\\mickl\\Desktop\\cliptrim-ui\\ClipTrimApp\\stream_deck_plugin\\ClipTrimDotNet\\!!README!!.txt",
+ "RelativeToolTip": "ClipTrimDotNet\\!!README!!.txt",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAAA4AAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|",
+ "WhenOpened": "2025-01-07T22:31:00.77Z"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/stream_deck_plugin/ClipTrimDotNet.sln b/stream_deck_plugin/ClipTrimDotNet.sln
new file mode 100644
index 0000000..a71fcb9
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34330.188
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClipTrimDotNet", "ClipTrimDotNet\ClipTrimDotNet.csproj", "{4635D874-69C0-4010-BE46-77EF92EB1553}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4635D874-69C0-4010-BE46-77EF92EB1553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4635D874-69C0-4010-BE46-77EF92EB1553}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4635D874-69C0-4010-BE46-77EF92EB1553}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4635D874-69C0-4010-BE46-77EF92EB1553}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {926C6896-F36A-4F3B-A9DD-CA3AA48AD99F}
+ EndGlobalSection
+EndGlobal
diff --git a/stream_deck_plugin/ClipTrimDotNet/!!README!!.txt b/stream_deck_plugin/ClipTrimDotNet/!!README!!.txt
new file mode 100644
index 0000000..b6e1b33
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/!!README!!.txt
@@ -0,0 +1,14 @@
+To use:
+1. Right click the project and choose "Manage Nuget Packages"
+2. Choose the restore option in the Nuget screen (or just install the latest StreamDeck-Tools from Nuget)
+3. Update the manifest.json file with the correct details about your plugin
+4. Modify PluginAction.cs as needed (it holds the logic for your plugin)
+5. Modify the PropertyInspector\PluginActionPI.html and PropertyInspector\PluginActionPI.js as needed to show field in the Property Inspector
+6. Before releasing, change the Assembly Information (Right click the project -> Properties -> Application -> Assembly Information...)
+
+For help with StreamDeck-Tools:
+ Discord Server: http://discord.barraider.com
+Resources:
+* StreamDeck-Tools samples and tutorial: https://github.com/BarRaider/streamdeck-tools
+* EasyPI library (for working with Property Inspector): https://github.com/BarRaider/streamdeck-easypi
+
diff --git a/stream_deck_plugin/ClipTrimDotNet/App.config b/stream_deck_plugin/ClipTrimDotNet/App.config
new file mode 100644
index 0000000..e9d06ee
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/App.config
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stream_deck_plugin/ClipTrimDotNet/BaseTest.cs b/stream_deck_plugin/ClipTrimDotNet/BaseTest.cs
new file mode 100644
index 0000000..e02abfc
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/BaseTest.cs
@@ -0,0 +1 @@
+
diff --git a/stream_deck_plugin/ClipTrimDotNet/ClipTrimDotNet.csproj b/stream_deck_plugin/ClipTrimDotNet/ClipTrimDotNet.csproj
new file mode 100644
index 0000000..d485dce
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/ClipTrimDotNet.csproj
@@ -0,0 +1,159 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {4635D874-69C0-4010-BE46-77EF92EB1553}
+ Exe
+ ClipTrimDotNet
+ ClipTrimDotNet
+ v4.8
+ 8
+ 512
+ true
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\com.michal-courson.cliptrim.sdPlugin\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\ClipTrimDotNet.sdPlugin\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\CommandLineParser.2.9.1\lib\net461\CommandLine.dll
+
+
+ ..\packages\Microsoft.Win32.Registry.4.7.0\lib\net461\Microsoft.Win32.Registry.dll
+
+
+ ..\packages\NAudio.2.2.1\lib\net472\NAudio.dll
+
+
+ ..\packages\NAudio.Asio.2.2.1\lib\netstandard2.0\NAudio.Asio.dll
+
+
+ ..\packages\NAudio.Core.2.2.1\lib\netstandard2.0\NAudio.Core.dll
+
+
+ ..\packages\NAudio.Midi.2.2.1\lib\netstandard2.0\NAudio.Midi.dll
+
+
+ ..\packages\NAudio.Wasapi.2.2.1\lib\netstandard2.0\NAudio.Wasapi.dll
+
+
+ ..\packages\NAudio.WinForms.2.2.1\lib\net472\NAudio.WinForms.dll
+
+
+ ..\packages\NAudio.WinMM.2.2.1\lib\netstandard2.0\NAudio.WinMM.dll
+
+
+ ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\packages\NLog.5.2.8\lib\net46\NLog.dll
+
+
+ ..\packages\StreamDeck-Tools.6.2.0\lib\netstandard2.0\StreamDeckTools.dll
+
+
+
+
+
+
+ ..\packages\System.Drawing.Common.8.0.1\lib\net462\System.Drawing.Common.dll
+
+
+
+
+ ..\packages\System.Security.AccessControl.4.7.0\lib\net461\System.Security.AccessControl.dll
+
+
+ ..\packages\System.Security.Principal.Windows.4.7.0\lib\net461\System.Security.Principal.Windows.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
+ npm run stop
+timeout /t 1 /nobreak
+
+
+ npm run start
+
+
\ No newline at end of file
diff --git a/stream_deck_plugin/ClipTrimDotNet/ClipTrimDotNet.csproj.user b/stream_deck_plugin/ClipTrimDotNet/ClipTrimDotNet.csproj.user
new file mode 100644
index 0000000..48d700b
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/ClipTrimDotNet.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ --port 23654 --pluginUUID com.michal-courson.cliptrim --registerEvent restart --info {}
+
+
\ No newline at end of file
diff --git a/stream_deck_plugin/ClipTrimDotNet/DialLayout.json b/stream_deck_plugin/ClipTrimDotNet/DialLayout.json
new file mode 100644
index 0000000..014c4e1
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/DialLayout.json
@@ -0,0 +1,40 @@
+{
+ "id": "sampleDial",
+ "items": [
+ {
+ "key": "title",
+ "type": "text",
+ "rect": [ 16, 10, 136, 24 ],
+ "font": {
+ "size": 16,
+ "weight": 600
+ },
+ "alignment": "left"
+ },
+ {
+ "key": "icon",
+ "type": "pixmap",
+ "rect": [ 16, 40, 48, 48 ]
+ },
+ {
+ "key": "value",
+ "type": "text",
+ "rect": [ 76, 40, 108, 32 ],
+ "font": {
+ "size": 24,
+ "weight": 600
+ },
+ "alignment": "right"
+ },
+ {
+ "key": "indicator",
+ "type": "gbar",
+ "rect": [ 76, 74, 108, 20 ],
+ "value": 0,
+ "subtype": 4,
+ "bar_h": 12,
+ "border_w": 0,
+ "bar_bg_c": "0:#427018,0.75:#705B1C,0.90:#702735,1:#702735"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/stream_deck_plugin/ClipTrimDotNet/GlobalSettings.cs b/stream_deck_plugin/ClipTrimDotNet/GlobalSettings.cs
new file mode 100644
index 0000000..07c3646
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/GlobalSettings.cs
@@ -0,0 +1,109 @@
+using BarRaider.SdTools;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using BarRaider.SdTools.Wrappers;
+using Newtonsoft.Json.Linq;
+using NAudio.MediaFoundation;
+
+namespace ClipTrimDotNet
+{
+ public class FileEntry
+ {
+ public FileEntry()
+ {
+ Volume = 1.0;
+ Playtype = "Play/Overlap";
+ }
+ [JsonProperty(PropertyName = "Volume")]
+ public double Volume { get; set; }
+ [JsonProperty(PropertyName = "Playtype")]
+ public string Playtype { get; set; }
+ }
+ public class CollectionEntry
+ {
+ public CollectionEntry()
+ {
+ Files = new Dictionary();
+ }
+ [JsonProperty(PropertyName = "Files")]
+ public Dictionary Files { get; set; }
+ }
+
+ public class GlobalSettings
+ {
+ public static GlobalSettings? _inst;
+ public static GlobalSettings Instance
+ {
+ get
+ {
+ _inst ??= CreateDefaultSettings();
+ return _inst;
+ }
+ set
+ {
+ _inst = value;
+ }
+ }
+ public static GlobalSettings CreateDefaultSettings()
+ {
+ GlobalSettings instance = new GlobalSettings();
+ instance.BasePath = null;
+ instance.ProfileName = null;
+ instance.Collections = new Dictionary();
+ return instance;
+ }
+
+
+ [FilenameProperty]
+ [JsonProperty(PropertyName = "basePath")]
+ public string? BasePath { get; set; }
+
+ [JsonProperty(PropertyName = "profileName")]
+ public string? ProfileName { get; set; }
+
+ [JsonProperty(PropertyName = "outputDevice")]
+ public string? OutputDevice { get; set; }
+
+ [JsonProperty(PropertyName = "collections")]
+ public Dictionary Collections { get; set; }
+
+ public void SetCurrentProfile(string profile)
+ {
+ ProfileName = profile;
+ if(!Collections.ContainsKey(profile))
+ {
+ Collections.Add(profile, new CollectionEntry());
+ }
+ }
+
+ public FileEntry GetFileOptionsInCurrentProfile(string filename)
+ {
+ if(!Collections.TryGetValue(ProfileName, out CollectionEntry collection))
+ {
+ return new FileEntry();
+ }
+ if(!collection.Files.TryGetValue(filename, out FileEntry file))
+ {
+ return new FileEntry();
+ }
+ Logger.Instance.LogMessage(TracingLevel.INFO, "fetched file settings " + filename + JsonConvert.SerializeObject(file));
+ return file;
+ }
+
+ public void SetFileOptionsCurrentProfile(string filename, FileEntry file)
+ {
+ Logger.Instance.LogMessage(TracingLevel.INFO, "SetFileOptionsCurrentProfile ");
+ if (!Collections.TryGetValue(ProfileName, out CollectionEntry collection))
+ {
+ return;
+ }
+ Logger.Instance.LogMessage(TracingLevel.INFO, "SetFileOptionsCurrentProfile 2");
+ //collection.Files[filename] = file;
+ Collections[ProfileName].Files[filename] = file;
+ }
+ }
+}
diff --git a/stream_deck_plugin/ClipTrimDotNet/Images/categoryIcon.png b/stream_deck_plugin/ClipTrimDotNet/Images/categoryIcon.png
new file mode 100644
index 0000000..c864463
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/Images/categoryIcon.png differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/Images/categoryIcon@2x.png b/stream_deck_plugin/ClipTrimDotNet/Images/categoryIcon@2x.png
new file mode 100644
index 0000000..88f7532
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/Images/categoryIcon@2x.png differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/Images/icon.png b/stream_deck_plugin/ClipTrimDotNet/Images/icon.png
new file mode 100644
index 0000000..282cc46
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/Images/icon.png differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/Images/icon@2x.png b/stream_deck_plugin/ClipTrimDotNet/Images/icon@2x.png
new file mode 100644
index 0000000..580d504
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/Images/icon@2x.png differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/Images/off_save.png b/stream_deck_plugin/ClipTrimDotNet/Images/off_save.png
new file mode 100644
index 0000000..1667313
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/Images/off_save.png differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/Images/pluginAction.png b/stream_deck_plugin/ClipTrimDotNet/Images/pluginAction.png
new file mode 100644
index 0000000..6f9dea4
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/Images/pluginAction.png differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/Images/pluginAction@2x.png b/stream_deck_plugin/ClipTrimDotNet/Images/pluginAction@2x.png
new file mode 100644
index 0000000..8f9d3d6
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/Images/pluginAction@2x.png differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/Images/pluginIcon.png b/stream_deck_plugin/ClipTrimDotNet/Images/pluginIcon.png
new file mode 100644
index 0000000..c864463
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/Images/pluginIcon.png differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/Images/pluginIcon@2x.png b/stream_deck_plugin/ClipTrimDotNet/Images/pluginIcon@2x.png
new file mode 100644
index 0000000..e98ca7c
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/Images/pluginIcon@2x.png differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/Player.cs b/stream_deck_plugin/ClipTrimDotNet/Player.cs
new file mode 100644
index 0000000..bec8efc
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/Player.cs
@@ -0,0 +1,182 @@
+using BarRaider.SdTools;
+using BarRaider.SdTools.Wrappers;
+using NAudio.CoreAudioApi.Interfaces;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Dynamic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ClipTrimDotNet
+{
+ [PluginActionId("com.michal-courson.cliptrim.player")]
+ public class Player : KeypadBase
+ {
+
+ private TitleParameters? titleParameters = null;
+ private string userTitle;
+ private static int counter = 0;
+ private class PluginSettings
+ {
+ public static PluginSettings CreateDefaultSettings()
+ {
+ PluginSettings instance = new PluginSettings();
+ instance.Path = null;
+ instance.PlayType = "Play/Overlap";
+ instance.Index = 0;
+ instance.Volume = 1;
+ return instance;
+ }
+
+ [FilenameProperty]
+ [JsonProperty(PropertyName = "path")]
+ public string? Path { get; set; }
+
+ [JsonProperty(PropertyName = "index")]
+ public int? Index { get; set; }
+ [JsonProperty(PropertyName = "playtype")]
+ public string PlayType { get; set; }
+
+ [JsonProperty(PropertyName = "volume")]
+ public double Volume { get; set; }
+ }
+
+ #region Private Members
+
+ private PluginSettings settings;
+
+ #endregion
+ public Player(SDConnection connection, InitialPayload payload) : base(connection, payload)
+ {
+ if (payload.Settings == null || payload.Settings.Count == 0)
+ {
+ this.settings = PluginSettings.CreateDefaultSettings();
+ SaveSettings();
+ }
+ else
+ {
+ this.settings = payload.Settings.ToObject();
+ }
+ GlobalSettingsManager.Instance.RequestGlobalSettings();
+ CheckFile();
+ }
+
+ private void Instance_OnReceivedGlobalSettings(object sender, ReceivedGlobalSettingsPayload e)
+ {
+ Tools.AutoPopulateSettings(GlobalSettings.Instance, e.Settings);
+ }
+
+ private async void CheckFile()
+ {
+
+ if (settings == null || GlobalSettings.Instance.BasePath == null || GlobalSettings.Instance.ProfileName ==null) 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();
+ }
+ }
+
+
+ private async void Connection_OnApplicationDidLaunch(object sender, BarRaider.SdTools.Wrappers.SDEventReceivedEventArgs e)
+ {
+
+ }
+
+ private void Connection_OnTitleParametersDidChange(object sender, SDEventReceivedEventArgs e)
+ {
+ titleParameters = e.Event?.Payload?.TitleParameters;
+ userTitle = e.Event?.Payload?.Title;
+ }
+
+ public override void Dispose()
+ {
+ Connection.OnTitleParametersDidChange -= Connection_OnTitleParametersDidChange;
+ Connection.OnApplicationDidLaunch -= Connection_OnApplicationDidLaunch;
+ //Logger.Instance.LogMessage(TracingLevel.INFO, $"Destructor called");
+ }
+
+ public override void KeyPressed(KeyPayload payload)
+ {
+ //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
+ {
+
+ }
+
+ }
+
+ public override void KeyReleased(KeyPayload payload) {
+
+ }
+
+ public override void OnTick() {
+ CheckFile();
+ }
+
+ public override async void ReceivedSettings(ReceivedSettingsPayload payload)
+ {
+ Logger.Instance.LogMessage(TracingLevel.INFO, "Player rec settings");
+ Tools.AutoPopulateSettings(settings, payload.Settings);
+ GlobalSettings.Instance.SetFileOptionsCurrentProfile(settings.Path, new FileEntry() { Playtype = settings.PlayType, Volume = settings.Volume });
+ await Connection.SetGlobalSettingsAsync(JObject.FromObject(GlobalSettings.Instance));
+ //SaveSettings();
+ //CheckFile();
+ }
+
+ public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload) {
+ //Logger.Instance.LogMessage(TracingLevel.INFO, "ReceivedGlobalSettings");
+
+ if (payload.Settings == null || payload.Settings.Count == 0)
+ {
+ var inst = GlobalSettings.Instance;
+ //GlobalSettingsManager.Instance.SetGlobalSettings(JObject.FromObject(inst));
+ }
+ else
+ {
+ GlobalSettings.Instance = payload.Settings.ToObject();
+ }
+
+ //CheckFile();
+ }
+
+ #region Private Methods
+
+ private Task SaveSettings()
+ {
+ return Connection.SetSettingsAsync(JObject.FromObject(settings));
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/stream_deck_plugin/ClipTrimDotNet/ProfileSwitcher.cs b/stream_deck_plugin/ClipTrimDotNet/ProfileSwitcher.cs
new file mode 100644
index 0000000..d1d2586
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/ProfileSwitcher.cs
@@ -0,0 +1,164 @@
+using BarRaider.SdTools;
+using BarRaider.SdTools.Wrappers;
+using NAudio.CoreAudioApi.Interfaces;
+using NAudio.Wave;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Dynamic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ClipTrimDotNet
+{
+ public class DataSourceItem
+ {
+ public string label { get; set; }
+ public string value { get; set; }
+ }
+ [PluginActionId("com.michal-courson.cliptrim.profile-switcher")]
+ public class ProfileSwitcher : KeypadBase
+ {
+ private class PluginSettings
+ {
+ public static PluginSettings CreateDefaultSettings()
+ {
+ PluginSettings instance = new PluginSettings();
+ instance.ProfileName = null;
+ return instance;
+ }
+
+ [JsonProperty(PropertyName = "profileName")]
+ public string? ProfileName { get; set; }
+ }
+
+ #region Private Members
+
+ private PluginSettings settings;
+
+ #endregion
+ public ProfileSwitcher(SDConnection connection, InitialPayload payload) : base(connection, payload)
+ {
+ if (payload.Settings == null || payload.Settings.Count == 0)
+ {
+ this.settings = PluginSettings.CreateDefaultSettings();
+ SaveSettings();
+ }
+ else
+ {
+ this.settings = payload.Settings.ToObject();
+ }
+ GlobalSettingsManager.Instance.RequestGlobalSettings();
+ Connection.OnSendToPlugin += Connection_OnSendToPlugin;
+ SetTitle();
+ }
+
+ private async void SetTitle()
+ {
+
+ await Connection.SetTitleAsync(settings.ProfileName);
+ }
+
+ private async void Connection_OnSendToPlugin(object sender, SDEventReceivedEventArgs e)
+ {
+ //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");
+ var items = files.Select(x => new DataSourceItem { label = x, value = x});
+ var obj = new JObject();
+ obj["event"] = "getProfiles";
+ obj["items"] = JArray.FromObject(items);
+ //Logger.Instance.LogMessage(TracingLevel.INFO, "get profiles return " + JsonConvert.SerializeObject(obj));
+ await Connection.SendToPropertyInspectorAsync(obj);
+ }
+ if (e.Event.Payload["event"].ToString() == "getOutputDevices")
+ {
+ List devices = new List();
+ for (int n = -1; n < WaveOut.DeviceCount; n++)
+ {
+ var caps = WaveOut.GetCapabilities(n);
+ devices.Add(caps);
+ }
+ var items = devices.Select(x => new DataSourceItem { label = x.ProductName, value = x.ProductName });
+ var obj = new JObject();
+ obj["event"] = "getOutputDevices";
+ obj["items"] = JArray.FromObject(items);
+ //Logger.Instance.LogMessage(TracingLevel.INFO, "get devices return " + JsonConvert.SerializeObject(obj));
+ await Connection.SendToPropertyInspectorAsync(obj);
+ }
+
+ }
+
+ private void Connection_OnTitleParametersDidChange(object sender, SDEventReceivedEventArgs e)
+ {
+ }
+
+ public override void Dispose()
+ {
+ Connection.OnTitleParametersDidChange -= Connection_OnTitleParametersDidChange;
+ //Logger.Instance.LogMessage(TracingLevel.INFO, $"Destructor called");
+ }
+
+ public override async void KeyPressed(KeyPayload payload)
+ {
+ //Logger.Instance.LogMessage(TracingLevel.INFO, "KeyPressed");
+ //Logger.Instance.LogMessage(TracingLevel.INFO, JsonConvert.SerializeObject(settings));
+ //Logger.Instance.LogMessage(TracingLevel.INFO, JsonConvert.SerializeObject(GlobalSettings.Instance));
+ GlobalSettings.Instance.SetCurrentProfile(settings.ProfileName);
+ Logger.Instance.LogMessage(TracingLevel.INFO, JsonConvert.SerializeObject(GlobalSettings.Instance));
+
+ await Connection.SetGlobalSettingsAsync(JObject.FromObject(GlobalSettings.Instance));
+ await Connection.SwitchProfileAsync("ClipTrim");
+ }
+
+ public override void KeyReleased(KeyPayload payload)
+ {
+
+ }
+
+ public override void OnTick()
+ {
+ SetTitle();
+ }
+
+ public override void ReceivedSettings(ReceivedSettingsPayload payload)
+ {
+ Tools.AutoPopulateSettings(settings, payload.Settings);
+ SaveSettings();
+ //tTitle();
+ //CheckFile();
+ }
+
+ public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload)
+ {
+ //Logger.Instance.LogMessage(TracingLevel.INFO, "ReceivedGlobalSettings");
+
+ if (payload.Settings == null || payload.Settings.Count == 0)
+ {
+ var inst = GlobalSettings.Instance;
+ //GlobalSettingsManager.Instance.SetGlobalSettings(JObject.FromObject(inst));
+ }
+ else
+ {
+ GlobalSettings.Instance = payload.Settings.ToObject();
+ }
+
+ //CheckFile();
+ }
+
+ #region Private Methods
+
+ private Task SaveSettings()
+ {
+ return Connection.SetSettingsAsync(JObject.FromObject(settings));
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/stream_deck_plugin/ClipTrimDotNet/Program.cs b/stream_deck_plugin/ClipTrimDotNet/Program.cs
new file mode 100644
index 0000000..9b01e28
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/Program.cs
@@ -0,0 +1,19 @@
+using BarRaider.SdTools;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ClipTrimDotNet
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ // Uncomment this line of code to allow for debugging
+ //while (!System.Diagnostics.Debugger.IsAttached) { System.Threading.Thread.Sleep(100); }
+ SDWrapper.Run(args);
+ }
+ }
+}
diff --git a/stream_deck_plugin/ClipTrimDotNet/Properties/AssemblyInfo.cs b/stream_deck_plugin/ClipTrimDotNet/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a5449c8
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ClipTrimDotNet")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ClipTrimDotNet")]
+[assembly: AssemblyCopyright("Copyright © 2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1bb90885-9d98-46ef-b983-4a4ef3aea890")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/stream_deck_plugin/ClipTrimDotNet/PropertyInspector/file_player.html b/stream_deck_plugin/ClipTrimDotNet/PropertyInspector/file_player.html
new file mode 100644
index 0000000..a33211e
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/PropertyInspector/file_player.html
@@ -0,0 +1,45 @@
+
+
+
+
+ Increment Counter Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/stream_deck_plugin/ClipTrimDotNet/PropertyInspector/profile_swticher.html b/stream_deck_plugin/ClipTrimDotNet/PropertyInspector/profile_swticher.html
new file mode 100644
index 0000000..10af32e
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/PropertyInspector/profile_swticher.html
@@ -0,0 +1,34 @@
+
+
+
+ Increment Counter Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stream_deck_plugin/ClipTrimDotNet/WavPlayer.cs b/stream_deck_plugin/ClipTrimDotNet/WavPlayer.cs
new file mode 100644
index 0000000..68036b6
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/WavPlayer.cs
@@ -0,0 +1,225 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.ServiceModel.Security;
+using System.Threading.Tasks;
+using BarRaider.SdTools;
+using NAudio.Wave;
+using NAudio.Wave.SampleProviders;
+using Newtonsoft.Json;
+
+class CachedSound
+{
+ public byte[] AudioData { get; private set; }
+ public WaveFormat WaveFormat { get; private set; }
+ public CachedSound(string audioFileName)
+ {
+ using (var audioFileReader = new AudioFileReader(audioFileName))
+ {
+ // TODO: could add resampling in here if required
+ WaveFormat = audioFileReader.WaveFormat;
+ var wholeFile = new List((int)(audioFileReader.Length));
+ var readBuffer = new byte[audioFileReader.WaveFormat.SampleRate * audioFileReader.WaveFormat.Channels*4];
+ int samplesRead;
+ while ((samplesRead = audioFileReader.Read(readBuffer, 0, readBuffer.Length)) > 0)
+ {
+ wholeFile.AddRange(readBuffer.Take(samplesRead));
+ }
+ AudioData = wholeFile.ToArray();
+ }
+ //Logger.Instance.LogMessage(TracingLevel.INFO, $"AudioData Length {AudioData.Length}");
+
+ }
+}
+class CachedSoundSampleProvider : IWaveProvider
+{
+ private readonly CachedSound cachedSound;
+ private long position;
+
+ ~CachedSoundSampleProvider() {
+ //Logger.Instance.LogMessage(TracingLevel.INFO, $"Cache destructor");
+ }
+
+ public CachedSoundSampleProvider(CachedSound cachedSound)
+ {
+ this.cachedSound = cachedSound;
+ position = 0;
+ }
+
+ public int Read(byte[] buffer, int offset, int count)
+ {
+ //Logger.Instance.LogMessage(TracingLevel.INFO, $"Read1 byte");
+ var availableSamples = cachedSound.AudioData.Length - position;
+ var samplesToCopy = Math.Min(availableSamples, count);
+ try
+ {
+ //Logger.Instance.LogMessage(TracingLevel.INFO, $"{cachedSound.AudioData.GetType()} {buffer.GetType()}");
+ Array.Copy(cachedSound.AudioData, position, buffer, offset, samplesToCopy);
+ }
+ catch (Exception ex)
+ {
+ //Logger.Instance.LogMessage(TracingLevel.INFO, $"{ex.ToString()}");
+ }
+ //Logger.Instance.LogMessage(TracingLevel.INFO, $"Read3");
+ position += samplesToCopy;
+ //Logger.Instance.LogMessage(TracingLevel.INFO, $"Sending {samplesToCopy} samples");
+ return (int)samplesToCopy;
+ }
+
+ public WaveFormat WaveFormat => cachedSound.WaveFormat;
+}
+
+public class WavPlayer
+{
+ private static WavPlayer? instance;
+ public static WavPlayer Instance
+ {
+ get
+ {
+ instance ??= new WavPlayer();
+ return instance;
+ }
+
+ }
+ public enum PlayMode
+ {
+ PlayOverlap,
+ PlayStop
+ }
+
+ private readonly ConcurrentDictionary>> _activePlayers;
+
+ public WavPlayer()
+ {
+ _activePlayers = new ConcurrentDictionary>>();
+ }
+
+ public void Play(string filePath, string id, double volume, PlayMode mode)
+ {
+ if (string.IsNullOrWhiteSpace(filePath))
+ throw new ArgumentException("File path cannot be null or empty.", nameof(filePath));
+
+ if (mode == PlayMode.PlayOverlap)
+ {
+ PlayWithOverlap(filePath, id, volume);
+ }
+ else if (mode == PlayMode.PlayStop)
+ {
+ PlayWithStop(filePath, id, volume);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(mode), "Invalid play mode specified.");
+ }
+ }
+
+ private void PlayWithOverlap(string filePath, string id, double volume)
+ {
+
+ try
+ {
+ //Logger.Instance.LogMessage(TracingLevel.INFO, "Play overlap");
+ var player = CreatePlayer(filePath, id);
+
+ if (!_activePlayers.ContainsKey(filePath))
+ {
+ _activePlayers[filePath] = new List>();
+ }
+
+ _activePlayers[filePath].Add(player);
+ player.Item1.Volume = (float)volume;
+ player.Item1.Play();
+ }
+ catch(Exception ex)
+ {
+ //Logger.Instance.LogMessage(TracingLevel.INFO, ex.ToString());
+ }
+
+ //var playersToDispose = _activePlayers[filePath].Where(x => x.Item1.PlaybackState == PlaybackState.Stopped).ToList();
+ //foreach (var p in playersToDispose)
+ //{
+ // p.Item1.Stop();
+ // p.Item1.Dispose();
+ //}
+ //_activePlayers[filePath].RemoveAll(x => x.Item1.PlaybackState == PlaybackState.Stopped);
+ }
+
+ private void PlayWithStop(string filePath, string id, double volume)
+ {
+ if (_activePlayers.TryGetValue(filePath, out var players))
+ {
+
+ // Stop and dispose all current players for this file
+ if (players.Any(x => x.Item1.PlaybackState == PlaybackState.Playing))
+ {
+ var playersToDispose = players.ToList();
+ foreach (var player in playersToDispose)
+ {
+ player.Item1.Stop();
+ player.Item1.Dispose();
+ }
+ }
+ else
+ {
+ PlayWithOverlap(filePath, id, volume);
+ }
+
+ }
+ else
+ {
+ // Start a new player
+ PlayWithOverlap(filePath, id, volume);
+ }
+
+ _activePlayers[filePath].RemoveAll(x => x.Item1.PlaybackState == PlaybackState.Stopped);
+ }
+
+ private Tuple CreatePlayer(string filePath, string name)
+ {
+ var reader = new CachedSoundSampleProvider(new CachedSound(filePath));
+ //var reader = new AudioFileReader(filePath);
+ int number = -1;
+ for (int i = 0; i < WaveOut.DeviceCount; ++i)
+ {
+ if (WaveOut.GetCapabilities(i).ProductName == name)
+ {
+ number = i;
+ }
+ }
+ var player = new WaveOutEvent() { DeviceNumber = number };
+ player.Init(reader);
+ return new Tuple(player, reader);
+ }
+
+ private void CleanupPlayer(string filePath)
+ {
+ if (_activePlayers.TryGetValue(filePath, out var players))
+ {
+ var playersToDispose = players.ToList();
+ foreach (var p in playersToDispose)
+ {
+ p.Item1.Stop();
+ p.Item1.Dispose();
+ }
+ }
+ _activePlayers[filePath].RemoveAll(x => x.Item1.PlaybackState == PlaybackState.Stopped);
+
+ }
+
+ public void StopAll()
+ {
+ foreach (var players in _activePlayers.Values)
+ {
+ var playersToDispose = players.ToList();
+ foreach (var player in playersToDispose)
+ {
+ player.Item1.Stop();
+ player.Item1.Dispose();
+ }
+ players.Clear();
+ }
+
+ _activePlayers.Clear();
+ }
+}
diff --git a/stream_deck_plugin/ClipTrimDotNet/com.michal-courson.cliptrim.streamDeckPlugin b/stream_deck_plugin/ClipTrimDotNet/com.michal-courson.cliptrim.streamDeckPlugin
new file mode 100644
index 0000000..0b84cd9
Binary files /dev/null and b/stream_deck_plugin/ClipTrimDotNet/com.michal-courson.cliptrim.streamDeckPlugin differ
diff --git a/stream_deck_plugin/ClipTrimDotNet/manifest.json b/stream_deck_plugin/ClipTrimDotNet/manifest.json
new file mode 100644
index 0000000..9ff9b8c
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/manifest.json
@@ -0,0 +1,62 @@
+{
+
+ "Actions": [
+ {
+ "Icon": "Images/icon",
+ "Name": "Player",
+ "States": [
+ {
+ "Image": "Images/pluginAction",
+ "TitleAlignment": "middle",
+ "FontSize": 11
+ }
+ ],
+ "SupportedInMultiActions": false,
+ "Tooltip": "Plays a bound audio file",
+ "UUID": "com.michal-courson.cliptrim.player",
+ "PropertyInspectorPath": "PropertyInspector/file_player.html"
+ },
+ {
+ "Icon": "Images/icon",
+ "Name": "Profile Switcher",
+ "States": [
+ {
+ "Image": "Images/pluginAction",
+ "TitleAlignment": "middle",
+ "FontSize": 11
+ }
+ ],
+ "SupportedInMultiActions": false,
+ "Tooltip": "Selects which sub folder to use and opens effect profile",
+ "UUID": "com.michal-courson.cliptrim.profile-switcher",
+ "PropertyInspectorPath": "PropertyInspector/profile_swticher.html"
+ }
+ ],
+ "Author": "Michal Courson",
+ "Name": "ClipTrimDotNet",
+ "Description": "Pairs with cliptrim for easy voice recording and trimming",
+ "Icon": "Images/pluginIcon",
+ "Version": "0.1.0.0",
+ "CodePath": "ClipTrimDotNet.exe",
+ "Category": "ClipTrimDotNet",
+ "CategoryIcon": "Images/categoryIcon",
+ "UUID": "com.michal-courson.cliptrim",
+ "OS": [
+ {
+ "Platform": "windows",
+ "MinimumVersion": "10"
+ }
+ ],
+ "SDKVersion": 2,
+ "Software": {
+ "MinimumVersion": "6.4"
+ },
+ "Profiles": [
+ {
+ "Name": "ClipTrim",
+ "DeviceType": 0,
+ "Readonly": false,
+ "DontAutoSwitchWhenInstalled": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/stream_deck_plugin/ClipTrimDotNet/pack.bat b/stream_deck_plugin/ClipTrimDotNet/pack.bat
new file mode 100644
index 0000000..8513b70
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/pack.bat
@@ -0,0 +1 @@
+npm exec streamdeck restart com.michal-courson.cliptrim
diff --git a/stream_deck_plugin/ClipTrimDotNet/package-lock.json b/stream_deck_plugin/ClipTrimDotNet/package-lock.json
new file mode 100644
index 0000000..8d76e11
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/package-lock.json
@@ -0,0 +1,272 @@
+{
+ "name": "ClipTrimDotNet",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "devDependencies": {
+ "shx": "^0.3.4"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
+ "dev": true,
+ "dependencies": {
+ "resolve": "^1.1.6"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/shelljs": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
+ "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
+ },
+ "bin": {
+ "shjs": "bin/shjs"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/shx": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz",
+ "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.3",
+ "shelljs": "^0.8.5"
+ },
+ "bin": {
+ "shx": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ }
+ }
+}
diff --git a/stream_deck_plugin/ClipTrimDotNet/package.json b/stream_deck_plugin/ClipTrimDotNet/package.json
new file mode 100644
index 0000000..c55417b
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/package.json
@@ -0,0 +1,14 @@
+{
+ "scripts": {
+ "stop": "streamdeck stop com.michal-courson.cliptrim",
+ "copy": "@powershell robocopy bin/Debug/ClipTrimDotNet.sdPlugin bin/Debug/com.michal-courson.cliptrim.sdPlugin",
+ "link": "streamdeck link bin/Debug/com.michal-courson.cliptrim.sdPlugin",
+ "restart": "streamdeck restart com.michal-courson.cliptrim",
+ "start": "npm run link && npm run restart",
+ "all": "npm run stop && npm run copy && npm run link && npm run restart",
+ "pack": "streamdeck pack bin/Debug/com.michal-courson.cliptrim.sdPlugin/"
+ },
+ "devDependencies": {
+ "shx": "^0.3.4"
+ }
+}
diff --git a/stream_deck_plugin/ClipTrimDotNet/packages.config b/stream_deck_plugin/ClipTrimDotNet/packages.config
new file mode 100644
index 0000000..c2b7e68
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/packages.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/stream_deck_plugin/ClipTrimDotNet/val.bat b/stream_deck_plugin/ClipTrimDotNet/val.bat
new file mode 100644
index 0000000..cb09412
--- /dev/null
+++ b/stream_deck_plugin/ClipTrimDotNet/val.bat
@@ -0,0 +1,8 @@
+
+npm exec streamdeck stop com.michal-courson.cliptrim
+robocopy bin/Debug/ClipTrimDotNet.sdPlugin bin/Debug/com.michal-courson.cliptrim.sdPlugin /E
+npm exec streamdeck validate bin/Debug/com.michal-courson.cliptrim.sdPlugin
+
+
+npm exec streamdeck link bin/Debug/com.michal-courson.cliptrim.sdPlugin
+npm exec streamdeck restart com.michal-courson.cliptrim
\ No newline at end of file