diff --git a/.gitignore b/.gitignore index 6db67bd..8b7e502 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,22 @@ -# Visual Studio -.vs/ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* -# Builds -bin/ +node_modules +dist +dist-ssr +*.local -Debug/ -Release/ \ No newline at end of file +# Editor directories and files +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..24d7cc6 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..ad08506 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,32 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Tauri Development Debug", + "cargo": { + "args": [ + "build", + "--manifest-path=./src-tauri/Cargo.toml", + "--no-default-features" + ] + }, + // task for the `beforeDevCommand` if used, must be configured in `.vscode/tasks.json` + "preLaunchTask": "ui:dev" + }, + { + "type": "lldb", + "request": "launch", + "name": "Tauri Production Debug", + "cargo": { + "args": ["build", "--release", "--manifest-path=./src-tauri/Cargo.toml"] + }, + // task for the `beforeBuildCommand` if used, must be configured in `.vscode/tasks.json` + "preLaunchTask": "ui:build" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..dd40294 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,25 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "ui:dev", + "type": "shell", + // `dev` keeps running in the background + // ideally you should also configure a `problemMatcher` + // see https://code.visualstudio.com/docs/editor/tasks#_can-a-background-task-be-used-as-a-prelaunchtask-in-launchjson + "isBackground": true, + // change this to your `beforeDevCommand`: + "command": "npm", + "args": ["run", "dev"] + }, + { + "label": "ui:build", + "type": "shell", + // change this to your `beforeBuildCommand`: + "command": "npm", + "args": ["run", "build"] + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index b47ae54..8c35f22 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,13 @@ If you don't record ShadowPlay clips with 2 audio tracks, you don't need this pr ## Installation 1. Download and install [ffmpeg](https://ffmpeg.org/download.html). - 1. An easy way on Windows is to use `winget`: `winget install ffmpeg` -2. Download VideoClipper.exe from the [Releases](https://github.com/GitGeddes/VideoClipper/releases) page. + 1. `winget` is an easy way to install it on Windows: `winget install ffmpeg` +2. Download the installer from the [Releases](https://github.com/GitGeddes/VideoClipper/releases) page. + 1. This ensures you have dependencies like vcredist and WebView2. ## Features - File picker -- Text input for start and end timestamps - - Strings are not validated, use `mm:ss` format compatible with `ffmpeg` +- Video preview with slider to select start and end timestamps - Text input for output filename - Mute or unmute microphone track - Choose whether or not to overwrite an existing output file (not tested) @@ -21,11 +21,11 @@ If you don't record ShadowPlay clips with 2 audio tracks, you don't need this pr ## Usage 1. Select a video to clip -2. Enter a start/end time in the format `mm:ss` +2. Select a start and end time with the slider 3. (Optional) Enter a filename for the output file 4. Choose whether to include the microphone audio track in the output 5. Process the video The output file goes into the same folder as the selected input video. -![screenshot](./VideoClipper/Resources/Images/VideoClipper-screenshot.png) +![screenshot](./public/videoclipper_screenshot.png) diff --git a/VideoClipper.sln b/VideoClipper.sln deleted file mode 100644 index 6705dac..0000000 --- a/VideoClipper.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.14.36212.18 d17.14 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VideoClipper", "VideoClipper\VideoClipper.csproj", "{2BA4F148-9281-4E54-B404-9FAC3219FAD3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2BA4F148-9281-4E54-B404-9FAC3219FAD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2BA4F148-9281-4E54-B404-9FAC3219FAD3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2BA4F148-9281-4E54-B404-9FAC3219FAD3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2BA4F148-9281-4E54-B404-9FAC3219FAD3}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {780EDDD3-19CE-4997-B0C5-D9DD14DDD4DC} - EndGlobalSection -EndGlobal diff --git a/VideoClipper/App.xaml b/VideoClipper/App.xaml deleted file mode 100644 index 545b94f..0000000 --- a/VideoClipper/App.xaml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - diff --git a/VideoClipper/App.xaml.cs b/VideoClipper/App.xaml.cs deleted file mode 100644 index a18e508..0000000 --- a/VideoClipper/App.xaml.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace VideoClipper -{ - public partial class App : Application - { - public App() - { - InitializeComponent(); - } - - protected override Window CreateWindow(IActivationState? activationState) - { - var window = new Window(new AppShell()) - { - Width = 400, - Height = 400 - }; - - return window; - } - } -} \ No newline at end of file diff --git a/VideoClipper/AppShell.xaml b/VideoClipper/AppShell.xaml deleted file mode 100644 index 74bf0ab..0000000 --- a/VideoClipper/AppShell.xaml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/VideoClipper/AppShell.xaml.cs b/VideoClipper/AppShell.xaml.cs deleted file mode 100644 index 9ab4a57..0000000 --- a/VideoClipper/AppShell.xaml.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace VideoClipper -{ - public partial class AppShell : Shell - { - public AppShell() - { - InitializeComponent(); - } - } -} diff --git a/VideoClipper/MauiProgram.cs b/VideoClipper/MauiProgram.cs deleted file mode 100644 index c4551b1..0000000 --- a/VideoClipper/MauiProgram.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.Extensions.Logging; - -namespace VideoClipper -{ - public static class MauiProgram - { - public static MauiApp CreateMauiApp() - { - var builder = MauiApp.CreateBuilder(); - builder - .UseMauiApp() - .ConfigureFonts(fonts => - { - fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); - fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); - }); - -#if DEBUG - builder.Logging.AddDebug(); -#endif - - return builder.Build(); - } - } -} diff --git a/VideoClipper/Platforms/Android/AndroidManifest.xml b/VideoClipper/Platforms/Android/AndroidManifest.xml deleted file mode 100644 index e9937ad..0000000 --- a/VideoClipper/Platforms/Android/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/VideoClipper/Platforms/Android/MainActivity.cs b/VideoClipper/Platforms/Android/MainActivity.cs deleted file mode 100644 index 21a39e2..0000000 --- a/VideoClipper/Platforms/Android/MainActivity.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Android.App; -using Android.Content.PM; -using Android.OS; - -namespace VideoClipper -{ - [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] - public class MainActivity : MauiAppCompatActivity - { - } -} diff --git a/VideoClipper/Platforms/Android/MainApplication.cs b/VideoClipper/Platforms/Android/MainApplication.cs deleted file mode 100644 index 0c16045..0000000 --- a/VideoClipper/Platforms/Android/MainApplication.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Android.App; -using Android.Runtime; - -namespace VideoClipper -{ - [Application] - public class MainApplication : MauiApplication - { - public MainApplication(IntPtr handle, JniHandleOwnership ownership) - : base(handle, ownership) - { - } - - protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); - } -} diff --git a/VideoClipper/Platforms/Android/Resources/values/colors.xml b/VideoClipper/Platforms/Android/Resources/values/colors.xml deleted file mode 100644 index c04d749..0000000 --- a/VideoClipper/Platforms/Android/Resources/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #512BD4 - #2B0B98 - #2B0B98 - \ No newline at end of file diff --git a/VideoClipper/Platforms/MacCatalyst/AppDelegate.cs b/VideoClipper/Platforms/MacCatalyst/AppDelegate.cs deleted file mode 100644 index ef868be..0000000 --- a/VideoClipper/Platforms/MacCatalyst/AppDelegate.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Foundation; - -namespace VideoClipper -{ - [Register("AppDelegate")] - public class AppDelegate : MauiUIApplicationDelegate - { - protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); - } -} diff --git a/VideoClipper/Platforms/MacCatalyst/Entitlements.plist b/VideoClipper/Platforms/MacCatalyst/Entitlements.plist deleted file mode 100644 index de4adc9..0000000 --- a/VideoClipper/Platforms/MacCatalyst/Entitlements.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - com.apple.security.app-sandbox - - - com.apple.security.network.client - - - - diff --git a/VideoClipper/Platforms/MacCatalyst/Info.plist b/VideoClipper/Platforms/MacCatalyst/Info.plist deleted file mode 100644 index 7268977..0000000 --- a/VideoClipper/Platforms/MacCatalyst/Info.plist +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - UIDeviceFamily - - 2 - - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - XSAppIconAssets - Assets.xcassets/appicon.appiconset - - diff --git a/VideoClipper/Platforms/MacCatalyst/Program.cs b/VideoClipper/Platforms/MacCatalyst/Program.cs deleted file mode 100644 index 6ddaf66..0000000 --- a/VideoClipper/Platforms/MacCatalyst/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -using ObjCRuntime; -using UIKit; - -namespace VideoClipper -{ - public class Program - { - // This is the main entry point of the application. - static void Main(string[] args) - { - // if you want to use a different Application Delegate class from "AppDelegate" - // you can specify it here. - UIApplication.Main(args, null, typeof(AppDelegate)); - } - } -} diff --git a/VideoClipper/Platforms/Tizen/Main.cs b/VideoClipper/Platforms/Tizen/Main.cs deleted file mode 100644 index a2c8cc7..0000000 --- a/VideoClipper/Platforms/Tizen/Main.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Microsoft.Maui; -using Microsoft.Maui.Hosting; - -namespace VideoClipper -{ - internal class Program : MauiApplication - { - protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); - - static void Main(string[] args) - { - var app = new Program(); - app.Run(args); - } - } -} diff --git a/VideoClipper/Platforms/Tizen/tizen-manifest.xml b/VideoClipper/Platforms/Tizen/tizen-manifest.xml deleted file mode 100644 index 6a0f93c..0000000 --- a/VideoClipper/Platforms/Tizen/tizen-manifest.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - maui-appicon-placeholder - - - - - http://tizen.org/privilege/internet - - - - \ No newline at end of file diff --git a/VideoClipper/Platforms/Windows/App.xaml b/VideoClipper/Platforms/Windows/App.xaml deleted file mode 100644 index 598607b..0000000 --- a/VideoClipper/Platforms/Windows/App.xaml +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/VideoClipper/Platforms/Windows/App.xaml.cs b/VideoClipper/Platforms/Windows/App.xaml.cs deleted file mode 100644 index 0a8dd5f..0000000 --- a/VideoClipper/Platforms/Windows/App.xaml.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.UI.Xaml; - -// To learn more about WinUI, the WinUI project structure, -// and more about our project templates, see: http://aka.ms/winui-project-info. - -namespace VideoClipper.WinUI -{ - /// - /// Provides application-specific behavior to supplement the default Application class. - /// - public partial class App : MauiWinUIApplication - { - /// - /// Initializes the singleton application object. This is the first line of authored code - /// executed, and as such is the logical equivalent of main() or WinMain(). - /// - public App() - { - this.InitializeComponent(); - } - - protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); - } - -} diff --git a/VideoClipper/Platforms/Windows/Package.appxmanifest b/VideoClipper/Platforms/Windows/Package.appxmanifest deleted file mode 100644 index 258957b..0000000 --- a/VideoClipper/Platforms/Windows/Package.appxmanifest +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - $placeholder$ - User Name - $placeholder$.png - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VideoClipper/Platforms/Windows/app.manifest b/VideoClipper/Platforms/Windows/app.manifest deleted file mode 100644 index e47f258..0000000 --- a/VideoClipper/Platforms/Windows/app.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - true/PM - PerMonitorV2, PerMonitor - - - diff --git a/VideoClipper/Platforms/iOS/AppDelegate.cs b/VideoClipper/Platforms/iOS/AppDelegate.cs deleted file mode 100644 index ef868be..0000000 --- a/VideoClipper/Platforms/iOS/AppDelegate.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Foundation; - -namespace VideoClipper -{ - [Register("AppDelegate")] - public class AppDelegate : MauiUIApplicationDelegate - { - protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); - } -} diff --git a/VideoClipper/Platforms/iOS/Info.plist b/VideoClipper/Platforms/iOS/Info.plist deleted file mode 100644 index 0004a4f..0000000 --- a/VideoClipper/Platforms/iOS/Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - LSRequiresIPhoneOS - - UIDeviceFamily - - 1 - 2 - - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - XSAppIconAssets - Assets.xcassets/appicon.appiconset - - diff --git a/VideoClipper/Platforms/iOS/Program.cs b/VideoClipper/Platforms/iOS/Program.cs deleted file mode 100644 index 6ddaf66..0000000 --- a/VideoClipper/Platforms/iOS/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -using ObjCRuntime; -using UIKit; - -namespace VideoClipper -{ - public class Program - { - // This is the main entry point of the application. - static void Main(string[] args) - { - // if you want to use a different Application Delegate class from "AppDelegate" - // you can specify it here. - UIApplication.Main(args, null, typeof(AppDelegate)); - } - } -} diff --git a/VideoClipper/Platforms/iOS/Resources/PrivacyInfo.xcprivacy b/VideoClipper/Platforms/iOS/Resources/PrivacyInfo.xcprivacy deleted file mode 100644 index 24ab3b4..0000000 --- a/VideoClipper/Platforms/iOS/Resources/PrivacyInfo.xcprivacy +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - NSPrivacyAccessedAPITypes - - - NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategoryFileTimestamp - NSPrivacyAccessedAPITypeReasons - - C617.1 - - - - NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategorySystemBootTime - NSPrivacyAccessedAPITypeReasons - - 35F9.1 - - - - NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategoryDiskSpace - NSPrivacyAccessedAPITypeReasons - - E174.1 - - - - - - diff --git a/VideoClipper/Properties/launchSettings.json b/VideoClipper/Properties/launchSettings.json deleted file mode 100644 index 4f85793..0000000 --- a/VideoClipper/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "Windows Machine": { - "commandName": "Project", - "nativeDebugging": false - } - } -} \ No newline at end of file diff --git a/VideoClipper/Resources/AppIcon/appicon.svg b/VideoClipper/Resources/AppIcon/appicon.svg deleted file mode 100644 index 9d63b65..0000000 --- a/VideoClipper/Resources/AppIcon/appicon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/VideoClipper/Resources/AppIcon/appiconfg.svg b/VideoClipper/Resources/AppIcon/appiconfg.svg deleted file mode 100644 index 21dfb25..0000000 --- a/VideoClipper/Resources/AppIcon/appiconfg.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/VideoClipper/Resources/Fonts/OpenSans-Regular.ttf b/VideoClipper/Resources/Fonts/OpenSans-Regular.ttf deleted file mode 100644 index 33b3e0d..0000000 Binary files a/VideoClipper/Resources/Fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/VideoClipper/Resources/Fonts/OpenSans-Semibold.ttf b/VideoClipper/Resources/Fonts/OpenSans-Semibold.ttf deleted file mode 100644 index a1f8571..0000000 Binary files a/VideoClipper/Resources/Fonts/OpenSans-Semibold.ttf and /dev/null differ diff --git a/VideoClipper/Resources/Images/VideoClipper-screenshot.png b/VideoClipper/Resources/Images/VideoClipper-screenshot.png deleted file mode 100644 index 4bbe716..0000000 Binary files a/VideoClipper/Resources/Images/VideoClipper-screenshot.png and /dev/null differ diff --git a/VideoClipper/Resources/Raw/AboutAssets.txt b/VideoClipper/Resources/Raw/AboutAssets.txt deleted file mode 100644 index 89dc758..0000000 --- a/VideoClipper/Resources/Raw/AboutAssets.txt +++ /dev/null @@ -1,15 +0,0 @@ -Any raw assets you want to be deployed with your application can be placed in -this directory (and child directories). Deployment of the asset to your application -is automatically handled by the following `MauiAsset` Build Action within your `.csproj`. - - - -These files will be deployed with your package and will be accessible using Essentials: - - async Task LoadMauiAsset() - { - using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt"); - using var reader = new StreamReader(stream); - - var contents = reader.ReadToEnd(); - } diff --git a/VideoClipper/Resources/Splash/splash.svg b/VideoClipper/Resources/Splash/splash.svg deleted file mode 100644 index 21dfb25..0000000 --- a/VideoClipper/Resources/Splash/splash.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/VideoClipper/Resources/Styles/Colors.xaml b/VideoClipper/Resources/Styles/Colors.xaml deleted file mode 100644 index 30307a5..0000000 --- a/VideoClipper/Resources/Styles/Colors.xaml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - #512BD4 - #ac99ea - #242424 - #DFD8F7 - #9880e5 - #2B0B98 - - White - Black - #D600AA - #190649 - #1f1f1f - - #E1E1E1 - #C8C8C8 - #ACACAC - #919191 - #6E6E6E - #404040 - #212121 - #141414 - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/VideoClipper/Resources/Styles/Styles.xaml b/VideoClipper/Resources/Styles/Styles.xaml deleted file mode 100644 index 86f574d..0000000 --- a/VideoClipper/Resources/Styles/Styles.xaml +++ /dev/null @@ -1,451 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VideoClipper/VideoClipper.csproj b/VideoClipper/VideoClipper.csproj deleted file mode 100644 index 2378a9b..0000000 --- a/VideoClipper/VideoClipper.csproj +++ /dev/null @@ -1,80 +0,0 @@ - - - - net9.0-android;net9.0-ios;net9.0-maccatalyst - $(TargetFrameworks);net9.0-windows10.0.19041.0 - - - - - - - Exe - VideoClipper - true - true - enable - enable - - - VideoClipper - - - com.companyname.videoclipper - - - 1.0 - 1 - - - None - - 15.0 - 15.0 - 21.0 - 10.0.17763.0 - 10.0.17763.0 - 6.5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MainPage.xaml - - - - - - MSBuild:Compile - - - - diff --git a/VideoClipper/VideoClipper.csproj.user b/VideoClipper/VideoClipper.csproj.user deleted file mode 100644 index b871828..0000000 --- a/VideoClipper/VideoClipper.csproj.user +++ /dev/null @@ -1,28 +0,0 @@ - - - - False - net9.0-windows10.0.19041.0 - Windows Machine - - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - \ No newline at end of file diff --git a/VideoClipper/Views/MainPage.xaml b/VideoClipper/Views/MainPage.xaml deleted file mode 100644 index 81c6c63..0000000 --- a/VideoClipper/Views/MainPage.xaml +++ /dev/null @@ -1,94 +0,0 @@ - - - - +
+ +
+
+ {/* Start time input */} + + {/* End time input */} + +
+
+
+ {/* Mute mic checkbox */} + + {/* Overwrite file checkbox */} + +
+
+ {/* Output filename text input */} + +

{statusMsg}

+
+ {/* Call ffmpeg button */} + +
+ + ); +} + +export default App; diff --git a/src/assets/react.svg b/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx new file mode 100644 index 0000000..3afd46e --- /dev/null +++ b/src/components/Checkbox.tsx @@ -0,0 +1,3 @@ +export default function Checkbox(props: { value: boolean; setValue: (arg0: boolean) => void; }) { + return {props.setValue(!props.value)}}/> +} \ No newline at end of file diff --git a/src/components/CheckboxLabel.tsx b/src/components/CheckboxLabel.tsx new file mode 100644 index 0000000..e82347f --- /dev/null +++ b/src/components/CheckboxLabel.tsx @@ -0,0 +1,19 @@ +import Checkbox from "./Checkbox"; + +type CheckboxLabelProps = { + text: string; + isValue: boolean; + setIsValue: (bool: boolean) => void; +} + +export default function CheckboxLabel(props: CheckboxLabelProps) { + return ( +
+

{props.text}

+ +
+ ); +} \ No newline at end of file diff --git a/src/components/FilenameInput.tsx b/src/components/FilenameInput.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/MinimumDistanceSlider.tsx b/src/components/MinimumDistanceSlider.tsx new file mode 100644 index 0000000..0ea68bc --- /dev/null +++ b/src/components/MinimumDistanceSlider.tsx @@ -0,0 +1,73 @@ +/* + https://mui.com/material-ui/react-slider/#minimum-distance +*/ +import { useState } from 'react'; +import Slider, { SliderProps } from '@mui/material/Slider'; + +function valuetext(value: number, _index: number) { + return `${secondsToFormattedString(value)}`; +} + +function secondsToFormattedString(seconds: number): string { + let secs: number = seconds % 60; + let mins: number = Math.floor(seconds / 60); + if (secs < 10) return mins + ":0" + secs; + return mins + ":" + secs; +} + +const minVal = 0; +const minDistance = 5; + +type MinDistanceSliderProps = SliderProps & { + setStartTime: (time: string) => void; + setEndTime: (time: string) => void; + seekToTime: (time: number) => void; +}; + +export default function MinimumDistanceSlider(props: MinDistanceSliderProps) { + const [values, setValues] = useState([0, minDistance]); + + const handleChange = (_event: Event, newValue: number | number[], activeThumb: number) => { + if (typeof newValue === "number") return; + if (newValue[1] - newValue[0] < minDistance) { + if (activeThumb === 0) { + const maxVal = Math.max(minVal, props.max ? props.max : minVal); + const clamped = Math.min(newValue[0], maxVal - minDistance); + const start = clamped; + const end = clamped + minDistance; + setValues([start, end]); + props.setStartTime(secondsToFormattedString(start)); + props.setEndTime(secondsToFormattedString(end)); + props.seekToTime(start); + } else { + const clamped = Math.max(newValue[1], minDistance); + const start = clamped - minDistance; + const end = clamped; + setValues([start, end]); + props.setStartTime(secondsToFormattedString(start)); + props.setEndTime(secondsToFormattedString(end)); + props.seekToTime(start); + } + } else { + setValues(newValue); + props.setStartTime(secondsToFormattedString(newValue[0])); + props.setEndTime(secondsToFormattedString(newValue[1])); + props.seekToTime(newValue[0]); + } + }; + + return ( + 'Minimum distance shift'} + getAriaValueText={valuetext} + disableSwap + /> + ); +} \ No newline at end of file diff --git a/src/components/TimeInput.tsx b/src/components/TimeInput.tsx new file mode 100644 index 0000000..65cab7a --- /dev/null +++ b/src/components/TimeInput.tsx @@ -0,0 +1,20 @@ +type TimeInputProps = { + text: string; + time: string; + setTime: (time: string) => void; +} + +export default function TimeInput(props: TimeInputProps) { + return ( +
+

{props.text}

+ props.setTime(e.currentTarget.value)} + onSubmit={(e) => props.setTime(e.currentTarget.value)} + placeholder="Enter a timestamp..." + /> +
+ ); +} \ No newline at end of file diff --git a/src/components/VideoPreview.tsx b/src/components/VideoPreview.tsx new file mode 100644 index 0000000..b3dc317 --- /dev/null +++ b/src/components/VideoPreview.tsx @@ -0,0 +1,33 @@ +import { convertFileSrc } from "@tauri-apps/api/core"; +import { useState } from "react"; +import ReactPlayer from 'react-player'; + +type VideoPreviewProps = { + setPlayerRef: (player: HTMLVideoElement) => void; + inputFilePath: string; + onLoadedMetadata: () => void; +}; + +export default function VideoPreview(props: VideoPreviewProps) { + const [_startTime, _setStartTime] = useState(""); + const [_endTime, _setEndTime] = useState(""); + + const onError = () => { + console.error("error loading video!"); + }; + + return ( + + ); +} \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..2be325e --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,9 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App"; + +ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( + + + , +); diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a7fc6fb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..42872c5 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..3ba3a9c --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,32 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +// @ts-expect-error process is a nodejs global +const host = process.env.TAURI_DEV_HOST; + +// https://vitejs.dev/config/ +export default defineConfig(async () => ({ + plugins: [react()], + + // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` + // + // 1. prevent vite from obscuring rust errors + clearScreen: false, + // 2. tauri expects a fixed port, fail if that port is not available + server: { + port: 1420, + strictPort: true, + host: host || false, + hmr: host + ? { + protocol: "ws", + host, + port: 1420, + } + : undefined, + watch: { + // 3. tell vite to ignore watching `src-tauri` + ignored: ["**/src-tauri/**"], + }, + }, +}));