Repository: MathewSachin/Captura Branch: master Commit: b0cc46780b18 Files: 720 Total size: 1.5 MB Directory structure: gitextract_9xzvr3yn/ ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ ├── feature_request.md │ │ └── question.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Inno.iss ├── LICENSE.md ├── README.md ├── SUPPORT.md ├── appveyor.yml ├── build.cake ├── choco/ │ ├── captura.nuspec │ └── tools/ │ └── chocolateyinstall.ps1 ├── crowdin.yml ├── docs/ │ ├── Acknowledgements.md │ ├── Build.md │ ├── CI.md │ ├── Cake.md │ ├── Changelogs/ │ │ ├── README.md │ │ ├── v7.0.1.md │ │ ├── v8.0.0.md │ │ └── v9.0.0.md │ ├── Choco.md │ ├── Cmdline/ │ │ ├── Arg-Source.md │ │ ├── README.md │ │ ├── Verb-FFmpeg.md │ │ ├── Verb-List.md │ │ ├── Verb-Shot.md │ │ └── Verb-Start.md │ ├── Directories.md │ ├── FAQ.md │ ├── FFmpeg.md │ ├── Portable.md │ ├── Projects.md │ ├── README.md │ ├── Screenshots/ │ │ ├── Dark.md │ │ └── Light.md │ ├── Setup.md │ └── System-Requirements.md ├── licenses/ │ ├── Captura, Screna.txt │ ├── CommandLineParser.txt │ ├── CroppingAdorner.txt │ ├── DirectShowLib.txt │ ├── FFMpeg.txt │ ├── Inno.txt │ ├── MUI.Extended.Toolkit.txt │ ├── MUI.txt │ ├── Media Foundation .NET.txt │ ├── MouseKeyHook.txt │ ├── NAudio.txt │ ├── Newtonsoft.Json.txt │ ├── Ooki.Dialogs.txt │ ├── ReactiveProperty.txt │ ├── ScreenToGif.txt │ ├── SharpAvi.txt │ ├── SharpDX.txt │ ├── System.Reactive.txt │ ├── WPFNotifyIcon.txt │ └── WpfToolkit.txt ├── scripts/ │ ├── apikeys.cake │ ├── backup.cake │ ├── choco.cake │ ├── constants.cake │ └── version.cake └── src/ ├── Captura/ │ ├── App.xaml │ ├── App.xaml.cs │ ├── Captura.csproj │ ├── Controls/ │ │ ├── CollapsedBar.xaml │ │ ├── CollapsedBar.xaml.cs │ │ ├── FontSelector.xaml │ │ ├── FontSelector.xaml.cs │ │ ├── HotkeySelector.cs │ │ ├── ImageOverlaySettingsControl.xaml │ │ ├── ImageOverlaySettingsControl.xaml.cs │ │ ├── LayerFrame.xaml │ │ ├── LayerFrame.xaml.cs │ │ ├── ModernButton.cs │ │ ├── ModernPasswordBox.xaml │ │ ├── ModernPasswordBox.xaml.cs │ │ ├── ModernToggleButton.cs │ │ ├── NotificationBalloon.xaml │ │ ├── NotificationBalloon.xaml.cs │ │ ├── NotificationStack.xaml │ │ ├── NotificationStack.xaml.cs │ │ ├── OutputFolderControl.xaml │ │ ├── OutputFolderControl.xaml.cs │ │ ├── PauseButton.xaml │ │ ├── PauseButton.xaml.cs │ │ ├── PositionSettingsControl.xaml │ │ ├── PositionSettingsControl.xaml.cs │ │ ├── PuncturedRegion.xaml │ │ ├── PuncturedRegion.xaml.cs │ │ ├── RecentItem.xaml │ │ ├── RecentItem.xaml.cs │ │ ├── ScreenShotBalloon.xaml │ │ ├── ScreenShotBalloon.xaml.cs │ │ ├── ScreenShotButton.xaml │ │ ├── ScreenShotButton.xaml.cs │ │ ├── StatusBar.xaml │ │ ├── StatusBar.xaml.cs │ │ ├── StripedBorder.xaml │ │ ├── StripedBorder.xaml.cs │ │ ├── TextOverlaySettingsControl.xaml │ │ ├── TextOverlaySettingsControl.xaml.cs │ │ ├── VideoSourceKindList.xaml │ │ └── VideoSourceKindList.xaml.cs │ ├── Models/ │ │ ├── AudioPlayer.cs │ │ ├── CmdOptions.cs │ │ ├── Dpi.cs │ │ ├── FFmpegViewsProvider.cs │ │ ├── HitType.cs │ │ ├── HotkeyListener.cs │ │ ├── HotkeySetup.cs │ │ ├── HotkeyViewActor.cs │ │ ├── IRemoveRequester.cs │ │ ├── MainModule.cs │ │ ├── MainWindowHelper.cs │ │ ├── MainWindowProvider.cs │ │ ├── MessageProvider.cs │ │ ├── PreviewWindowService.cs │ │ ├── RegionSelectorProvider.cs │ │ ├── ServiceLocator.cs │ │ ├── SingleInstanceManager.cs │ │ ├── SystemInfo.cs │ │ ├── SystemTray.cs │ │ └── VideoSourcePicker.cs │ ├── Pages/ │ │ ├── AboutPage.xaml │ │ ├── AboutPage.xaml.cs │ │ ├── AudioPage.xaml │ │ ├── AudioPage.xaml.cs │ │ ├── CensorOverlaysPage.xaml │ │ ├── CensorOverlaysPage.xaml.cs │ │ ├── CrashLogsPage.xaml │ │ ├── CrashLogsPage.xaml.cs │ │ ├── FFmpegCodecsPage.xaml │ │ ├── FFmpegCodecsPage.xaml.cs │ │ ├── FFmpegLogsPage.xaml │ │ ├── FFmpegLogsPage.xaml.cs │ │ ├── FFmpegPage.xaml │ │ ├── FFmpegPage.xaml.cs │ │ ├── FileNameFormatPage.xaml │ │ ├── FileNameFormatPage.xaml.cs │ │ ├── HomePage.xaml │ │ ├── HomePage.xaml.cs │ │ ├── HotkeysPage.xaml │ │ ├── HotkeysPage.xaml.cs │ │ ├── ImageOverlaysPage.xaml │ │ ├── ImageOverlaysPage.xaml.cs │ │ ├── InterfacePage.xaml │ │ ├── InterfacePage.xaml.cs │ │ ├── KeystrokesPage.xaml │ │ ├── KeystrokesPage.xaml.cs │ │ ├── LicensesPage.xaml │ │ ├── LicensesPage.xaml.cs │ │ ├── MainPage.xaml │ │ ├── MainPage.xaml.cs │ │ ├── MouseOverlayPage.xaml │ │ ├── MouseOverlayPage.xaml.cs │ │ ├── OverlayPage.xaml │ │ ├── OverlayPage.xaml.cs │ │ ├── ProxyPage.xaml │ │ ├── ProxyPage.xaml.cs │ │ ├── RecentPage.xaml │ │ ├── RecentPage.xaml.cs │ │ ├── ScreenShotsPage.xaml │ │ ├── ScreenShotsPage.xaml.cs │ │ ├── SettingsPage.xaml │ │ ├── SettingsPage.xaml.cs │ │ ├── SoundsPage.xaml │ │ ├── SoundsPage.xaml.cs │ │ ├── TextOverlaysPage.xaml │ │ ├── TextOverlaysPage.xaml.cs │ │ ├── TrayIconPage.xaml │ │ ├── TrayIconPage.xaml.cs │ │ ├── VideoPage.xaml │ │ ├── VideoPage.xaml.cs │ │ ├── WebcamPage.xaml │ │ └── WebcamPage.xaml.cs │ ├── Presentation/ │ │ ├── CroppingAdorner.cs │ │ ├── OverlayPositionAdorner.cs │ │ ├── PuncturedRect.cs │ │ ├── Themes/ │ │ │ ├── Expander.xaml │ │ │ ├── Generic.xaml │ │ │ ├── LICENSE.md │ │ │ ├── ModernButton.xaml │ │ │ ├── ModernToggleButton.xaml │ │ │ ├── ModernTogglePill.xaml │ │ │ ├── RegionPickerMagnifier.xaml │ │ │ ├── RoundSlider.xaml │ │ │ └── VirtualizingItemsControl.xaml │ │ └── WpfExtensions.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── ValueConverters/ │ │ ├── DrawingToWpfColorConverter.cs │ │ ├── GetTypeConverter.cs │ │ ├── InkToolToIconConverter.cs │ │ ├── IntegralTimeSpanConverter.cs │ │ ├── IsLessThanConverter.cs │ │ ├── IsPlayingToButtonStyleConverter.cs │ │ ├── LanguageConverter.cs │ │ ├── NegatingConverter.cs │ │ ├── NotNullConverter.cs │ │ ├── NotRecordingConverter.cs │ │ ├── OneWayConverter.cs │ │ ├── SecondsToTimeSpanConverter.cs │ │ ├── StateToRecordButtonGeometryConverter.cs │ │ ├── StateToTaskbarOverlayConverter.cs │ │ ├── StateToTrayIconSourceConverter.cs │ │ ├── StaticResourceConverter.cs │ │ ├── TimeSpanToSecondsConverter.cs │ │ └── ValueConverters.xaml │ ├── ViewModels/ │ │ ├── AboutViewModel.cs │ │ ├── ExceptionViewModel.cs │ │ ├── Overlays/ │ │ │ ├── CensorOverlayReactor.cs │ │ │ ├── ImageOverlayReactor.cs │ │ │ ├── PositionOverlayReactor.cs │ │ │ ├── TextOverlayReactor.cs │ │ │ └── WebcamOverlayReactor.cs │ │ ├── RegionSelectorViewModel.cs │ │ ├── ScreenPickerViewModel.cs │ │ └── TrimmerViewModel.cs │ ├── Windows/ │ │ ├── ErrorWindow.xaml │ │ ├── ErrorWindow.xaml.cs │ │ ├── ExceptionWindow.xaml │ │ ├── ExceptionWindow.xaml.cs │ │ ├── FFmpegDownloaderWindow.xaml │ │ ├── FFmpegDownloaderWindow.xaml.cs │ │ ├── MainWindow.xaml │ │ ├── MainWindow.xaml.cs │ │ ├── RegionPickerWindow.xaml │ │ ├── RegionPickerWindow.xaml.cs │ │ ├── RegionSelector.xaml │ │ ├── RegionSelector.xaml.cs │ │ ├── ScreenPickerWindow.xaml │ │ ├── ScreenPickerWindow.xaml.cs │ │ ├── SettingsWindow.xaml │ │ ├── SettingsWindow.xaml.cs │ │ ├── TrimmerWindow.xaml │ │ ├── TrimmerWindow.xaml.cs │ │ ├── VideoSourcePickerWindow.xaml │ │ ├── VideoSourcePickerWindow.xaml.cs │ │ ├── YouTubeUploaderWindow.xaml │ │ └── YouTubeUploaderWindow.xaml.cs │ └── app.config ├── Captura.Audio/ │ ├── Captura.Audio.csproj │ ├── IAudioFileWriter.cs │ ├── IAudioItem.cs │ ├── IAudioProvider.cs │ ├── IAudioSource.cs │ ├── IAudioWriterItem.cs │ └── WaveFormat/ │ ├── WaveFormat.cs │ └── WaveFormatEncoding.cs ├── Captura.Base/ │ ├── Captura.Base.csproj │ ├── ComparableExtensions.cs │ ├── DelegateCommand.cs │ ├── FrameExtensions.cs │ ├── IImageUploader.cs │ ├── IOverlay.cs │ ├── IRecorder.cs │ ├── IScreen.cs │ ├── IWindow.cs │ ├── Images/ │ │ ├── IBitmapFrame.cs │ │ ├── IBitmapImage.cs │ │ ├── IBitmapLoader.cs │ │ ├── IEditableFrame.cs │ │ ├── IFont.cs │ │ ├── IFrameWrapper.cs │ │ ├── IImageProvider.cs │ │ ├── IImageWriterItem.cs │ │ ├── IImagingSystem.cs │ │ ├── INV12Frame.cs │ │ ├── ImageFormats.cs │ │ └── RepeatFrame.cs │ ├── Modifiers.cs │ ├── Notification/ │ │ ├── INotification.cs │ │ └── NotificationAction.cs │ ├── NotifyPropertyChanged.cs │ ├── Recent/ │ │ ├── IRecentItem.cs │ │ ├── IRecentList.cs │ │ └── RecentAction.cs │ ├── Services/ │ │ ├── Binder.cs │ │ ├── IAudioPlayer.cs │ │ ├── IBinder.cs │ │ ├── IClipboardService.cs │ │ ├── IDialogService.cs │ │ ├── IFpsManager.cs │ │ ├── IIconSet.cs │ │ ├── IMainWindow.cs │ │ ├── IMessageProvider.cs │ │ ├── IModule.cs │ │ ├── IPlatformServices.cs │ │ ├── IPreviewWindow.cs │ │ ├── IRegionProvider.cs │ │ ├── ISystemTray.cs │ │ ├── IVideoSourcePicker.cs │ │ ├── IWebCamProvider.cs │ │ ├── IWebcamCapture.cs │ │ ├── IWebcamItem.cs │ │ └── ServiceProvider.cs │ ├── Settings/ │ │ ├── Alignment.cs │ │ ├── AudioSettings.cs │ │ ├── MouseOverlaySettings.cs │ │ ├── PositionedOverlaySettings.cs │ │ ├── PropertyStore.cs │ │ ├── ProxySettings.cs │ │ ├── StepsSettings.cs │ │ ├── TextOverlaySettings.cs │ │ └── VideoSettings.cs │ ├── SoundKind.cs │ ├── SyncContextManager.cs │ ├── UploadResult.cs │ ├── Video/ │ │ ├── IVideoConverter.cs │ │ ├── IVideoFileWriter.cs │ │ ├── IVideoItem.cs │ │ ├── IVideoSourceProvider.cs │ │ ├── IVideoWriterItem.cs │ │ ├── IVideoWriterProvider.cs │ │ ├── RecorderMode.cs │ │ ├── VideoConverterParams.cs │ │ └── VideoWriterArgs.cs │ └── WindowClosedException.cs ├── Captura.Console/ │ ├── App.config │ ├── Captura.Console.csproj │ ├── CmdOptions/ │ │ ├── CommonCmdOptions.cs │ │ ├── FFMpegCmdOptions.cs │ │ ├── ICmdlineVerb.cs │ │ ├── ListCmdOptions.cs │ │ ├── ShotCmdOptions.cs │ │ ├── StartCmdOptions.cs │ │ ├── UploadCmdOptions.cs │ │ ├── UploadService.cs │ │ └── VerbsModule.cs │ ├── ConsoleLister.cs │ ├── ConsoleManager.cs │ ├── FFmpegConsoleManager.cs │ ├── Program.cs │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ └── launchSettings.json │ └── User32.cs ├── Captura.Core/ │ ├── ApiKeys.cs │ ├── Captura.Core.csproj │ ├── CoreModule.cs │ ├── Extensions.cs │ ├── FpsManager.cs │ ├── MaterialDesignIcons.cs │ ├── Models/ │ │ ├── AroundMouseItem.cs │ │ ├── AroundMouseSourceProvider.cs │ │ ├── Discard/ │ │ │ ├── DiscardWriter.cs │ │ │ ├── DiscardWriterItem.cs │ │ │ └── DiscardWriterProvider.cs │ │ ├── EditorWriter.cs │ │ ├── ImageWriterItems/ │ │ │ ├── ClipboardWriter.cs │ │ │ ├── DiskWriter.cs │ │ │ └── ImageUploadWriter.cs │ │ ├── NoVideoItem.cs │ │ ├── NoVideoSourceProvider.cs │ │ ├── Notifications/ │ │ │ ├── FileSaveNotification.cs │ │ │ ├── ImageUploadNotification.cs │ │ │ └── TextNotification.cs │ │ ├── Recents/ │ │ │ ├── FileRecentItem.cs │ │ │ ├── FileRecentSerializer.cs │ │ │ ├── IRecentItemSerializer.cs │ │ │ ├── RecentFileType.cs │ │ │ ├── RecentListRepository.cs │ │ │ ├── UploadRecentItem.cs │ │ │ └── UploadRecentSerializer.cs │ │ ├── RecorderState.cs │ │ ├── StepWriters/ │ │ │ ├── ImageFolderWriter.cs │ │ │ ├── ImageFolderWriterItem.cs │ │ │ └── StepsVideoWriterItem.cs │ │ ├── UpdateCheckers/ │ │ │ ├── DevUpdateChecker.cs │ │ │ ├── IUpdateChecker.cs │ │ │ └── UpdateChecker.cs │ │ ├── WebcamSourceProvider.cs │ │ └── WebcamVideoItem.cs │ ├── NoWebcamItem.cs │ ├── Settings/ │ │ ├── Models/ │ │ │ ├── AroundMouseSettings.cs │ │ │ ├── ScreenShotSettings.cs │ │ │ ├── SoundSettings.cs │ │ │ ├── TraySettings.cs │ │ │ ├── VisualSettings.cs │ │ │ └── WebcamOverlaySettings.cs │ │ └── Settings.cs │ ├── ViewModels/ │ │ ├── RecordingModel.cs │ │ ├── RecordingModelParams.cs │ │ ├── ScreenShotModel.cs │ │ ├── TimerModel.cs │ │ ├── ViewModelBase.cs │ │ └── WebcamModel.cs │ ├── WebcamImageProvider.cs │ ├── WebcamOverlay.cs │ └── WithPreviewWriter.cs ├── Captura.FFmpeg/ │ ├── ArgsBuilder/ │ │ ├── FFmpegArgs.cs │ │ ├── FFmpegArgsBuilder.cs │ │ ├── FFmpegInputArgs.cs │ │ └── FFmpegOutputArgs.cs │ ├── Audio/ │ │ ├── FFmpegAudioArgsProvider.cs │ │ ├── FFmpegAudioItem.cs │ │ └── FFmpegAudioWriter.cs │ ├── Captura.FFmpeg.csproj │ ├── DownloadFFmpeg.cs │ ├── FFMpegLogItem.cs │ ├── FFmpegDownloaderProgress.cs │ ├── FFmpegDownloaderState.cs │ ├── FFmpegException.cs │ ├── FFmpegModule.cs │ ├── FFmpegNotFoundException.cs │ ├── FFmpegService.cs │ ├── FFmpegTrimmer.cs │ ├── FFmpgDownloadModel.cs │ ├── IFFmpegLogEntry.cs │ ├── IFFmpegLogRepository.cs │ ├── IFFmpegViewsProvider.cs │ ├── Settings/ │ │ ├── FFMpegSettings.cs │ │ ├── FFmpegCodecSettings.cs │ │ └── X264Settings.cs │ └── Video/ │ ├── Codecs/ │ │ ├── CustomFFmpegVideoCodec.cs │ │ ├── CustomStreamingVideoCodec.cs │ │ ├── FFmpegVideoCodec.cs │ │ ├── NvencVideoCodec.cs │ │ ├── QsvHevcVideoCodec.cs │ │ ├── StreamingVideoCodec.cs │ │ ├── TempFileVideoCodec.cs │ │ ├── TwitchVideoCodec.cs │ │ ├── Vp8VideoCodec.cs │ │ ├── Vp9VideoCodec.cs │ │ ├── X264VideoCodec.cs │ │ ├── XvidVideoCodec.cs │ │ └── YouTubeLiveVideoCodec.cs │ ├── FFmpegGifConverter.cs │ ├── FFmpegReplayWriter.cs │ ├── FFmpegVideoConverter.cs │ ├── FFmpegVideoWriter.cs │ ├── FFmpegVideoWriterArgs.cs │ ├── FFmpegWriterProvider.cs │ └── StreamingWriterProvider.cs ├── Captura.Fakes/ │ ├── Captura.Fakes.csproj │ ├── FakeAudioPlayer.cs │ ├── FakeFFmpegLogRepository.cs │ ├── FakeFFmpegViewsProvider.cs │ ├── FakeMessageProvider.cs │ ├── FakePreviewWindow.cs │ ├── FakeRegionProvider.cs │ ├── FakeSystemTray.cs │ ├── FakeVideoSourcePicker.cs │ ├── FakeWindowProvider.cs │ └── FakesModule.cs ├── Captura.Hotkeys/ │ ├── Captura.Hotkeys.csproj │ ├── HotKey.cs │ ├── HotKeyManager.cs │ ├── HotkeyModel.cs │ ├── IHotkeyActor.cs │ ├── IHotkeyListener.cs │ ├── Kernel32.cs │ ├── Service.cs │ ├── ServiceName.cs │ └── User32.cs ├── Captura.Imgur/ │ ├── Captura.Imgur.csproj │ ├── IImgurApiKeys.cs │ ├── ImgurData.cs │ ├── ImgurRefreshTokenResponse.cs │ ├── ImgurResponse.cs │ ├── ImgurSettings.cs │ ├── ImgurUploadResponse.cs │ └── ImgurUploader.cs ├── Captura.Loc/ │ ├── Captura.Loc.csproj │ ├── ILocalizationProvider.cs │ ├── LanguageFields.cs │ ├── LanguageManager.cs │ ├── Languages/ │ │ ├── ar.json │ │ ├── be.json │ │ ├── ca.json │ │ ├── cs.json │ │ ├── da.json │ │ ├── de.json │ │ ├── el.json │ │ ├── en.json │ │ ├── es.json │ │ ├── fi.json │ │ ├── fr.json │ │ ├── he.json │ │ ├── hi.json │ │ ├── id.json │ │ ├── is.json │ │ ├── it.json │ │ ├── ja.json │ │ ├── kab.json │ │ ├── ko.json │ │ ├── ml.json │ │ ├── nl.json │ │ ├── no.json │ │ ├── pl.json │ │ ├── pt-BR.json │ │ ├── pt.json │ │ ├── ro.json │ │ ├── ru.json │ │ ├── sl.json │ │ ├── sv.json │ │ ├── th.json │ │ ├── tr.json │ │ ├── uk.json │ │ ├── vi.json │ │ ├── zh-CN.json │ │ └── zh-TW.json │ ├── ObjectLocalizer.cs │ └── TextLocalizer.cs ├── Captura.MouseKeyHook/ │ ├── Captura.MouseKeyHook.csproj │ ├── IMouseKeyHook.cs │ ├── KeyOverlay.cs │ ├── KeyRecord/ │ │ ├── DummyKeyRecord.cs │ │ ├── IKeyRecord.cs │ │ ├── KeyRecord.cs │ │ ├── KeyRecords.cs │ │ └── RepeatKeyRecord.cs │ ├── KeymapViewModel.cs │ ├── Models/ │ │ ├── Keymap.cs │ │ ├── KeystrokesSettings.cs │ │ ├── MappingGroup.cs │ │ ├── ModifierStates.cs │ │ └── MouseClickSettings.cs │ ├── MouseClickOverlay.cs │ ├── MouseKeyHook.cs │ ├── MouseKeyOverlay.cs │ ├── ScrollOverlay.cs │ ├── Steps/ │ │ ├── IRecordStep.cs │ │ ├── KeyModifiedStep.cs │ │ ├── KeyStep.cs │ │ ├── MouseClickStep.cs │ │ ├── MouseDragBeginStep.cs │ │ ├── MouseDragStep.cs │ │ ├── ScrollStep.cs │ │ └── StepsRecorder.cs │ └── keymaps/ │ ├── de.json │ ├── en-IN.json │ ├── en.json │ ├── ml.json │ ├── schema.json │ └── tr.json ├── Captura.NAudio/ │ ├── Captura.NAudio.csproj │ ├── MixedAudioProvider.cs │ ├── NAudioItem.cs │ ├── NAudioNotificationClient.cs │ ├── NAudioProvider.cs │ ├── NAudioSource.cs │ ├── WasapiCaptureProvider.cs │ ├── WasapiLoopbackCaptureProvider.cs │ └── WaveFormatExtensions.cs ├── Captura.SharpAvi/ │ ├── AviCodec.cs │ ├── AviWriter.cs │ ├── Captura.SharpAvi.csproj │ ├── IAudioProviderAdapter.cs │ ├── SharpAviItem.cs │ └── SharpAviWriterProvider.cs ├── Captura.ViewCore/ │ ├── Captura.ViewCore.csproj │ ├── FFmpegLog.cs │ ├── FileContentItem.cs │ ├── FileNameFormatGroup.cs │ ├── FileNameFormatItem.cs │ ├── HotkeyActor.cs │ ├── RememberByName.cs │ ├── SoundsViewModelItem.cs │ ├── ViewCoreModule.cs │ └── ViewModels/ │ ├── AudioSourceViewModel.cs │ ├── CensorOverlaysViewModel.cs │ ├── CrashLogsViewModel.cs │ ├── CustomImageOverlaysViewModel.cs │ ├── CustomOverlaysViewModel.cs │ ├── FFmpegCodecsViewModel.cs │ ├── FFmpegLogViewModel.cs │ ├── FFmpgDownloadViewModel.cs │ ├── FileNameFormatViewModel.cs │ ├── HotkeysViewModel.cs │ ├── LicensesViewModel.cs │ ├── MainViewModel.cs │ ├── OverlayListViewModel.cs │ ├── ProxySettingsViewModel.cs │ ├── RecentViewModel.cs │ ├── RecordingViewModel.cs │ ├── ScreenShotViewModel.cs │ ├── SoundsViewModel.cs │ ├── UpdateCheckerViewModel.cs │ ├── VideoSourcesViewModel.cs │ ├── VideoWritersViewModel.cs │ ├── ViewConditionsModel.cs │ └── YouTubeUploaderViewModel.cs ├── Captura.Windows/ │ ├── Captura.Windows.csproj │ ├── Capture/ │ │ ├── DxgiTargetDeviceContext.cs │ │ ├── GdiTargetDeviceContext.cs │ │ ├── ITargetDeviceContext.cs │ │ ├── MouseCursor.cs │ │ ├── RegionProvider.cs │ │ ├── ScreenShot.cs │ │ ├── WindowProvider.cs │ │ └── WindowScreenShotBackdrop.cs │ ├── ClipboardService.cs │ ├── DesktopDuplication/ │ │ ├── AcquireResult.cs │ │ ├── DeskDuplFullScreenImageProvider.cs │ │ ├── DeskDuplImageProvider.cs │ │ ├── DeskDuplOutputEntry.cs │ │ ├── DesktopDuplicator.cs │ │ ├── DuplCapture.cs │ │ ├── FrameGrabber.cs │ │ ├── FullScreenDesktopDuplicator.cs │ │ └── MousePointer/ │ │ ├── ColorPointerShape.cs │ │ ├── DXMousePointer.cs │ │ ├── IPointerShape.cs │ │ ├── MaskedColorPointerShape.cs │ │ ├── MaskedPointerShape.cs │ │ └── MonochromePointerShape.cs │ ├── DialogService.cs │ ├── Imaging/ │ │ ├── Direct2D/ │ │ │ ├── D3D9PreviewAssister.cs │ │ │ ├── Direct2DEditor.cs │ │ │ ├── Direct2DEditorSession.cs │ │ │ ├── Direct2DFont.cs │ │ │ ├── Direct2DImage.cs │ │ │ └── Texture2DFrame.cs │ │ └── Drawing/ │ │ ├── DrawingFont.cs │ │ ├── DrawingFrame.cs │ │ ├── DrawingImage.cs │ │ ├── DrawingImagingSystem.cs │ │ ├── GraphicsBitmapLoader.cs │ │ ├── GraphicsEditor.cs │ │ └── GraphicsExtensions.cs │ ├── MediaFoundation/ │ │ ├── MfAudioItem.cs │ │ ├── MfAudioWriter.cs │ │ ├── MfColorConverter.cs │ │ ├── MfItem.cs │ │ ├── MfManager.cs │ │ ├── MfWriter.cs │ │ ├── MfWriterProvider.cs │ │ ├── PackedLong.cs │ │ └── RateControlMode.cs │ ├── Native/ │ │ ├── DwmApi.cs │ │ ├── EnumWindowsProc.cs │ │ ├── Enums/ │ │ │ ├── DrawIconExFlags.cs │ │ │ ├── FileOperationFlags.cs │ │ │ ├── FileOperationType.cs │ │ │ ├── GetWindowEnum.cs │ │ │ ├── GetWindowLongValue.cs │ │ │ ├── SetWindowPositionFlags.cs │ │ │ └── WindowStyles.cs │ │ ├── Gdi32.cs │ │ ├── Kernel32.cs │ │ ├── NativeExtensions.cs │ │ ├── Shell32.cs │ │ ├── Structs/ │ │ │ ├── CursorInfo.cs │ │ │ ├── IconInfo.cs │ │ │ ├── RECT.cs │ │ │ └── ShFileOpStruct.cs │ │ ├── UnsafeBitmap.cs │ │ └── User32.cs │ ├── ScreenWrapper.cs │ ├── Webcam/ │ │ ├── CaptureWebcam.cs │ │ ├── DummyForm.cs │ │ ├── Filter.cs │ │ ├── GraphState.cs │ │ ├── README.md │ │ ├── WebcamCapture.cs │ │ ├── WebcamItem.cs │ │ └── WebcamProvider.cs │ ├── Window.cs │ ├── WindowsModule.cs │ ├── WindowsPlatformServices.cs │ └── WindowsSettings.cs ├── Captura.YouTube/ │ ├── Captura.YouTube.csproj │ ├── IYouTubeApiKeys.cs │ ├── YouTubePrivacyStatus.cs │ ├── YouTubeUploadRequest.cs │ └── YouTubeUploader.cs ├── Captura.sln ├── Directory.Build.props ├── PostBuild.targets ├── Screna/ │ ├── AudioFileWriter.cs │ ├── AudioRecorder.cs │ ├── Extensions.cs │ ├── ImageProviders/ │ │ ├── AroundMouseImageProvider.cs │ │ └── OverlayedImageProvider.cs │ ├── MultiDisposeFrame.cs │ ├── MultiRecorder.cs │ ├── Overlays/ │ │ ├── CensorOverlay.cs │ │ ├── CustomImageOverlay.cs │ │ ├── CustomOverlay.cs │ │ ├── ElapsedOverlay.cs │ │ ├── ImageOverlay.cs │ │ ├── MousePointerOverlay.cs │ │ ├── Settings/ │ │ │ ├── CensorOverlaySettings.cs │ │ │ ├── CustomImageOverlaySettings.cs │ │ │ ├── CustomOverlaySettings.cs │ │ │ └── ImageOverlaySettings.cs │ │ └── TextOverlay.cs │ ├── Recorder.cs │ ├── RegionItem.cs │ ├── ScreenShot.cs │ ├── Screna.csproj │ ├── Timing.cs │ ├── VideoItems/ │ │ ├── FullScreenItem.cs │ │ ├── ScreenItem.cs │ │ ├── WaveItem.cs │ │ └── WindowItem.cs │ └── VideoSourceProviders/ │ ├── FullScreenSourceProvider.cs │ ├── RegionSourceProvider.cs │ ├── ScreenSourceProvider.cs │ ├── VideoSourceProviderBase.cs │ └── WindowSourceProvider.cs └── Tests/ ├── AudioFileWriterTests.cs ├── ConsoleStartTests.cs ├── Fixtures/ │ ├── AppRunnerFixture.cs │ ├── MoqFixture.cs │ ├── TestCollection.cs │ └── TestManagerFixture.cs ├── ImageProviderTests.cs ├── Models/ │ └── FakePropertyStore.cs ├── PropertyStoreTests.cs ├── RecorderTests.cs ├── ScreenShotTests.cs ├── Tests.csproj └── WindowTests.cs ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto *.cs diff=csharp ================================================ FILE: .github/FUNDING.yml ================================================ github: [MathewSachin] custom: https://mathewsachin.github.io/Captura/donate ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: bug assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. Windows 8.1] - RAM: [e.g. 4GB] - CPU: [e.g. i5 2GHz] - Graphic Card: - Captura Version: [e.g. v8.0.0] **Additional context** Add any other context about the problem here like FFmpeg Log or error messages. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: enhancement assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .github/ISSUE_TEMPLATE/question.md ================================================ --- name: Question about: For asking questions or discussions title: '' labels: question assignees: '' --- ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ Please don't send pull-requests for translation. Use the [Crowdin](https://crowdin.com/project/captura) project instead. ================================================ FILE: .gitignore ================================================ # Build Output bin/ obj/ # NuGet *.nupkg packages/ # Visual Studio .vs/ .vscode/ publish/ TestResults/ *.suo *.user # Cake /tools /temp/ /dist/ *.pfx ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ### Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ### Our Standards Examples of behavior that contributes to creating a positive environment include: - Using welcoming and inclusive language - Being respectful of differing viewpoints and experiences - Gracefully accepting constructive criticism - Focusing on what is best for the community - Showing empathy towards other community members Examples of unacceptable behavior by participants include: - Trolling, insulting/derogatory comments, and personal or political attacks - Public or private harassment - Publishing others' private information, such as a physical or electronic address, without explicit permission - Other conduct which could reasonably be considered inappropriate in a professional setting ### Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ### Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ### Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at `mathew DOT sachin DOT git AT outlook DOT com`. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ### Attribution This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.4, available at http://contributor-covenant.org/version/1/4 ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing ### Star :star: The easiest way to show your support is by starring the repository ### Reporting Bugs - Check the [FAQ](https://mathewsachin.github.io/Captura/faq). - Check if an issue has already been reported. If so, comment on it and provide further info if any. - Follow the `Bug Report` issue template and provide relevant information. ### Get in touch You can chat with us on [Gitter](https://gitter.im/MathewSachin/Captura). ### Contributing Code - Make sure to follow the code style followed throughout the project. - If you add a new dependency, make sure it is compatible with MIT license. *e.g. GPL is not compatible with MIT license.* Also, add the license file to the **licenses** folder. - If you want to add a new feature, discuss it first by opening an issue on GitHub whether it aligns with the goals of the project. - If possible, write tests. ### Translation Don't send pull-requests for translation. Use [Crowdin](https://crowdin.com/project/captura) instead. If you want to add a new language, open a discussion on the Crowdin project or a new issue here on GitHub to let me know. ### Testing A lot of help is needed in this area. Writing tests or just manually testing and reporting or fixing the issues found would be a great help. ### Website The website in written in Angular and resides in a [separate repository](https://github.com/MathewSachin/ng-captura). ### Donation :heavy_dollar_sign: You can donate on [PayPal](https://www.paypal.me/MathewSachin). You can see the list of donations on the [website](https://mathewsachin.github.io/Captura/donate). ### Spread the word Recommend to others, write reviews, etc. ================================================ FILE: Inno.iss ================================================ ; Override version before compiling ;#define MyAppVersion "6.0.0" #define MyAppName "Captura" #define MyAppPublisher "Mathew Sachin" #define MyAppURL "https://MathewSachin.github.io/Captura" #define MyAppExeName "captura.exe" [Setup] AppId={{C1670C5E-5042-4300-9491-6BFFF963823F} AppName={#MyAppName} AppVersion={#MyAppVersion} AppVerName={#MyAppName} v{#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} DefaultDirName={pf}\{#MyAppName} DisableProgramGroupPage=yes OutputBaseFilename=Captura-Setup Compression=lzma SolidCompression=yes SetupIconFile=src/Captura/Images/Captura.ico OutputDir=temp [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl" Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl" Name: "french"; MessagesFile: "compiler:Languages\French.isl" Name: "german"; MessagesFile: "compiler:Languages\German.isl" Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl" Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl" Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl" Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl" Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl" Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked ; Remove Assemblies from previous installation to prevent conflicts [InstallDelete] Type: files; Name: "{app}\lib\*.dll" [Files] Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs [Icons] Name: "{commonprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent ================================================ FILE: LICENSE.md ================================================ MIT License Copyright (c) 2020 Mathew Sachin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ ![Captura](https://mathewsachin.github.io/Captura/assets/Banner.png) [![Master Build Status](https://img.shields.io/appveyor/ci/MathewSachin/Captura/master.svg?style=flat-square&logo=appveyor)](https://ci.appveyor.com/project/MathewSachin/Captura) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.md) [![Chat](https://img.shields.io/badge/chat-on_gitter-yellow.svg?style=flat-square&logo=gitter)](https://gitter.im/MathewSachin/Captura) [![Downloads](https://img.shields.io/github/downloads/MathewSachin/Captura/total.svg?style=flat-square)](https://mathewsachin.github.io/Captura/download) [![PayPal Donate](https://img.shields.io/badge/donate-PayPal-orange.svg?style=flat-square&logo=paypal)](https://mathewsachin.github.io/Captura/donate) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/captura/localized.svg)](https://crowdin.com/project/captura) © [Copyright 2019](LICENSE.md) Mathew Sachin :link: Capture Screen, WebCam, Audio, Cursor, Mouse Clicks and Keystrokes. ## Features - Take ScreenShots - Capture ScreenCasts (Avi/Gif/Mp4) - Capture with/without Mouse Cursor - Capture Specific Regions, Screens or Windows - Capture Mouse Clicks or Keystrokes - Mix Audio recorded from Microphone and Speaker Output - Capture from WebCam. - Can be used from [Command-line](https://mathewsachin.github.io/Captura/cmdline) (*BETA*). - Available in [multiple languages](https://mathewsachin.github.io/Captura/translation) - Configurable [Hotkeys](https://mathewsachin.github.io/Captura/hotkeys) ## Installation [latest]: https://github.com/MathewSachin/Captura/releases/latest Portable and Setup builds for the latest release can be downloaded from [here][latest]. ### Chocolatey ```powershell choco install captura -y ``` ### Dev Builds See the [Continuous Integration page](docs/CI.md). ## Docs [Build Notes](docs/Build.md) | [System Requirements](docs/System-Requirements.md) | [Contributing](CONTRIBUTING.md) [ScreenShots](docs/Screenshots) | [Command-line](docs/Cmdline/README.md) | [Hotkeys](https://mathewsachin.github.io/Captura/hotkeys) [FAQ](docs/FAQ.md) | [Code of Conduct](CODE_OF_CONDUCT.md) | [Changelog](docs/Changelogs/README.md) [Continuous Integration](docs/CI.md) | [FFmpeg](docs/FFmpeg.md) ## License [MIT License](LICENSE.md) Check [here](licenses/) for licenses of dependencies. ================================================ FILE: SUPPORT.md ================================================ # Support ## GitHub Issues Use [GitHub issues](https://github.com/MathewSachin/Captura/issues) for Bug Reports, Feature Requests and Questions. ## Gitter [![Chat](https://img.shields.io/badge/chat-on_gitter-yellow.svg?style=flat-square)](https://gitter.im/MathewSachin/Captura) ## Mail Try to use GitHub Issues instead of mailing, it allows us to track your Feature Requests and Bug Reports better. Use mail only in cases where personal information is involved. Please specify what you want help with in the mail itself instead of asking for other contact information like phone number or social account details. Avoid sending mails regarding selling Captura or making a product similar to Captura as those won't be entertained. `mathew DOT sachin DOT git AT outlook DOT com` ================================================ FILE: appveyor.yml ================================================ version: 0.0.{build} branches: except: - l10n_master # Crowdin - gh-pages # Website image: Visual Studio 2019 configuration: - Debug - Release # Used in build.cake environment: imgur_client_id: secure: Y/2WUSisk7oLSQNY1YzUxw== yt_client_id: secure: CPwUWOhTyZ2IiE+lvVilTKQz1h8sbn7FmkTJvtTlY6mJf2pDlfDhFmhDk1i47M9OPnD4y8a8BlB6yfkpVt/0U/PODAXPzFR0QuOWIfJvltc= yt_client_secret: secure: fsl/BRldjlmEJCroWa0iqw5tAxbGx84BbHT3BpzaeX4= choco_key: secure: h5jOVeiDmjLnF3EotkOhBFJharX/9TWx6OWykiXn30pWSIfVjSvAaCJM1Y48zjXr git_key: secure: eRA1NCG/iXaLTQaBbe2X5Tpje+2Hvk3WOPEP3ZLPFMqW7ZS0ZMTb4UXpw7w59pbc install: - dotnet tool install -g Cake.Tool --version 0.32.1 - choco install innosetup -y --no-progress # Build using Cake build_script: - ps: >- $tag = $env:APPVEYOR_REPO_TAG_NAME if ($tag -ne $null) { $env:prerelease = $tag.Contains("-") if ($tag -match "^build-number-") { Write-Host "Build number tag is skipped" Exit-AppveyorBuild } else { dotnet-cake --target=CI --configuration=$env:CONFIGURATION --build_version=$tag } } else { $version = "v0.0." + $env:APPVEYOR_BUILD_NUMBER dotnet-cake --target=CI --configuration=$env:CONFIGURATION --build_version=$version } test: off artifacts: - path: temp/Captura-Portable.zip name: Portable - path: temp/Captura-Setup.exe name: Setup - path: temp/captura.*.nupkg name: Chocolatey deploy: - provider: GitHub tag: $(APPVEYOR_REPO_TAG_NAME) release: Captura $(APPVEYOR_REPO_TAG_NAME) prerelease: $(prerelease) description: "[Changelog](https://github.com/MathewSachin/Captura/tree/master/docs/Changelogs)" auth_token: $(git_key) artifact: Portable, Setup on: configuration: Release appveyor_repo_tag: true - provider: NuGet server: https://chocolatey.org api_key: $(choco_key) artifact: Chocolatey on: configuration: Release appveyor_repo_tag: true ================================================ FILE: build.cake ================================================ #tool nuget:?package=xunit.runner.console&version=2.4.1 #l "scripts/backup.cake" #l "scripts/constants.cake" #l "scripts/choco.cake" #l "scripts/apikeys.cake" #l "scripts/version.cake" using System.Collections.Generic; #region Fields readonly var target = Argument("target", "Default"); readonly var configuration = Argument("configuration", Release); #endregion #region Functions void PopulateOutput() { // Copy License files CopyDirectory(licensesFolder, distFolder + Directory("licenses")); var consoleBinFolder = sourceFolder + Directory("Captura.Console/bin") + Directory(configuration); var uiBinFolder = sourceFolder + Directory("Captura/bin") + Directory(configuration); // Copy Languages CopyDirectory(uiBinFolder + Directory("Languages"), distFolder + Directory("languages")); // Copy executables and config files CopyFiles(consoleBinFolder.Path + "/*.exe*", distFolder); CopyFiles(uiBinFolder.Path + "/*.exe*", distFolder); // Copy Keymap files CopyDirectory(uiBinFolder + Directory("keymaps"), distFolder + Directory("keymaps")); // For Debug builds if (configuration != Release) { // Assemblies, Symbol Files and XML Documentation foreach (var extension in new [] { ".dll", ".pdb", ".xml" }) { CopyFiles(consoleBinFolder.Path + "/*" + extension, distFolder); CopyFiles(uiBinFolder.Path + "/*" + extension, distFolder); } } else { CopyDirectory(consoleBinFolder + Directory("lib"), distFolder + Directory("lib")); CopyDirectory(uiBinFolder + Directory("lib"), distFolder + Directory("lib")); } } void PackPortable() { // Portable build directories var settingsDir = distFolder + Directory("Settings"); var codecsDir = distFolder + Directory("Codecs"); CreateDirectory(settingsDir); CreateDirectory(codecsDir); Zip(distFolder, PortablePath); var dirDeleteSettings = new DeleteDirectorySettings { Recursive = true, Force = true }; DeleteDirectory(settingsDir, dirDeleteSettings); DeleteDirectory(codecsDir, dirDeleteSettings); } #endregion #region Setup / Teardown Setup(context => { EnsureDirectoryExists(tempFolder); EnsureDirectoryExists(distFolder); HandleVersion(); if (configuration == Release) { EmbedApiKeys(); } }); Teardown(context => { RestoreBackups(); }); #endregion #region Tasks var buildTask = Task("Build") .Does(() => { MSBuild(slnPath, settings => { settings.SetConfiguration(configuration) .SetVerbosity(Verbosity.Minimal) .WithTarget("Rebuild") .WithRestore() .UseToolVersion(MSBuildToolVersion.VS2019); }); }); var cleanOutputTask = Task("Clean-Output").Does(() => CleanDirectory(distFolder)); var populateOutputTask = Task("Populate-Output") .IsDependentOn(cleanOutputTask) .IsDependentOn(buildTask) .Does(() => PopulateOutput()); var packPortableTask = Task("Pack-Portable") .IsDependentOn(populateOutputTask) .Does(() => PackPortable()); var packSetupTask = Task("Pack-Setup") .IsDependentOn(populateOutputTask) .Does(() => { const string InnoScriptPath = "Inno.iss"; InnoSetup(InnoScriptPath, new InnoSetupSettings { QuietMode = InnoSetupQuietMode.Quiet, ArgumentCustomization = Args => Args.Append($"/DMyAppVersion={version}") }); }); var packChocoTask = Task("Pack-Choco") .IsDependentOn(packPortableTask) .Does(() => PackChoco()); var testTask = Task("Test") .IsDependentOn(buildTask) .Does(() => XUnit2(sourceFolder + File($"Tests/bin/{configuration}/**/Captura.Tests.dll"))); var defaultTask = Task("Default") .IsDependentOn(packPortableTask) .IsDependentOn(packSetupTask) .IsDependentOn(packChocoTask); #endregion Task("CI") .IsDependentOn(testTask) .IsDependentOn(packPortableTask) .IsDependentOn(packSetupTask) .IsDependentOn(packChocoTask) .Does(() => { }); // Start RunTarget(target); ================================================ FILE: choco/captura.nuspec ================================================ captura 8.0.0 Captura Mathew Sachin https://MathewSachin.github.io/Captura https://github.com/MathewSachin/Captura https://raw.githubusercontent.com/MathewSachin/Captura/master/src/Captura/Images/Logo.png https://github.com/MathewSachin/Captura/blob/master/LICENSE.md https://github.com/MathewSachin/Captura/tree/master/choco https://github.com/MathewSachin/Captura/issues https://MathewSachin.github.io/Captura https://gitter.im/MathewSachin/Captura (c) 2018 Mathew Sachin captura screen capture recording loopback screenshot screencast Capture Screen/Audio/Cursor/Clicks/Keystrokes Captura is an application to capture Screen/Audio/Cursor/Clicks/Keystrokes. [Changelog](https://MathewSachin.github.io/Captura/changelog) ================================================ FILE: choco/tools/chocolateyinstall.ps1 ================================================ $params = @{ 'PackageName' = 'Captura'; 'Url' = "https://github.com/MathewSachin/Captura/releases/download/$tag/Captura-Portable.zip"; 'UnzipLocation' = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"; 'Checksum' = $checksum; 'ChecksumType' = 'sha256'; }; Install-ChocolateyZipPackage @params ================================================ FILE: crowdin.yml ================================================ files: - source: /src/Captura.Loc/Languages/en.json translation: /src/Captura.Loc/Languages/%two_letters_code%.json languages_mapping: two_letters_code: zh-CN: zh-CN zh-TW: zh-TW pt-BR: pt-BR ================================================ FILE: docs/Acknowledgements.md ================================================ # Acknowledgements ## Tools and Services ### Resharper Kudos to Jetbrains for providing open-source license for [Resharper Ultimate](https://www.jetbrains.com/resharper/). Resharper makes development much intutive and easier. You should really check it out. If you become a regular contributor to Captura, you may request for the Resharper license. ### Crowdin Great thanks to [Crowdin](https://crowdin.com/) for providing open-source license. The translation for Captura is done on Crowdin. Also, thanks to everyone who contributed the translations. ### AppVeyor We use [AppVeyor](https://www.appveyor.com/) for Continuous Integration. The build and release processes run there. It's free for open-source projects and especially good for .NET projects. ### GitHub I can't thank [GitHub](https://github.com/) enough for being an open platform for developers. The source code and the website are both hosted here. ### Cake Build [Cake](https://cakebuild.net/) allows us to write our build scripts in C# instead of using other scripting languages. ### Visual Studio Community [Visual Studio IDE](https://visualstudio.microsoft.com/) for free for open-source and small organisations. ### Visual Studio Code [Visual Studio Code](https://code.visualstudio.com) is an open-source text editor used to build the website and write the documentation. ### Inno Setup Setup files for Captura are built using [Inno Setup](http://www.jrsoftware.org/isinfo.php). ## Libraries ### CommandLineParser [GitHub](https://github.com/commandlineparser/commandline/) - [MIT License](https://github.com/commandlineparser/commandline/blob/master/License.md) ``` NuGet Install CommandLineParser ``` ### CroppingAdorner [CodeProject Article](https://www.codeproject.com/Articles/23158/A-Photoshop-like-Cropping-Adorner-for-WPF) - [Code Project Open License (CPOL)](https://www.codeproject.com/info/cpol10.aspx) ### DirectShowLib [SourceForge](http://directshownet.sourceforge.net/) ### FFmpeg [Website](https://ffmpeg.org/) ### MouseKeyHook [GitHub](https://github.com/gmamaladze/globalmousekeyhook) - [MIT License](https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/LICENSE.txt) ``` nuget install MouseKeyHook ``` ### MUI.Extended.Toolkit [GitHub](https://github.com/samoatesgames/mui.extended.toolkit) - [MIT License](https://github.com/samoatesgames/mui.extended.toolkit/blob/master/LICENSE) ### MUI [GitHub](https://github.com/firstfloorsoftware/mui) - [MS-PL](https://github.com/firstfloorsoftware/mui/blob/master/LICENSE.md) ### NAudio [GitHub](https://github.com/naudio/NAudio) - [MS-PL](https://github.com/naudio/NAudio/blob/master/license.txt) ### Newtonsoft.Json [Website](https://www.newtonsoft.com/json) - [GitHub](https://github.com/JamesNK/Newtonsoft.Json) - [MIT License](https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md) ### Ooki.Dialogs [Website](http://www.ookii.org/software/dialogs/) ### ReactiveProperty [GitHub](https://github.com/runceel/ReactiveProperty) ### ScreenToGif [Website](https://www.screentogif.com/) ### SharpAvi [GitHub](https://github.com/baSSiLL/SharpAvi) ### SharpDX [GitHub](https://github.com/sharpdx/SharpDX) ### WPFNotifyIcon [Website](http://www.hardcodet.net/wpf-notifyicon) ### WpfToolkit [GitHub](https://github.com/xceedsoftware/wpftoolkit) ### Media Foundation .NET [SourceForge](http://mfnet.sourceforge.net/) ### ReactiveX [GitHub](https://github.com/dotnet/reactive) ================================================ FILE: docs/Build.md ================================================ # Building ## Setting up locally ### Prerequisites - Visual Studio 2019 or newer with .NET desktop development workload. - .Net Core 2.1 or greater - Cake tool Install: `dotnet tool install -g Cake.Tool --version 0.32.1` - Some features have other specific requirements, see [here](https://mathewsachin.github.io/Captura/sys-req). ### Steps 1. Clone `git clone https://github.com/MathewSachin/Captura.git` 2. Setup Api Keys. These are loaded from environment variables during development and embedded into the app on production builds. Environment Variable | Description ---------------------|------------- imgur_client_id | Imgur Client Id yt_client_id | YouTube Client Id yt_client_secret | YouTube Client Secret Imgur credentials are only required if you want to upload to Imgur. See [here](https://apidocs.imgur.com/) for more info. YouTube credentials are only required if you want to upload to YouTube. See [here](https://developers.google.com/youtube/registering_an_application) for more info. 3. Download FFmpeg from within the app or from https://ffmpeg.zeranoe.com/builds/ or use a custom build. 4. Now, you're good to go. You can build using Visual Studio or the [cake script](Cake.md). ================================================ FILE: docs/CI.md ================================================ # Continuous Integration We use [Appveyor](https://www.appveyor.com/) for CI. When a commit is pushed to the GitHub repository, AppVeyor clones the repo and builds and tests it using the Cake build script. If it is a tag build, the release is deployed to GitHub Releases as a draft and to Chocolatey. ### Getting dev builds > Dev builds can be unstable and should be used for testing purposes only. 1. Go to [AppVeyor project](https://ci.appveyor.com/project/MathewSachin/Captura/branch/master) page. 2. Select Build Configuration: **Debug** or **Release**. ![img](https://mathewsachin.github.io/Captura/assets/dev-builds/1.png) 3. Open **Artifacts** tab. ![img](https://mathewsachin.github.io/Captura/assets/dev-builds/2.png) 4. Download the Portable or Setup version according to your need. ![img](https://mathewsachin.github.io/Captura/assets/dev-builds/3.png) ================================================ FILE: docs/Cake.md ================================================ # Cake build script ### Installing Cake .NET Core 2.1 is required. ``` dotnet tool install -g Cake.Tool --version 0.32.1 ``` ### Running the build script ``` dotnet-cake ``` ### Arguments Option | Description ---------------|-------------- -build_version | Build version. Should be like v9.0.0 for stable and CI builds and like v9.0.0-beta3 for prerelease builds. AssemblyInfo.cs files are updated based on this value during build. -configuration | Configuration: Release or Debug -target | The Task to run in the build script. See build.cake ``` dotnet-cake --target=CI --configuration=Release ``` ================================================ FILE: docs/Changelogs/README.md ================================================ # Changelogs - [v9.0.0](v9.0.0.md) - [v8.0.0](v8.0.0.md) - [v7.0.1](v7.0.1.md) ================================================ FILE: docs/Changelogs/v7.0.1.md ================================================ # v7.0.1 **Fix:** FFmpeg download link gives 404. ================================================ FILE: docs/Changelogs/v8.0.0.md ================================================ # v8.0.0 > This changelog is incomplete. ### Audio / Video Sources - Stop Window capture when Window is closed. - **Fix:** Mouse cursor position is wrong after moving region selector. - **Fix:** Unable to resize Region Selector after stopping recording. - Desktop Duplication is supported with Variable Frame Rate Gif. - **Fix:** Desktop Duplication recording does not crash when Screen enters non-recordable mode. e.g. Sign-in screen. - Added an option to playback recorded audio in real-time in Config | Extras. - Record and ScreenShot buttons on Region Selector. - Added Window picker and Screen picker which prompt for selector on starting recording or taking screenshot. - More than 2 audio sources can be simultaneously recorded. - Audio sources can be changed during recording. A checkbox next to the Audio heading determines whether audio will be recorded. - Shows Error Message when bass.dll or bassmix.dll is not present. - Hide when Recording option is configured on Region Selector itself. - Refresh retains selected Audio/Video sources/codecs and Webcam. - Basic drawing support in Region Selector. ### Preview - Added option to Preview while recording. - Supports full screen view. ### Overlays - Overlays are now configured on a separate window. - Overlays can be positioned by dragging boxes over a Background on the window. - Separate colors for Right and Middle mouse click overlays. - Support for custom image overlays. - Overlay customization from UI is used in Console. - Option to display Mouse Pointer Overlay to make easier to track Mouse Pointer. - Added minimal mouse click animation. - Elapsed is separated from TextOverlays and can be toggled from Main View. ### FFmpeg - Option to resize FFmpeg output video size. - FFmpeg Log maintains multiple logs. - FFmpeg Log copies complete output to clipboard. - Multiple Custom FFmpeg Codecs. - Increased FFmpeg thread_queue_size - Ensure previous frame is written when writing asynchronously. ### Hotkey Window Separate window to manage hotkeys with option to add, delete or edit action and keys. ### Image Editor - Added a minimal image editor. - Added a new ScreenShot target: Editor. ### Image Cropper Added option to crop images. ### Audio / Video Trimmer Added option to trim Audio and Video. ### Translation Added new translations: - Japanese - Chinese (Simplified) - Chinese (Traditional) ### Other - **Fix:**captura shot failing for fullscreen screenshots. - **Fix:** Main window webcam preview position on high DPI. - Duration is considered after Start Delay has elapsed. - Duration and Start Delay are stored in Settings. - Added option to use System Proxy. - **Fix:** Mouse Cursor moves slowly when recording from Command-line - Webcam capture support from Command-line. - Option to Minimize to System Tray on Startup. - Option to Minimize to System Tray when Closed. - Add a Translator window to aid in translation. Can be opened from About tab. - More icons in the UI. - Multiple selectable Screenshot Save Locations. - Display Licenses in a Window. - Notification Stack - Added an Exception Dialog. - Stop Recorder when Frames are not being writen. This happens when either the FrameRate is too high or a codec is slow. No of frames to be written are checked with a maximum value to determine whether to stop recording. This helps prevent crash from 100% RAM usage and causing the system to hang. - Ability to delete uploaded images from Imgur ================================================ FILE: docs/Changelogs/v9.0.0.md ================================================ # v9.0.0 > Not released yet! - Translations updated. - Added Portuguese, Brazilian translation. - Fallback to NAudio for audio when BASS is not available. - Update check in footer. - Open Webcam preview window by clicking on small preview. - **Fix:** Recording failing due to `System can't keep up with the Recording. Frames are not being written. Retry again or try with a smaller region, lower Frame Rate or another Codec.` - Replaced the Gif encoder with FFmpeg Gif (Post-Processing) encoder. - Discard writer renamed to Preview Only and automatically shows Preview window on starting recording. - Use system confirmation dialog when deleting from recent list. - Added YouTube upload feature. Can be used from recent list context menu. - Remove notifications when notification stack hides. - Region dimension boxes on Main UI. - FFmpeg Log can be opened from Home page. - PasswordBox for Proxy and Streaming keys. - Region Selector can be Moved/Resized using Keyboard. - **Fix:** Window position is not remembered. - **Fix:** Remove 5 fps limit on Preview window. - **Fix:** Arrow and Only Audio icons. - **Fix:** weird behaviour of Region Selector border. - **Fix:** DPI issues when saving from Image Editor. - **Fix:** BASS WaveFormat for SeparateAudioFilePerSource. - **Fix:** Smooth rendering of mouse clicks. - **Fix:** Streaming FrameRate was always set to 10. - Added Webcam only mode. - Settings, Codecs folders in AppDir for portability. - Support `%CAPTURA_PATH%` to point to app directory in FFmpeg, Output and Settings paths. - Change `Minimize on Capture Start` to minimize to tray. - Show a simpler Error Window on Exceptions. ================================================ FILE: docs/Choco.md ================================================ # Chocolatey Chocolatey package is created using the Cake build script and deployed on tag builds by AppVeyor. ### Installation ``` choco install captura -y ``` ================================================ FILE: docs/Cmdline/Arg-Source.md ================================================ # Using the source Argument ## Desktop Use the `desktop` parameter to capture the entire Desktop **(Default)**. Works with both `captura-cli start` and `captura-cli shot`. This is the default option, so is as good as not using this option. e.g. ``` captura-cli start --source desktop ``` ## Region Use Left, Top, Width and Height resp. as comma separated values to represent the region to capture. Works with both `captura-cli start` and `captura-cli shot`. The dimensions of the region must be even. If not, they are decreased by 1 as required. e.g. ``` captura-cli shot --source 100,100,300,400 ``` ## Screen Use `screen:` as the argument. `index` is a zero-based index identifying the screen. Works with both `captura-cli start` and `captura-cli shot`. You can use `captura-cli list` to check screen indices. e.g. ``` captura-cli start --source screen:1 ``` ## No Video Use `none` for No Video. Available only with `captura-cli start`. Can be used for audio only recording. e.g. Record only the speaker output. ``` captura-cli start --source none --speaker 0 ``` ## Window Use `win:` as the argument. `hWnd` is handle of the window. When using with `captura-cli start`, the window handle must be in the `captura-cli list` output. You can use `captura-cli list` to check visible window handles. ## Webcam Use `webcam` as the argument to capture only the webcam. Can only work with `captura-cli start`. Use the `--webcam` argument to set the webcam. You can use `captura-cli list` to check available webcams. e.g. ``` captura-cli start --source webcam --webcam 0 ``` ================================================ FILE: docs/Cmdline/README.md ================================================ # Command-line Project | Executable -------------|---------------- UI | captura.exe Command-line | captura-cli.exe We use the [CommandLineParser](https://nuget.org/packages/CommandLineParser) NuGet package. The console projects uses default settings with a few modifications and does not save settings. > Command-line support is not very stable. Please report any bugs you find. ### Why a separate Console app? There are many issues related to using a WPF application as a console app. - WPF applications don't block the console. So, we cannot use it for scenarios like wait till capture is completed. - Writing to console does not work by default - If `AttachConsole` is used, the written content interferes with console prompt. - And more ... ### Command-line parameters for UI version Argument | Description -------------|---------------------------------- --reset | Reset all Settings --tray | Starts minimized to System Tray --no-persist | Don't Save any changes in Settings --no-hotkey | Don't Register Hotkeys. --settings | Custom settings folder e.g. Start captura minimized to tray ``` captura --tray ``` ### Implemented Verbs - [list](Verb-List.md) List available Screens, Windows, Audio Sources, Webcams, etc. - [start](Verb-Start.md) Start a Recording - [shot](Verb-Shot.md) Take a ScreenShot - [ffmpeg](Verb-FFmpeg.md) Allows installation of ffmpeg from command-line. - help Provides help on using the console app. - version Prints the version of the console app. ================================================ FILE: docs/Cmdline/Verb-FFmpeg.md ================================================ # Verb: FFmpeg Can be used to install FFmpeg e.g. Install FFmpeg to Codecs directory ``` captura-cli ffmpeg --install Codecs ``` ================================================ FILE: docs/Cmdline/Verb-List.md ================================================ # Verb: list Displays the following information: - Version - If FFmpeg is available - FFmpeg encoders - If SharpAvi is available - SharpAvi encoders - If MouseKeyHook is available - Visible Windows with hWnd - Screens if there are more than 1 - Available Microphones - Available Speaker output sources ``` captura list ``` ================================================ FILE: docs/Cmdline/Verb-Shot.md ================================================ # Verb: shot Takes a screenshot Argument | Description -----------------|-------------------------------------------- `--cursor` | Include cursor in the screenshot `--source` | The source to take screenshot of. See [here](Arg-Source.md). `-f` or `--file` | Output file path. e.g. Take a screenshot containing cursor. ``` captura-cli shot --cursor ``` ================================================ FILE: docs/Cmdline/Verb-Start.md ================================================ # Verb: start Starts Recording. There are two modes. When Length is specified, recording runs until specified Length. When Length is not specified, press q to quit message is displayed. Argument | Description ----------------------|------------------------------------------------------------------------- `--cursor` | Include cursor `--keys` | Include keystrokes `--clicks` | Include mouse clicks `--delay` | Delay before starting recording (in ms) `-t` or `--length` | Length of recording (in s) `--source` | The source to record from. See [here](Arg-Source.md). `--mic` | The microphone index to use. (-1 = none (Default)) (0 is first device). `--speaker` | The speaker output index to use. (-1 = none (Default)) (0 is first device). `--webcam` | Webcam to use. (-1 = none (Default)) (0 is first webcam). `-r` or `--framerate` | Frame Rate (Default is 10). `--encoder` | The video encoder to use. See below. `--vq` | Video Quality (1 to 100) (Default is 70). `--aq` | Audio Quality (1 to 100) (Default is 50). `-f` or `--file` | Output file path. `-y` | Overwrite existing file. `--replay` | Replay recording. Specify duration in seconds as parameter. e.g. `--replay 20`. e.g. Record 10 seconds with cursor and keystrokes and audio from first speaker output. ``` captura-cli start --length 10 --cursor --keys --speaker=0 ``` ## Using the Encoder argument By default, SharpAvi Motion JPEG encoder is used. ### SharpAvi Use `sharpavi:` as argument. `index` is a zero-based index identifying the encoder. You can use `captura-cli list` to check encoder indices. e.g. ``` captura-cli start --encoder sharpavi:0 ``` ## Media Foundation Use `mf` as argument. e.g. ``` captura-cli start --encoder mf ``` ### FFmpeg Use `ffmpeg:` as argument. `index` is a zero-based index identifying the encoder. You can use `captura-cli list` to check encoder indices. e.g. ``` captura-cli start --encoder ffmpeg:0 ``` ### Stream Use `stream:` as argument. `url` is the rtmp url of the streaming service. e.g. Stream to Twitch ``` captura-cli start --encoder stream:rtmp://live.twitch.tv/app/TWITCH_KEY ``` ### Steps Use `steps:video` and `steps:images` as `encoder` for Steps recording mode. #### Record steps to video (avi) ``` captura-cli start --encoder steps:video ``` #### Record steps to a folder containing images (png) ``` captura-cli start --encoder steps:images ``` ================================================ FILE: docs/Directories.md ================================================ # Directory Structure - **src** Contains the source code. It is organized into multiple [projects](Projects.md). - **temp** Used for temporary files generated when building using the Cake script. - **dist** Cake build output folder. - **choco** Files for generating the Chocolatey package. - **licenses** Licenses of dependencies. - **scripts** Build scripts used by `build.cake`. - **tools** Created by Cake build to store its dependencies. ================================================ FILE: docs/FAQ.md ================================================ # Frequently Asked Questions ## Will Captura support Linux or Mac? Captura is written using .NET Framework, which at present, is supported only on Windows. Software written using .NET Framework can work on Linux and Mac using Mono but the native calls and UI pose a problem to that. Also, the recently released .Net Core only has support for console applications. ## Does Captura support DirectX Game Video Recording? Some games can be recorded when running on Windows 8 and above. In Captura v8.0.0 there was a separate `Desktop Duplication` option which can also record games which support that. From v9.0.0, `Desktop Duplication` is the default mode. ## Why is maximum frame rate 30fps? Captura is not very fast on low-end systems. This limit on framerate is a protection against Captura consuming all of your CPU/Memory/Disk and causing your system to hang. Starting from v8.0.0, you can remove this limitation by going to Config / Extras / Remove FPS Limit. For reference, Captura can capture 1920x1080 screen at 40fps on my system without audio using FFmpeg x264 codec. My system specifications: 8GB RAM DDR4, Intel i5 6th Gen CPU 2.3 GHz, Windows 10. ## Why is the length of captured video shorter than recording duration? This happens when Captura drops frames when your system can't keep with the specified frame rate. Try using a lower value of framerate, faster codec or smaller region. ## Why does Captura run out of resources (high memory/CPU/disk usage) during recording? Atleast 2 GHz CPU and 4 GB RAM are recommended. This may happen if frames are not being captured as fast as the framerate set. Try a lower value of framerate, faster codec or smaller region. Also, try terminating unnecessary applications running in background using Task Manager. We admit that the technology employed in Captura is not fast. ## Why does my Antivirus say that Captura is virus infected? Captura is virus-free. It does not include any spam, adware or spyware. It is probably due to the keystrokes capture feature being mistaken for a keylogger. ================================================ FILE: docs/FFmpeg.md ================================================ # FFmpeg > It is recommended to always download the latest version of FFmpeg using FFmpeg Downloader. Older versions of FFmpeg can cause unexpected behaviour. [FFmpeg](http://ffmpeg.org/) is an open-source cross-platform solution to record, convert and stream audio and video. It adds support for more output formats like **H.264** for Video and **Mp3**, **AAC** etc. when capturing **Only Audio**. FFmpeg is configured on the **FFmpeg** section in the **Configure** tab. Due to its large size (approx. 30MB), it is not included in the downloads. If you already have FFmpeg on your system, you can just set the path to the folder containing it. If it is installed globally (available in PATH), you don't have to do anything. If you don't have FFmpeg or want to update, use the inbuilt **FFmpeg Downloader**. FFmpeg needs to be downloaded only once. In cases where the **FFmpeg Downloader** fails, please download manually from and set FFmpeg folder in `Configure | FFmpeg`. If you don't want to use FFmpeg, you can switch to `SharpAvi`. ================================================ FILE: docs/Portable.md ================================================ # Portable Starting from v9.0.0, for portable builds: 1. Settings are stored in `Settings` folder in app folder by default. Deleting the `Settings` folder will cause settings to be saved at `%AppData%\Captura`. This can be overridden by using the `--settings` command-line argument. 2. FFmpeg is downloaded into `Codecs` folder in app folder by default. Deleting the `Codecs` folder will cause FFmpeg to be downloaded into `%LocalAppData%\Captura`. This can be overriden from UI. When setting FFmpeg folder, Settings folder or output folder, `%CAPTURA_PATH%` can be used to refer to the app folder. e.g. `%CAPTURA_PATH%/Settings` means `Settings` folder in app folder. ================================================ FILE: docs/Projects.md ================================================ # Project Structure ## Base `Captura.Base` contains common interfaces and base classes. This project is referenced by all other projects. ## Localization `Captura.Loc` contains the localization code. ## Audio `Captura.Audio` contains the audio interfaces which are implemented by specific libraries like `Captura.NAudio`. ## Screna, Core `Screna` and `Captura.Core` projects contain the bulk of the code and are depended on by both UI and Console projects. ## Windows `Captura.Windows` conatins code that is completely specific to the Windows OS. ## Console `Captura.Console` builds the console application. ## View Core `Captura.ViewCore` project contains View models and is depended on by the UI project. ## UI `Captura` is a WPF project containing the UI. ## Other The remaining projects add specific features like Imgur, SharpAvi, FFmpeg, etc. ================================================ FILE: docs/README.md ================================================ # Docs > INCOMPLETE. WORK IN PROGRESS. BEING WRITTEN FOR v9.0.0 WHICH IS YET TO BE RELEASED. ================================================ FILE: docs/Screenshots/Dark.md ================================================ # Screenshots - Dark Theme ## Home ![Home](https://mathewsachin.github.io/Captura/assets/ScreenShots/Home-Dark.png) ## Collapsed ![Collapsed](https://mathewsachin.github.io/Captura/assets/ScreenShots/Collapsed-Dark.png) ## Recent ![Recent](https://mathewsachin.github.io/Captura/assets/ScreenShots/Recent-Dark.png) ## Configure ![Configure](https://mathewsachin.github.io/Captura/assets/ScreenShots/Configure-Dark.png) ## Hotkeys ![Hotkeys](https://mathewsachin.github.io/Captura/assets/ScreenShots/Hotkeys-Dark.png) ## FFmpeg ![FFmpeg](https://mathewsachin.github.io/Captura/assets/ScreenShots/FFmpeg-Dark.png) ## Overlays ![Overlays](https://mathewsachin.github.io/Captura/assets/ScreenShots/Overlays-Dark.png) ## About ![About](https://mathewsachin.github.io/Captura/assets/ScreenShots/About-Dark.png) ================================================ FILE: docs/Screenshots/Light.md ================================================ # Screenshots - Light Theme ## Home ![Home](https://mathewsachin.github.io/Captura/assets/ScreenShots/Home.png) ## Collapsed ![Collapsed](https://mathewsachin.github.io/Captura/assets/ScreenShots/Collapsed.png) ## Recent ![Recent](https://mathewsachin.github.io/Captura/assets/ScreenShots/Recent.png) ## Configure ![Configure](https://mathewsachin.github.io/Captura/assets/ScreenShots/Configure.png) ## Hotkeys ![Hotkeys](https://mathewsachin.github.io/Captura/assets/ScreenShots/Hotkeys.png) ## FFmpeg ![FFmpeg](https://mathewsachin.github.io/Captura/assets/ScreenShots/FFmpeg.png) ## Overlays ![Overlays](https://mathewsachin.github.io/Captura/assets/ScreenShots/Overlays.png) ## About ![About](https://mathewsachin.github.io/Captura/assets/ScreenShots/About.png) ================================================ FILE: docs/Setup.md ================================================ # Setup We use [Inno Setup](http://www.jrsoftware.org/isinfo.php) to create the installer for Captura. ================================================ FILE: docs/System-Requirements.md ================================================ # System Requirements System Requirements for the app to run. ## Operating System Windows 10 is recommended. Atleast Windows 7 is required. If you are on Window 7, make sure *Aero* is enabled. Screen recording is more efficient on Windows 8 and above as compared to Windows 7. ## Hardware - 2 GHz CPU (Recommended) - 4 GB RAM (Recommended) ## .NET Framework [.NET Framework v4.7.2 Runtime](https://dotnet.microsoft.com/download/dotnet-framework/net472) is required. ## FFmpeg The app automatically prompts to download FFmpeg if it is not already present on your system. ## Intel QSV Using the **FFmpeg Intel QSV HEVC** encoder requires the processor to be **Skylake (6th generation)** or later. ## NVenc See if your GPU supports NVenc for H.264 and H.265 in the [Support Matrix](https://developer.nvidia.com/video-encode-decode-gpu-support-matrix.) ## Lagarith codec Lagarith codec can be used with SharpAvi. - Install the codec from its [official website](https://lags.leetcode.net/codec.html). - Make sure it is configured to use RGB mode. - Make sure that Null Frames is disabled. RGB mode and Null Frames can be configured from the registry: ##### HKEY_CURRENT_USER\Software\Lagarith: - Mode = RGB - NullFrames= 2294784 ================================================ FILE: licenses/Captura, Screna.txt ================================================ The MIT License (c) Copyright 2018 Mathew Sachin. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/CommandLineParser.txt ================================================ The MIT License (MIT) Copyright (c) 2005 - 2015 Giacomo Stelluti Scala & Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/CroppingAdorner.txt ================================================ Code Project Open License (CPOL) https://www.codeproject.com/info/cpol10.aspx https://www.codeproject.com/Articles/23158/A-Photoshop-like-Cropping-Adorner-for-WPF ================================================ FILE: licenses/DirectShowLib.txt ================================================ GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ================================================ FILE: licenses/FFMpeg.txt ================================================ GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ================================================ FILE: licenses/Inno.txt ================================================ Inno Setup License ================== Except where otherwise noted, all of the documentation and software included in the Inno Setup package is copyrighted by Jordan Russell. Copyright (C) 1997-2013 Jordan Russell. All rights reserved. Portions Copyright (C) 2000-2013 Martijn Laan. All rights reserved. This software is provided "as-is," without any express or implied warranty. In no event shall the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter and redistribute it, provided that the following conditions are met: 1. All redistributions of source code files must retain all copyright notices that are currently in place, and this list of conditions without modification. 2. All redistributions in binary form must retain all occurrences of the above copyright notice and web site addresses that are currently in place (for example, in the About boxes). 3. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software to distribute a product, an acknowledgment in the product documentation would be appreciated but is not required. 4. Modified versions in source or binary form must be plainly marked as such, and must not be misrepresented as being the original software. Jordan Russell jr-2010 AT jrsoftware.org http://www.jrsoftware.org/ ================================================ FILE: licenses/MUI.Extended.Toolkit.txt ================================================ MIT License Copyright (c) 2016 Sam Oates Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/MUI.txt ================================================ Microsoft Public License (Ms-PL) This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution. 2. Grant of Rights (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. ================================================ FILE: licenses/Media Foundation .NET.txt ================================================ GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ================================================ FILE: licenses/MouseKeyHook.txt ================================================ Copyright (c) 2004-2015, George Mamaladze All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of asssdwd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: licenses/NAudio.txt ================================================ Microsoft Public License (Ms-PL) This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution. 2. Grant of Rights (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. ================================================ FILE: licenses/Newtonsoft.Json.txt ================================================ The MIT License (MIT) Copyright (c) 2007 James Newton-King Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/Ooki.Dialogs.txt ================================================ License agreement for Ookii.Dialogs. Copyright Sven Groot (Ookii.org) 2009 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3) Neither the name of the ORGANIZATION nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: licenses/ReactiveProperty.txt ================================================ The MIT License (MIT) Copyright (c) 2018 neuecc, xin9le, okazuki Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/ScreenToGif.txt ================================================ Captura.Webcam is adapted from ScreenToGif # Microsoft Public License (Ms-PL) This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. ## 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution. ## 2. Grant of Rights (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. ## 3. Conditions and Limitations (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. ================================================ FILE: licenses/SharpAvi.txt ================================================ The MIT License Copyright (c) 2013-2014 Vasili Maslov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/SharpDX.txt ================================================ Copyright (c) 2010-2014 SharpDX - Alexandre Mutel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/System.Reactive.txt ================================================ Copyright (c) .NET Foundation and Contributors All Rights Reserved Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: licenses/WPFNotifyIcon.txt ================================================ Code Project Open License (CPOL) https://www.codeproject.com/info/cpol10.aspx ================================================ FILE: licenses/WpfToolkit.txt ================================================ # Microsoft Public License (Ms-PL) This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. ## 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution. ## 2. Grant of Rights (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. ## 3. Conditions and Limitations (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. ================================================ FILE: scripts/apikeys.cake ================================================ #l "constants.cake" #l "backup.cake" using System.Text.RegularExpressions; IEnumerable GetVariables(string ApiKeysContent) { var match = Regex.Match(ApiKeysContent, "Get\\(\"(.*)\"\\)"); while (match.Success) { yield return match.Groups[1].ToString(); match = match.NextMatch(); } } void EmbedApiKeys() { var apiKeysPath = sourceFolder + File("Captura.Core/ApiKeys.cs"); Information("Embedding Api Keys from Environment Variables ..."); CreateBackup(apiKeysPath, tempFolder + File("ApiKeys.cs")); var content = FileRead(apiKeysPath); foreach (var variable in GetVariables(content)) { if (HasEnvironmentVariable(variable)) { content = content.Replace($"Get(\"{variable}\")", $"\"{EnvironmentVariable(variable)}\""); } } FileWrite(apiKeysPath, content); } ================================================ FILE: scripts/backup.cake ================================================ readonly var Backups = new List(); class Backup { public Backup(string OriginalPath, string BackupPath) { this.OriginalPath = OriginalPath; this.BackupPath = BackupPath; } public string OriginalPath { get; } public string BackupPath { get; } } void CreateBackup(string OriginalPath, string BackupPath) { var backup = new Backup(OriginalPath, BackupPath); CopyFile(OriginalPath, BackupPath); Backups.Add(backup); } void RestoreBackups() { Backups.ForEach(M => { DeleteFile(M.OriginalPath); MoveFile(M.BackupPath, M.OriginalPath); }); } string FileRead(string FileName) => System.IO.File.ReadAllText(FileName); void FileWrite(string FileName, string Content) => System.IO.File.WriteAllText(FileName, Content); ================================================ FILE: scripts/choco.cake ================================================ #l "constants.cake" #l "backup.cake" #l "version.cake" readonly var chocoVersion = tag?.Substring(1) ?? ""; readonly var ChocoPkgPath = tempFolder + File($"captura.{chocoVersion}.nupkg"); void PackChoco() { var checksum = CalculateFileHash(PortablePath).ToHex(); var chocoInstallScript = chocoFolder + File("tools/chocolateyinstall.ps1"); var originalContent = FileRead(chocoInstallScript); var newContent = $"$tag = '{tag}'; $checksum = '{checksum}'; {originalContent}"; CreateBackup(chocoInstallScript, tempFolder + File("cinst.ps1")); FileWrite(chocoInstallScript, newContent); ChocolateyPack(chocoFolder + File("captura.nuspec"), new ChocolateyPackSettings { Version = chocoVersion, ArgumentCustomization = Args => Args.Append($"--outputdirectory {tempFolder}") }); } ================================================ FILE: scripts/constants.cake ================================================ readonly var sourceFolder = Directory("src"); readonly var tempFolder = Directory("temp"); readonly var distFolder = Directory("dist"); readonly var licensesFolder = Directory("licenses"); readonly var chocoFolder = Directory("choco"); readonly var slnPath = sourceFolder + File("Captura.sln"); readonly var PortablePath = tempFolder + File("Captura-Portable.zip"); readonly var SetupPath = tempFolder + File("Captura-Setup.exe"); const string Release = "Release"; ================================================ FILE: scripts/version.cake ================================================ #l "constants.cake" #l "backup.cake" using static System.Text.RegularExpressions.Regex; // version parameter is already used by cake.exe var tag = Argument("build_version", "v0.0.0"); var version = tag; void UpdateVersion(string AssemblyInfoPath) { var content = FileRead(AssemblyInfoPath); var start = content.IndexOf("AssemblyVersion"); var end = content.IndexOf(")", start); var replace = content.Replace(content.Substring(start, end - start + 1), $"AssemblyVersion(\"{version}\")"); FileWrite(AssemblyInfoPath, replace); } void HandleVersion() { const string StableVersionRegex = @"^v\d+\.\d+\.\d+$"; const string PrereleaseVersionRegex = @"^v\d+\.\d+\.\d+-[^\s]+$"; // Stable Release or CI build if (IsMatch(version, StableVersionRegex)) { version = version.Substring(1); } // Prerelease else if (IsMatch(version, PrereleaseVersionRegex)) { version = version.Split('-')[0].Substring(1); } else throw new ArgumentException("Invalid Version Format", "build_version"); var assemblyInfoFile = File("Properties/AssemblyInfo.cs"); var uiAssemblyInfo = sourceFolder + Directory("Captura") + assemblyInfoFile; var consoleAssemblyInfo = sourceFolder + Directory("Captura.Console") + assemblyInfoFile; // Update AssemblyInfo files CreateBackup(uiAssemblyInfo, tempFolder + File("AssemblyInfo.cs")); CreateBackup(consoleAssemblyInfo, tempFolder + File("console.cs")); UpdateVersion(uiAssemblyInfo); UpdateVersion(consoleAssemblyInfo); } ================================================ FILE: src/Captura/App.xaml ================================================  ================================================ FILE: src/Captura/App.xaml.cs ================================================ using FirstFloor.ModernUI.Presentation; using System; using System.IO; using System.Linq; using System.Windows; using System.Windows.Threading; using Captura.Loc; using Captura.Models; using Captura.MouseKeyHook; using Captura.ViewModels; using Captura.Views; using CommandLine; namespace Captura { public partial class App { public App() { SingleInstanceManager.SingleInstanceCheck(); // Splash Screen should be created manually and after single-instance is checked ShowSplashScreen(); } public static CmdOptions CmdOptions { get; private set; } void App_OnDispatcherUnhandledException(object Sender, DispatcherUnhandledExceptionEventArgs Args) { var dir = Path.Combine(ServiceProvider.SettingsDir, "Crashes"); Directory.CreateDirectory(dir); File.WriteAllText(Path.Combine(dir, $"{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt"), Args.Exception.ToString()); Args.Handled = true; new ErrorWindow(Args.Exception, Args.Exception.Message).ShowDialog(); } void ShowSplashScreen() { var splashScreen = new SplashScreen("Images/Logo.png"); splashScreen.Show(true); } void Application_Startup(object Sender, StartupEventArgs Args) { AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainOnUnhandledException; ServiceProvider.LoadModule(new CoreModule()); ServiceProvider.LoadModule(new ViewCoreModule()); Parser.Default.ParseArguments(Args.Args) .WithParsed(M => CmdOptions = M); if (CmdOptions.Settings != null) { ServiceProvider.SettingsDir = CmdOptions.Settings; } var settings = ServiceProvider.Get(); InitTheme(settings); BindLanguageSetting(settings); BindKeymapSetting(settings); } void OnCurrentDomainOnUnhandledException(object S, UnhandledExceptionEventArgs E) { var dir = Path.Combine(ServiceProvider.SettingsDir, "Crashes"); Directory.CreateDirectory(dir); File.WriteAllText(Path.Combine(dir, $"{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt"), E.ExceptionObject.ToString()); if (E.ExceptionObject is Exception e) { Current.Dispatcher.Invoke(() => new ErrorWindow(e, e.Message).ShowDialog()); } Shutdown(); } static void BindKeymapSetting(Settings Settings) { var keymap = ServiceProvider.Get(); if (!string.IsNullOrWhiteSpace(Settings.Keystrokes.KeymapName)) { var matched = keymap.AvailableKeymaps.FirstOrDefault(M => M.Name == Settings.Keystrokes.KeymapName); if (matched != null) keymap.SelectedKeymap = matched; } keymap.PropertyChanged += (S, E) => Settings.Keystrokes.KeymapName = keymap.SelectedKeymap.Name; } static void BindLanguageSetting(Settings Settings) { var loc = LanguageManager.Instance; if (!string.IsNullOrWhiteSpace(Settings.UI.Language)) { var matchedCulture = loc.AvailableCultures.FirstOrDefault(M => M.Name == Settings.UI.Language); if (matchedCulture != null) loc.CurrentCulture = matchedCulture; } loc.LanguageChanged += L => Settings.UI.Language = L.Name; } static void InitTheme(Settings Settings) { if (!CmdOptions.Reset) { Settings.Load(); } if (Settings.UI.DarkTheme) { AppearanceManager.Current.ThemeSource = AppearanceManager.DarkThemeSource; } var accent = Settings.UI.AccentColor; if (!string.IsNullOrEmpty(accent)) { AppearanceManager.Current.AccentColor = WpfExtensions.ParseColor(accent); } } } } ================================================ FILE: src/Captura/Captura.csproj ================================================  WinExe Captura captura net472 false true false true Images\Captura.ico false ================================================ FILE: src/Captura/Controls/CollapsedBar.xaml ================================================  ================================================ FILE: src/Captura/Controls/CollapsedBar.xaml.cs ================================================ using System.Windows; namespace Captura { public partial class CollapsedBar { public CollapsedBar() { InitializeComponent(); } void OpenSettings(object Sender, RoutedEventArgs E) { SettingsWindow.ShowInstance(); } } } ================================================ FILE: src/Captura/Controls/FontSelector.xaml ================================================  ================================================ FILE: src/Captura/Controls/FontSelector.xaml.cs ================================================ using System.Windows; namespace Captura { public partial class FontSelector { public FontSelector() { InitializeComponent(); } public static readonly DependencyProperty SelectedFontProperty = DependencyProperty.Register( nameof(SelectedFont), typeof(string), typeof(FontSelector), new FrameworkPropertyMetadata("Arial")); public string SelectedFont { get => (string) GetValue(SelectedFontProperty); set => SetValue(SelectedFontProperty, value); } } } ================================================ FILE: src/Captura/Controls/HotkeySelector.cs ================================================ using System.Windows; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Media; using Captura.Hotkeys; using Button = System.Windows.Controls.Button; using KeyEventArgs = System.Windows.Input.KeyEventArgs; namespace Captura { public class HotkeySelector : Button { bool _editing; static readonly SolidColorBrush RedBrush = new SolidColorBrush(WpfExtensions.ParseColor("#ef5350")); static readonly SolidColorBrush GreenBrush = new SolidColorBrush(WpfExtensions.ParseColor("#43a047")); static readonly SolidColorBrush WhiteBrush = new SolidColorBrush(Colors.White); public static readonly DependencyProperty HotkeyModelProperty = DependencyProperty.Register(nameof(HotkeyModel), typeof(Hotkey), typeof(HotkeySelector), new UIPropertyMetadata(HotkeyModelChangedCallback)); static void HotkeyModelChangedCallback(DependencyObject Sender, DependencyPropertyChangedEventArgs Args) { if (Sender is HotkeySelector selector && Args.NewValue is Hotkey hotkey) { selector.TextColor(); hotkey.PropertyChanged += (S, E) => { if (E.PropertyName == nameof(Hotkey.IsActive)) selector.TextColor(); }; selector.Content = hotkey.ToString(); } } public Hotkey HotkeyModel { get => (Hotkey) GetValue(HotkeyModelProperty); set => SetValue(HotkeyModelProperty, value); } void HotkeyEdited(Key NewKey, Modifiers NewModifiers) { HotkeyEdited((Keys) KeyInterop.VirtualKeyFromKey(NewKey), NewModifiers); } void TextColor() { if (HotkeyModel.IsActive) { Background = HotkeyModel.IsRegistered ? GreenBrush : RedBrush; Foreground = WhiteBrush; } else { ClearValue(BackgroundProperty); ClearValue(ForegroundProperty); } } void HotkeyEdited(Keys NewKey, Modifiers NewModifiers) { HotkeyModel.Change(NewKey, NewModifiers); // Red Text on Error TextColor(); Content = HotkeyModel.ToString(); _editing = false; } protected override void OnClick() { base.OnClick(); _editing = !_editing; Content = _editing ? "Press new Hotkey..." : HotkeyModel.ToString(); } protected override void OnLostFocus(RoutedEventArgs E) { base.OnLostFocus(E); CancelEditing(); } void CancelEditing() { if (!_editing) return; _editing = false; Content = HotkeyModel.ToString(); } static bool IsValid(KeyEventArgs E) { return E.Key != Key.None // Some key must pe pressed && !E.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Windows) // Windows Key is reserved by OS && E.Key != Key.LeftCtrl && E.Key != Key.RightCtrl // Modifier Keys alone are not supported && E.Key != Key.LeftAlt && E.Key != Key.RightAlt && E.Key != Key.LeftShift && E.Key != Key.RightShift; } protected override void OnPreviewKeyDown(KeyEventArgs E) { // Ignore Repeats if (E.IsRepeat) { E.Handled = true; return; } if (_editing) { // Suppress event propagation E.Handled = true; switch (E.Key) { case Key.Escape: CancelEditing(); break; case Key.System: if (E.SystemKey == Key.LeftAlt || E.SystemKey == Key.RightAlt) Content = "Alt + ..."; else HotkeyEdited(E.SystemKey, Modifiers.Alt); break; default: if (IsValid(E)) HotkeyEdited(E.Key, (Modifiers)E.KeyboardDevice.Modifiers); else { var modifiers = E.KeyboardDevice.Modifiers; Content = ""; if (modifiers.HasFlag(ModifierKeys.Control)) Content += "Ctrl + "; if (modifiers.HasFlag(ModifierKeys.Alt)) Content += "Alt + "; if (modifiers.HasFlag(ModifierKeys.Shift)) Content += "Shift + "; Content += "..."; } break; } } base.OnPreviewKeyDown(E); } protected override void OnPreviewKeyUp(KeyEventArgs E) { // Ignore Repeats if (E.IsRepeat) return; if (_editing) { // Suppress event propagation E.Handled = true; // PrintScreen is not recognized in KeyDown switch (E.Key) { case Key.Snapshot: HotkeyEdited(Keys.PrintScreen, (Modifiers)E.KeyboardDevice.Modifiers); break; case Key.System when E.SystemKey == Key.Snapshot: HotkeyEdited(Keys.PrintScreen, Modifiers.Alt); break; } } base.OnPreviewKeyUp(E); } } } ================================================ FILE: src/Captura/Controls/ImageOverlaySettingsControl.xaml ================================================  ================================================ FILE: src/Captura/Controls/ImageOverlaySettingsControl.xaml.cs ================================================ namespace Captura { public partial class ImageOverlaySettingsControl { public ImageOverlaySettingsControl() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Controls/LayerFrame.xaml ================================================  ================================================ FILE: src/Captura/Controls/LayerFrame.xaml.cs ================================================ using System; using System.Windows; namespace Captura { public partial class LayerFrame { public LayerFrame() { InitializeComponent(); } public event Action PositionUpdated; public void RaisePositionChanged(Rect Rect) { PositionUpdated?.Invoke(Rect); } } } ================================================ FILE: src/Captura/Controls/ModernButton.cs ================================================ using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace Captura { public class ModernButton : Button { public static readonly DependencyProperty IconDataProperty = DependencyProperty.Register(nameof(IconData), typeof(Geometry), typeof(ModernButton)); public ModernButton() { DefaultStyleKey = typeof(ModernButton); } public Geometry IconData { get => (Geometry)GetValue(IconDataProperty); set => SetValue(IconDataProperty, value); } } } ================================================ FILE: src/Captura/Controls/ModernPasswordBox.xaml ================================================  ================================================ FILE: src/Captura/Controls/ModernPasswordBox.xaml.cs ================================================ using System.Windows; namespace Captura { public partial class ModernPasswordBox { public ModernPasswordBox() { InitializeComponent(); PswBox.PasswordChanged += (S, E) => Password = PswBox.Password; } public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register( nameof(Password), typeof(string), typeof(ModernPasswordBox), new UIPropertyMetadata((S, E) => { if (S is ModernPasswordBox modernPswBox && E.NewValue is string psw) { if (modernPswBox.PswBox.Password != psw) modernPswBox.PswBox.Password = psw; } })); public string Password { get => (string) GetValue(PasswordProperty); set => SetValue(PasswordProperty, value); } public static readonly DependencyProperty PasswordVisibleProperty = DependencyProperty.Register( nameof(PasswordVisible), typeof(bool), typeof(ModernPasswordBox)); public bool PasswordVisible { get => (bool)GetValue(PasswordVisibleProperty); set => SetValue(PasswordVisibleProperty, value); } void ToggleVisibility(object Sender, RoutedEventArgs E) { PasswordVisible = !PasswordVisible; } } } ================================================ FILE: src/Captura/Controls/ModernToggleButton.cs ================================================ using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace Captura { public class ModernToggleButton : CheckBox { public static readonly DependencyProperty IconDataProperty = DependencyProperty.Register(nameof(IconData), typeof(Geometry), typeof(ModernToggleButton)); public ModernToggleButton() { DefaultStyleKey = typeof(ModernToggleButton); } public Geometry IconData { get => (Geometry)GetValue(IconDataProperty); set => SetValue(IconDataProperty, value); } } } ================================================ FILE: src/Captura/Controls/NotificationBalloon.xaml ================================================  ================================================ FILE: src/Captura/Controls/NotificationBalloon.xaml.cs ================================================ using System.Windows; using System.Windows.Input; using System; namespace Captura { public partial class NotificationBalloon : IRemoveRequester { public INotification Notification { get; } public NotificationBalloon(INotification Notification) { this.Notification = Notification; Notification.RemoveRequested += OnClose; InitializeComponent(); } void OnClose() { RemoveRequested?.Invoke(); } public event Action RemoveRequested; void CloseButton_Click(object Sender, RoutedEventArgs E) => OnClose(); void TextBlock_MouseUp(object Sender, MouseButtonEventArgs E) { Notification.RaiseClick(); OnClose(); } } } ================================================ FILE: src/Captura/Controls/NotificationStack.xaml ================================================  ================================================ FILE: src/Captura/Controls/NotificationStack.xaml.cs ================================================ using System; using System.Linq; using System.Windows; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Threading; using MouseEventArgs = System.Windows.Input.MouseEventArgs; namespace Captura { public partial class NotificationStack { static readonly TimeSpan TimeoutToHide = TimeSpan.FromSeconds(5); DateTime _lastMouseMoveTime; readonly DispatcherTimer _timer; public NotificationStack() { InitializeComponent(); _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; _timer.Tick += TimerOnTick; _timer.Start(); } void TimerOnTick(object Sender, EventArgs Args) { var now = DateTime.Now; var elapsed = now - _lastMouseMoveTime; var unfinished = ItemsControl.Items .OfType() .Any(M => !M.Notification.Finished); if (unfinished) { _lastMouseMoveTime = now; } if (elapsed < TimeoutToHide) return; if (!unfinished) { OnClose(); } } public void Hide() { BeginAnimation(OpacityProperty, new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(100)))); if (_timer.IsEnabled) _timer.Stop(); } public void Show() { _lastMouseMoveTime = DateTime.Now; BeginAnimation(OpacityProperty, new DoubleAnimation(1, new Duration(TimeSpan.FromMilliseconds(300)))); if (!_timer.IsEnabled) _timer.Start(); } void OnClose() { Hide(); var copy = ItemsControl.Items.OfType().ToArray(); foreach (var frameworkElement in copy) { Remove(frameworkElement); } } void CloseButton_Click(object Sender, RoutedEventArgs E) => OnClose(); /// /// Slides out element while decreasing opacity, then decreases height, then removes. /// void Remove(FrameworkElement Element) { var transform = new TranslateTransform(); Element.RenderTransform = transform; var translateAnim = new DoubleAnimation(500, new Duration(TimeSpan.FromMilliseconds(200))); var opactityAnim = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(200))); var heightAnim = new DoubleAnimation(Element.ActualHeight, 0, new Duration(TimeSpan.FromMilliseconds(200))); heightAnim.Completed += (S, E) => { ItemsControl.Items.Remove(Element); if (ItemsControl.Items.Count == 0) { Hide(); } }; opactityAnim.Completed += (S, E) => Element.BeginAnimation(HeightProperty, heightAnim); transform.BeginAnimation(TranslateTransform.XProperty, translateAnim); Element.BeginAnimation(OpacityProperty, opactityAnim); } const int MaxItems = 5; public void Add(FrameworkElement Element) { if (Element is IRemoveRequester removeRequester) { removeRequester.RemoveRequested += () => Remove(Element); } if (Element is ScreenShotBalloon ssBalloon) ssBalloon.Expander.IsExpanded = true; foreach (var item in ItemsControl.Items) { if (item is ScreenShotBalloon screenShotBalloon) { screenShotBalloon.Expander.IsExpanded = false; } } ItemsControl.Items.Insert(0, Element); if (ItemsControl.Items.Count > MaxItems) { var itemsToRemove = ItemsControl.Items .OfType() .Skip(MaxItems) .ToArray(); foreach (var frameworkElement in itemsToRemove) { if (frameworkElement is NotificationBalloon progressBalloon && !progressBalloon.Notification.Finished) continue; Remove(frameworkElement); } } } void NotificationStack_OnMouseMove(object Sender, MouseEventArgs E) { if (ItemsControl.Items.Count == 0) return; _lastMouseMoveTime = DateTime.Now; Show(); } } } ================================================ FILE: src/Captura/Controls/OutputFolderControl.xaml ================================================  ================================================ FILE: src/Captura/Controls/OutputFolderControl.xaml.cs ================================================ using System.Windows.Input; using Captura.ViewModels; namespace Captura { public partial class OutputFolderControl { public OutputFolderControl() { InitializeComponent(); } void SelectTargetFolder(object Sender, MouseButtonEventArgs E) { if (DataContext is MainViewModel vm) { vm.SelectOutputFolderCommand.ExecuteIfCan(); } } } } ================================================ FILE: src/Captura/Controls/PauseButton.xaml ================================================  ================================================ FILE: src/Captura/Controls/PauseButton.xaml.cs ================================================ namespace Captura { public partial class PauseButton { public PauseButton() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Controls/PositionSettingsControl.xaml ================================================  ================================================ FILE: src/Captura/Controls/PositionSettingsControl.xaml.cs ================================================ namespace Captura { public partial class PositionSettingsControl { public PositionSettingsControl() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Controls/PuncturedRegion.xaml ================================================  ================================================ FILE: src/Captura/Controls/PuncturedRegion.xaml.cs ================================================ using System.Windows; namespace Captura { public partial class PuncturedRegion { public Rect? Region { get => (Rect?)GetValue(RegionProperty); set => SetValue(RegionProperty, value); } public static readonly DependencyProperty RegionProperty = DependencyProperty.Register( nameof(Region), typeof(Rect?), typeof(PuncturedRegion), new PropertyMetadata(RegionChanged)); static void RegionChanged(DependencyObject Obj, DependencyPropertyChangedEventArgs E) { if (Obj is PuncturedRegion r) { switch (E.NewValue) { case null: // Must not be collapsed, since ActualWidth and ActualHeight are used. r.Visibility = Visibility.Hidden; break; case Rect region: var w = r.ActualWidth; var h = r.ActualHeight; r.BorderTop.Margin = new Thickness(); r.BorderTop.Width = w; r.BorderTop.Height = region.Top.Clip(0, h); r.BorderBottom.Margin = new Thickness(0, region.Bottom, 0, 0); r.BorderBottom.Width = w; r.BorderBottom.Height = (h - region.Bottom).Clip(0, h); r.BorderLeft.Margin = new Thickness(0, region.Top, 0, 0); r.BorderLeft.Width = region.Left.Clip(0, w); r.BorderLeft.Height = region.Height; r.BorderRight.Margin = new Thickness(region.Right, region.Top, 0, 0); r.BorderRight.Width = (w - region.Right).Clip(0, w); r.BorderRight.Height = region.Height; r.Visibility = Visibility.Visible; break; } } } public PuncturedRegion() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Controls/RecentItem.xaml ================================================  ================================================ FILE: src/Captura/Controls/RecentItem.xaml.cs ================================================ namespace Captura { public partial class RecentItem { public RecentItem() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Controls/ScreenShotBalloon.xaml ================================================  ================================================ FILE: src/Captura/Controls/ScreenShotBalloon.xaml.cs ================================================ using System.Windows; using System.Windows.Input; using System.IO; using System.Diagnostics; using System; using System.Windows.Media.Imaging; using Captura.Models; namespace Captura { public partial class ScreenShotBalloon : IRemoveRequester { readonly string _filePath; public ScreenShotBalloon(string FilePath) { _filePath = FilePath; DataContext = Path.GetFileName(FilePath); InitializeComponent(); // Do not assign image directly, cache it, else the file can't be deleted. var image = new BitmapImage(); image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; image.UriSource = new Uri(FilePath); image.EndInit(); Img.Source = image; } void CloseButton_Click(object Sender, RoutedEventArgs E) => OnClose(); void OnClose() { RemoveRequested?.Invoke(); } public event Action RemoveRequested; void Image_MouseUp(object Sender, MouseButtonEventArgs E) { ServiceProvider.LaunchFile(new ProcessStartInfo(_filePath)); OnClose(); } void EditButton_OnClick(object Sender, RoutedEventArgs E) { var winserv = ServiceProvider.Get(); winserv.EditImage(_filePath); } } } ================================================ FILE: src/Captura/Controls/ScreenShotButton.xaml ================================================  ================================================ FILE: src/Captura/Controls/ScreenShotButton.xaml.cs ================================================ namespace Captura { public partial class ScreenShotButton { public ScreenShotButton() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Controls/StatusBar.xaml ================================================  ================================================ FILE: src/Captura/Controls/StatusBar.xaml.cs ================================================ namespace Captura { public partial class StatusBar { public StatusBar() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Controls/StripedBorder.xaml ================================================  ================================================ FILE: src/Captura/Controls/StripedBorder.xaml.cs ================================================ namespace Captura { public partial class StripedBorder { public StripedBorder() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Controls/TextOverlaySettingsControl.xaml ================================================  ================================================ FILE: src/Captura/Controls/TextOverlaySettingsControl.xaml.cs ================================================ namespace Captura { public partial class TextOverlaySettingsControl { public TextOverlaySettingsControl() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Controls/VideoSourceKindList.xaml ================================================  ================================================ FILE: src/Captura/Controls/VideoSourceKindList.xaml.cs ================================================ using System.Windows.Controls; using System.Windows.Input; using Captura.Video; namespace Captura { public partial class VideoSourceKindList { public VideoSourceKindList() { InitializeComponent(); } void OnVideoSourceReSelect(object Sender, MouseButtonEventArgs E) { if (Sender is ListViewItem item && item.IsSelected) { if (item.DataContext is IVideoSourceProvider provider) { provider.OnSelect(); } } } } } ================================================ FILE: src/Captura/Models/AudioPlayer.cs ================================================ using System; using System.IO; using System.Windows.Media; namespace Captura.Audio { // ReSharper disable once ClassNeverInstantiated.Global public class AudioPlayer : IAudioPlayer { readonly SoundSettings _settings; readonly MediaPlayer _mediaPlayer; public AudioPlayer(SoundSettings Settings) { _settings = Settings; _mediaPlayer = new MediaPlayer(); } void PlaySound(string Path) { if (!File.Exists(Path)) return; _mediaPlayer.Open(new Uri(Path)); _mediaPlayer.Play(); } public void Play(SoundKind SoundKind) { if (_settings.Items.TryGetValue(SoundKind, out var value)) PlaySound(value); } } } ================================================ FILE: src/Captura/Models/CmdOptions.cs ================================================ using CommandLine; namespace Captura { /// /// Command-line options for the WPF app. /// // ReSharper disable once ClassNeverInstantiated.Global public class CmdOptions { [Option("reset", HelpText = "Reset all setting values to default.")] public bool Reset { get; set; } [Option("tray", HelpText = "Start minimized into the system tray.")] public bool Tray { get; set; } [Option("no-hotkey", HelpText = "Do not Register hotkeys.")] public bool NoHotkeys { get; set; } [Option("no-persist", HelpText = "Do not save any changes in settings.")] public bool NoPersist { get; set; } [Option("settings", HelpText = "Settings Directory")] public string Settings { get; set; } } } ================================================ FILE: src/Captura/Models/Dpi.cs ================================================ using System.Windows.Interop; namespace Captura { /// /// Provides DPI scaling factor. /// Only needs to be used when dealing with WPF since their sizes are specified in Device Independent Pixels. /// // ReSharper disable once ClassNeverInstantiated.Global public class Dpi { static Dpi() { using var src = new HwndSource(new HwndSourceParameters()); if (src.CompositionTarget != null) { var matrix = src.CompositionTarget.TransformToDevice; X = (float) matrix.M11; Y = (float) matrix.M22; } } public static float X { get; } public static float Y { get; } } } ================================================ FILE: src/Captura/Models/FFmpegViewsProvider.cs ================================================ using System.Windows; using Captura.Audio; using Captura.Loc; using Captura.Models; using Captura.Views; using FirstFloor.ModernUI.Windows.Controls; namespace Captura.FFmpeg { // ReSharper disable once ClassNeverInstantiated.Global public class FFmpegViewsProvider : IFFmpegViewsProvider { readonly ILocalizationProvider _loc; readonly IAudioPlayer _audioPlayer; readonly FFmpegSettings _settings; readonly IDialogService _dialogService; public FFmpegViewsProvider(ILocalizationProvider Loc, IAudioPlayer AudioPlayer, FFmpegSettings Settings, IDialogService DialogService) { _loc = Loc; _audioPlayer = AudioPlayer; _settings = Settings; _dialogService = DialogService; } public void ShowLogs() { SettingsWindow.ShowFFmpegLogs(); } public void ShowUnavailable() { Application.Current.Dispatcher.Invoke(() => { var dialog = new ModernDialog { Title = "FFmpeg Unavailable", Content = "FFmpeg was not found on your system.\n\nSelect FFmpeg Folder if you alrady have FFmpeg on your system, else Download FFmpeg." }; // Yes -> Select FFmpeg Folder dialog.YesButton.Content = _loc.SelectFFmpegFolder; dialog.YesButton.Click += (S, E) => PickFolder(); // No -> Download FFmpeg dialog.NoButton.Content = _loc.DownloadFFmpeg; dialog.NoButton.Click += (S, E) => ShowDownloader(); dialog.CancelButton.Content = "Cancel"; dialog.Buttons = new[] { dialog.YesButton, dialog.NoButton, dialog.CancelButton }; _audioPlayer.Play(SoundKind.Error); dialog.ShowDialog(); }); } public void ShowDownloader() { FFmpegDownloaderWindow.ShowInstance(); } public void PickFolder() { var folder = _dialogService.PickFolder(_settings.GetFolderPath(), _loc.SelectFFmpegFolder); if (!string.IsNullOrWhiteSpace(folder)) _settings.FolderPath = folder; } } } ================================================ FILE: src/Captura/Models/HitType.cs ================================================ namespace Captura { enum HitType { None, Body, Left, Right, Top, Bottom, UpperLeft, UpperRight, LowerRight, LowerLeft } } ================================================ FILE: src/Captura/Models/HotkeyListener.cs ================================================ using System; using System.Windows.Interop; namespace Captura.Hotkeys { public class HotkeyListener : IHotkeyListener { const int WindowsMessageHotkey = 786; public HotkeyListener() { ComponentDispatcher.ThreadPreprocessMessage += (ref MSG Message, ref bool Handled) => { if (Message.message == WindowsMessageHotkey) { var id = Message.wParam.ToInt32(); HotkeyReceived?.Invoke(id); } }; } public event Action HotkeyReceived; } } ================================================ FILE: src/Captura/Models/HotkeySetup.cs ================================================ using System.Linq; using Captura.Models; namespace Captura.Hotkeys { // ReSharper disable once ClassNeverInstantiated.Global public class HotkeySetup { readonly HotKeyManager _hotKeyManager; readonly IMessageProvider _messageProvider; public HotkeySetup(HotKeyManager HotKeyManager, IMessageProvider MessageProvider) { _hotKeyManager = HotKeyManager; _messageProvider = MessageProvider; } public void Setup() { _hotKeyManager.RegisterAll(); } public void ShowUnregistered() { var notRegisteredOnStartup = _hotKeyManager .Hotkeys .Where(M => M.IsActive && !M.IsRegistered) .ToArray(); if (notRegisteredOnStartup.Length <= 0) return; var message = "The following Hotkeys could not be registered:\nOther programs might be using them.\nTry changing them.\n\n"; foreach (var hotkey in notRegisteredOnStartup) { message += $"{hotkey.Service.Description} - {hotkey}\n\n"; } _messageProvider.ShowError(message, "Failed to Register Hotkeys"); } } } ================================================ FILE: src/Captura/Models/HotkeyViewActor.cs ================================================ namespace Captura.Hotkeys { public class HotkeyViewActor : IHotkeyActor { public void Act(ServiceName Service) { switch (Service) { case ServiceName.ShowMainWindow: MainWindow.Instance.ShowAndFocus(); break; } } } } ================================================ FILE: src/Captura/Models/IRemoveRequester.cs ================================================ using System; namespace Captura { public interface IRemoveRequester { event Action RemoveRequested; } } ================================================ FILE: src/Captura/Models/MainModule.cs ================================================ using System; using Captura.Audio; using Captura.FFmpeg; using Captura.Hotkeys; using Captura.Models; using Captura.Video; using Captura.ViewModels; using Hardcodet.Wpf.TaskbarNotification; namespace Captura { public class MainModule : IModule { public void OnLoad(IBinder Binder) { // Use singleton to ensure the same instance is used every time. Binder.Bind(); Binder.Bind(); Binder.Bind(); Binder.Bind(); Binder.Bind(); Binder.Bind(); Binder.Bind(); Binder.Bind(); Binder.Bind(); Binder.BindSingleton(); Binder.BindSingleton(); Binder.BindSingleton(); // Bind as a Function to ensure the UI objects are referenced only after they have been created. Binder.Bind>(() => () => MainWindow.Instance.SystemTray); Binder.Bind(() => new MainWindowProvider(() => MainWindow.Instance)); } public void Dispose() { } } } ================================================ FILE: src/Captura/Models/MainWindowHelper.cs ================================================ using Captura.Hotkeys; using Captura.ViewModels; namespace Captura { // ReSharper disable once ClassNeverInstantiated.Global class MainWindowHelper { public MainWindowHelper(MainViewModel MainViewModel, HotkeySetup HotkeySetup, TimerModel TimerModel, Settings Settings, RecordingViewModel RecordingViewModel) { this.MainViewModel = MainViewModel; this.HotkeySetup = HotkeySetup; this.TimerModel = TimerModel; this.Settings = Settings; this.RecordingViewModel = RecordingViewModel; } public MainViewModel MainViewModel { get; } public HotkeySetup HotkeySetup { get; } public TimerModel TimerModel { get; } public Settings Settings { get; } public RecordingViewModel RecordingViewModel { get; } } } ================================================ FILE: src/Captura/Models/MainWindowProvider.cs ================================================ using System; using System.Diagnostics; using System.Windows; using Captura.Views; namespace Captura.Models { class MainWindowProvider : IMainWindow { readonly Func _window; public MainWindowProvider(Func Window) { _window = Window; } public bool IsVisible { get => _window.Invoke().IsVisible; set { if (value) _window.Invoke().Show(); else _window.Invoke().Hide(); } } public bool IsMinimized { get => _window.Invoke().WindowState == WindowState.Minimized; set => _window.Invoke().WindowState = value ? WindowState.Minimized : WindowState.Normal; } public void EditImage(string FileName) { var settings = ServiceProvider.Get().ScreenShots; Process.Start(settings.ExternalEditor, $"\"{FileName}\""); } public void TrimMedia(string FileName) { var win = new TrimmerWindow(); win.Open(FileName); win.ShowAndFocus(); } public void UploadToYouTube(string FileName) { var win = new YouTubeUploaderWindow(); win.Open(FileName); win.ShowAndFocus(); } } } ================================================ FILE: src/Captura/Models/MessageProvider.cs ================================================ using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using Captura.Audio; using Captura.Loc; using Captura.Views; using FirstFloor.ModernUI.Windows.Controls; namespace Captura.Models { // ReSharper disable once ClassNeverInstantiated.Global public class MessageProvider : IMessageProvider { readonly IAudioPlayer _audioPlayer; readonly ILocalizationProvider _loc; public MessageProvider(IAudioPlayer AudioPlayer, ILocalizationProvider Loc) { _audioPlayer = AudioPlayer; _loc = Loc; } public void ShowError(string Message, string Header = null) { Application.Current.Dispatcher.Invoke(() => { var dialog = new ModernDialog { Title = _loc.ErrorOccurred, Content = new StackPanel { Children = { new TextBlock { Text = Header, Margin = new Thickness(0, 0, 0, 10), FontSize = 15 }, new ScrollViewer { Content = Message, HorizontalScrollBarVisibility = ScrollBarVisibility.Auto, Padding = new Thickness(0, 0, 0, 10) } } } }; dialog.OkButton.Content = _loc.Ok; dialog.Buttons = new[] { dialog.OkButton }; dialog.BackgroundContent = new Grid { Background = new SolidColorBrush(Color.FromArgb(255, 244, 67, 54)), VerticalAlignment = VerticalAlignment.Top, Height = 10 }; _audioPlayer.Play(SoundKind.Error); dialog.ShowDialog(); }); } public void ShowException(Exception Exception, string Message, bool Blocking = false) { Application.Current.Dispatcher.Invoke(() => { var win = new ErrorWindow(Exception, Message); _audioPlayer.Play(SoundKind.Error); if (Blocking) { win.ShowDialog(); } else win.ShowAndFocus(); }); } public bool ShowYesNo(string Message, string Title) { return Application.Current.Dispatcher.Invoke(() => { var dialog = new ModernDialog { Title = Title, Content = new ScrollViewer { Content = Message, HorizontalScrollBarVisibility = ScrollBarVisibility.Auto, Padding = new Thickness(0, 0, 0, 10) } }; var result = false; dialog.YesButton.Content = _loc.Yes; dialog.YesButton.Click += (S, E) => result = true; dialog.NoButton.Content = _loc.No; dialog.Buttons = new[] { dialog.YesButton, dialog.NoButton }; dialog.ShowDialog(); return result; }); } } } ================================================ FILE: src/Captura/Models/PreviewWindowService.cs ================================================ using System; using System.Windows; using System.Windows.Interop; using Captura.Windows.DirectX; using Captura.Windows.Gdi; using Reactive.Bindings.Extensions; using SharpDX.Direct3D9; namespace Captura.Video { // ReSharper disable once ClassNeverInstantiated.Global public class PreviewWindowService : IPreviewWindow { D3D9PreviewAssister _d3D9PreviewAssister; IntPtr _backBufferPtr; Texture _texture; readonly VisualSettings _visualSettings; public void Show() { _visualSettings.Expanded = true; } public bool IsVisible { get; private set; } public PreviewWindowService(VisualSettings VisualSettings) { _visualSettings = VisualSettings; VisualSettings.ObserveProperty(M => M.Expanded) .Subscribe(M => IsVisible = M); } IBitmapFrame _lastFrame; public void Display(IBitmapFrame Frame) { if (Frame is RepeatFrame) return; if (!IsVisible) { Frame.Dispose(); return; } var win = MainWindow.Instance; win.Dispatcher.Invoke(() => { win.DisplayImage.Image = null; _lastFrame?.Dispose(); _lastFrame = Frame; Frame = Frame.Unwrap(); switch (Frame) { case DrawingFrame drawingFrame: try { // TODO: Preview is not shown during Webcam only recordings // This check swallows errors var h = drawingFrame.Bitmap.Height; if (h == 0) return; } catch { return; } win.WinFormsHost.Visibility = Visibility.Visible; win.DisplayImage.Image = drawingFrame.Bitmap; break; case Texture2DFrame texture2DFrame: win.WinFormsHost.Visibility = Visibility.Collapsed; if (_d3D9PreviewAssister == null) { _d3D9PreviewAssister = new D3D9PreviewAssister(ServiceProvider.Get()); _texture = _d3D9PreviewAssister.GetSharedTexture(texture2DFrame.PreviewTexture); using var surface = _texture.GetSurfaceLevel(0); _backBufferPtr = surface.NativePointer; } Invalidate(_backBufferPtr, texture2DFrame.Width, texture2DFrame.Height); break; } }); } void Invalidate(IntPtr BackBufferPtr, int Width, int Height) { var win = MainWindow.Instance; win.D3DImage.Lock(); win.D3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, BackBufferPtr); if (BackBufferPtr != IntPtr.Zero) win.D3DImage.AddDirtyRect(new Int32Rect(0, 0, Width, Height)); win.D3DImage.Unlock(); } public void Dispose() { var win = MainWindow.Instance; win.Dispatcher.Invoke(() => { win.DisplayImage.Image = null; win.WinFormsHost.Visibility = Visibility.Collapsed; _lastFrame?.Dispose(); _lastFrame = null; if (_d3D9PreviewAssister != null) { Invalidate(IntPtr.Zero, 0, 0); _texture.Dispose(); _d3D9PreviewAssister.Dispose(); _d3D9PreviewAssister = null; } }); } } } ================================================ FILE: src/Captura/Models/RegionSelectorProvider.cs ================================================ using System; using System.Drawing; using System.Windows; using Captura.ViewModels; namespace Captura.Video { // ReSharper disable once ClassNeverInstantiated.Global public class RegionSelectorProvider : IRegionProvider { readonly Lazy _regionSelector; readonly RegionItem _regionItem; readonly RegionSelectorViewModel _viewModel; public RegionSelectorProvider(RegionSelectorViewModel ViewModel, IPlatformServices PlatformServices) { _viewModel = ViewModel; _regionSelector = new Lazy(() => new RegionSelector(ViewModel)); _regionItem = new RegionItem(this, PlatformServices); } public bool SelectorVisible { get => _regionSelector.Value.Visibility == Visibility.Visible; set { if (value) _regionSelector.Value.Show(); else _regionSelector.Value.Hide(); } } public Rectangle SelectedRegion { get => _viewModel.SelectedRegion; set => _viewModel.SelectedRegion = value; } public IVideoItem VideoSource => _regionItem; public IntPtr Handle => _regionSelector.Value.Handle; } } ================================================ FILE: src/Captura/Models/ServiceLocator.cs ================================================ using Captura.Models; using Captura.MouseKeyHook; using Captura.ViewModels; using Captura.Webcam; // ReSharper disable MemberCanBeMadeStatic.Global namespace Captura { /// /// Used as a Static Resource to inject ViewModels into UI. /// public class ServiceLocator { static ServiceLocator() { ServiceProvider.LoadModule(new MainModule()); } public WebcamPage WebcamPage => ServiceProvider.Get(); public MainViewModel MainViewModel => ServiceProvider.Get(); public RecentViewModel RecentViewModel => ServiceProvider.Get(); public ScreenShotViewModel ScreenShotViewModel => ServiceProvider.Get(); public AboutViewModel AboutViewModel => ServiceProvider.Get(); public RegionSelectorViewModel RegionSelectorViewModel => ServiceProvider.Get(); public FFmpegDownloadViewModel FFmpegDownloadViewModel => ServiceProvider.Get(); public FFmpegLogViewModel FFmpegLog => ServiceProvider.Get(); public IFpsManager FpsManager => ServiceProvider.Get(); public FFmpegCodecsViewModel FFmpegCodecsViewModel => ServiceProvider.Get(); public ProxySettingsViewModel ProxySettingsViewModel => ServiceProvider.Get(); public LicensesViewModel LicensesViewModel => ServiceProvider.Get(); public CrashLogsViewModel CrashLogsViewModel => ServiceProvider.Get(); public FileNameFormatViewModel FileNameFormatViewModel => ServiceProvider.Get(); public YouTubeUploaderViewModel YouTubeUploaderViewModel => ServiceProvider.Get(); public SoundsViewModel SoundsViewModel => ServiceProvider.Get(); public KeymapViewModel Keymap => ServiceProvider.Get(); public EditorWriter EditorWriter => ServiceProvider.Get(); public HotkeysViewModel HotkeysViewModel => ServiceProvider.Get(); public IIconSet Icons => ServiceProvider.Get(); public UpdateCheckerViewModel UpdateCheckerViewModel => ServiceProvider.Get(); public CustomImageOverlaysViewModel CustomImageOverlays => ServiceProvider.Get(); public CustomOverlaysViewModel CustomOverlays => ServiceProvider.Get(); public CensorOverlaysViewModel CensorOverlays => ServiceProvider.Get(); public ViewConditionsModel ViewConditions => ServiceProvider.Get(); public TimerModel TimerModel => ServiceProvider.Get(); public AudioSourceViewModel AudioSource => ServiceProvider.Get(); public WebcamModel WebcamModel => ServiceProvider.Get(); public VideoWritersViewModel VideoWritersViewModel => ServiceProvider.Get(); public VideoSourcesViewModel VideoSourcesViewModel => ServiceProvider.Get(); public RecordingViewModel RecordingViewModel => ServiceProvider.Get(); } } ================================================ FILE: src/Captura/Models/SingleInstanceManager.cs ================================================ using System; using System.Threading; using System.Threading.Tasks; namespace Captura.Models { public static class SingleInstanceManager { // ReSharper disable once NotAccessedField.Local static Mutex _mutex; // ReSharper disable once NotAccessedField.Local static Task _task; // Mutex allows us to know whether another instance is already open const string MutexId = "captura-mutex-304bae7c-e520-4bfe-a308-c99476062091"; // EventWaitHandle allows us to communicate to a already running instance const string EventWaitHandleId = "captura-wait-304bae7c-e520-4bfe-a308-c99476062091"; public static void SingleInstanceCheck() { _mutex = new Mutex(true, MutexId, out var createdNew); if (!createdNew) { // Bring the already running instance to the foreground var handle = CreateWaitHandle(); handle.Set(); // Exit duplicate instance Environment.Exit(0); } } static EventWaitHandle CreateWaitHandle() { return new EventWaitHandle(false, EventResetMode.AutoReset, EventWaitHandleId); } public static void StartListening(Action Callback) { // First instance listens for events from other instances in a loop _task = Task.Run(() => { var waitHandle = CreateWaitHandle(); while (true) { waitHandle.WaitOne(); // Callback should bring first instance to foreground Callback.Invoke(); } }); } } } ================================================ FILE: src/Captura/Models/SystemInfo.cs ================================================ using System; using System.Management; using System.Text; using Captura.Audio; using Captura.ViewModels; using Captura.Webcam; namespace Captura.Models { public static class SystemInfo { public static string GetInfo() { var sb = new StringBuilder(); sb.AppendLine($"{nameof(Captura)} v{AboutViewModel.Version}"); sb.AppendLine(OsInfo()); sb.AppendLine($"{(Environment.Is64BitOperatingSystem ? 64 : 32)}-bit OS"); sb.AppendLine($"{(Environment.Is64BitProcess ? 64 : 32)}-bit Process"); sb.AppendLine($"{Environment.ProcessorCount} processor(s)"); sb.AppendLine(); sb.Append(CpuInfo()); sb.Append(RamInfo()); sb.Append(GpuInfo()); var platformServices = ServiceProvider.Get(); try { sb.AppendLine($"Desktop: {platformServices.DesktopRectangle}"); foreach (var screen in platformServices.EnumerateScreens()) { sb.AppendLine($"Screen: {screen.DeviceName}: {screen.Rectangle}"); } } catch { sb.AppendLine("Unable to get screen dimensions"); } var audioSource = ServiceProvider.Get(); try { foreach (var mic in audioSource.Microphones) { sb.AppendLine($"Mic: {mic.Name}"); } foreach (var speaker in audioSource.Speakers) { sb.AppendLine($"Speaker: {speaker.Name}"); } } catch { sb.AppendLine("Unable to get audio devices"); } try { var webcamSource = ServiceProvider.Get(); foreach (var webcam in webcamSource.GetSources()) { sb.AppendLine($"Webcam: {webcam.Name}"); } } catch { sb.AppendLine("Unable to get webcams"); } sb.AppendLine(); return sb.ToString(); } static string DeviceInformation(string ClassName, string[] Properties) { var sb = new StringBuilder(); foreach (var instance in new ManagementClass(ClassName).GetInstances()) { foreach (var property in Properties) { try { sb.AppendLine($"{property}: {instance.Properties[property].Value}"); } catch { //Add codes to manage more information } } sb.AppendLine(); } return sb.ToString(); } static string CpuInfo() { return DeviceInformation("Win32_Processor", new[] { "Name", "NumberOfCores", "NumberOfLogicalProcessors" }); } static string GpuInfo() { return DeviceInformation("Win32_VideoController", new[] { "Name", "AdapterRAM" }); } static string OsInfo() { var devInfo = DeviceInformation("Win32_OperatingSystem", new[] { "Name" }); return $"OS: {devInfo.Split(':')[1].Trim()}"; } static string RamInfo() { return DeviceInformation("Win32_PhysicalMemory", new[] { "Name", "Capacity" }); } } } ================================================ FILE: src/Captura/Models/SystemTray.cs ================================================ using Hardcodet.Wpf.TaskbarNotification; using System; using System.Windows.Controls.Primitives; using Captura.Audio; namespace Captura.Models { // ReSharper disable once ClassNeverInstantiated.Global class SystemTray : ISystemTray, IDisposable { bool _first = true; /// /// Using a Function ensures that the object is used only after it is initialised. /// readonly Func _trayIcon; readonly Settings _settings; readonly IAudioPlayer _audioPlayer; readonly NotificationStack _notificationStack = new NotificationStack(); public SystemTray(Func TaskbarIcon, Settings Settings, IAudioPlayer AudioPlayer) { _trayIcon = TaskbarIcon; _settings = Settings; _audioPlayer = AudioPlayer; _notificationStack.Opacity = 0; } public void HideNotification() { _notificationStack.Hide(); } void Show() { var trayIcon = _trayIcon.Invoke(); if (trayIcon != null && _first) { trayIcon.ShowCustomBalloon(_notificationStack, PopupAnimation.None, null); _first = false; } _audioPlayer.Play(SoundKind.Notification); _notificationStack.Show(); } public void ShowScreenShotNotification(string FilePath) { if (!_settings.Tray.ShowNotifications) return; _notificationStack.Add(new ScreenShotBalloon(FilePath)); Show(); } public void ShowNotification(INotification Notification) { if (!_settings.Tray.ShowNotifications) return; _notificationStack.Add(new NotificationBalloon(Notification)); Show(); } public void Dispose() { _trayIcon.Invoke()?.Dispose(); } } } ================================================ FILE: src/Captura/Models/VideoSourcePicker.cs ================================================ using System; using System.Drawing; namespace Captura.Video { // ReSharper disable once ClassNeverInstantiated.Global public class VideoSourcePicker : IVideoSourcePicker { public IWindow PickWindow(Predicate Filter = null) { return VideoSourcePickerWindow.PickWindow(Filter); } public IScreen PickScreen() { return ScreenPickerWindow.PickScreen(); } public Rectangle? PickRegion() { return RegionPickerWindow.PickRegion(); } } } ================================================ FILE: src/Captura/Pages/AboutPage.xaml ================================================  ================================================ FILE: src/Captura/Pages/HomePage.xaml.cs ================================================ namespace Captura { public partial class HomePage { public HomePage() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Pages/HotkeysPage.xaml ================================================  ================================================ FILE: src/Captura/Pages/ScreenShotsPage.xaml.cs ================================================ namespace Captura { public partial class ScreenShotsPage { public ScreenShotsPage() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Pages/SettingsPage.xaml ================================================  ================================================ FILE: src/Captura/Pages/SettingsPage.xaml.cs ================================================ namespace Captura { public partial class SettingsPage { public SettingsPage() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Pages/SoundsPage.xaml ================================================  ================================================ FILE: src/Captura/Pages/SoundsPage.xaml.cs ================================================ using System.Windows; using System.Windows.Input; using Captura.ViewModels; namespace Captura { public partial class SoundsPage { public SoundsPage() { InitializeComponent(); } void SetFile(object Sender, MouseButtonEventArgs E) { if (Sender is FrameworkElement element && element.DataContext is SoundsViewModelItem vm) { vm.SetCommand.ExecuteIfCan(); } } } } ================================================ FILE: src/Captura/Pages/TextOverlaysPage.xaml ================================================  ================================================ FILE: src/Captura/Pages/TextOverlaysPage.xaml.cs ================================================ namespace Captura { public partial class TextOverlaysPage { public TextOverlaysPage() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Pages/TrayIconPage.xaml ================================================  ================================================ FILE: src/Captura/Pages/TrayIconPage.xaml.cs ================================================ namespace Captura { public partial class TrayIconPage { public TrayIconPage() { InitializeComponent(); } } } ================================================ FILE: src/Captura/Pages/VideoPage.xaml ================================================  Use GDI instead of DesktopDuplication ================================================ FILE: src/Captura/Windows/ScreenPickerWindow.xaml.cs ================================================ using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Input; using Captura.Video; using Captura.ViewModels; using Reactive.Bindings; namespace Captura { public partial class ScreenPickerWindow { const double Scale = 0.15; public ObservableCollection ScreenPickerViewModels { get; } = new ObservableCollection(); public ICommand SelectScreenCommand { get; } ScreenPickerWindow() { SelectScreenCommand = new ReactiveCommand() .WithSubscribe(M => { SelectedScreen = M; Close(); }); InitializeComponent(); ScreenContainer.Width = SystemParameters.VirtualScreenWidth * Scale; ScreenContainer.Height = SystemParameters.VirtualScreenHeight * Scale; var platformServices = ServiceProvider.Get(); var screens = platformServices.EnumerateScreens().ToArray(); foreach (var screen in screens) { ScreenPickerViewModels.Add(new ScreenPickerViewModel(screen, Scale)); } } public IScreen SelectedScreen { get; private set; } void CloseClick(object Sender, RoutedEventArgs E) { SelectedScreen = null; Close(); } public static IScreen PickScreen() { var picker = new ScreenPickerWindow { Owner = MainWindow.Instance }; picker.ShowDialog(); return picker.SelectedScreen; } } } ================================================ FILE: src/Captura/Windows/SettingsWindow.xaml ================================================  ================================================ FILE: src/Captura/Windows/SettingsWindow.xaml.cs ================================================ using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Navigation; namespace Captura { public partial class SettingsWindow { SettingsWindow() { InitializeComponent(); } static SettingsWindow _instance; public static void ShowInstance() { if (_instance == null) { _instance = new SettingsWindow(); _instance.Closed += (S, E) => _instance = null; } _instance.ShowAndFocus(); } void OnGoToPage(object Sender, ExecutedRoutedEventArgs E) { if (Sender is Frame frame) { switch (E.Parameter) { case string s: frame.Navigate(new Uri(s, UriKind.RelativeOrAbsolute)); break; case { } o: frame.Navigate(o); break; } } } static void ShowPage(string PageName) { ShowInstance(); _instance.NavFrame.Navigate(new Uri($"/Pages/{PageName}Page.xaml", UriKind.RelativeOrAbsolute)); } public static void ShowFFmpegLogs() => ShowPage("FFmpegLogs"); public static void ShowWebcamPage() { ShowInstance(); _instance.NavFrame.Navigate(ServiceProvider.Get()); } void OnGoBack(object Sender, RoutedEventArgs E) { NavFrame.GoBack(); } void OnGoNext(object Sender, RoutedEventArgs E) { NavFrame.GoForward(); } void NavFrame_OnNavigated(object Sender, NavigationEventArgs E) { if (E.Content is Page page) { var transform = new TranslateTransform(); page.RenderTransform = transform; var anim = new DoubleAnimation { Duration = TimeSpan.FromSeconds(0.3), DecelerationRatio = 0.5, From = 100, To = 0 }; transform.BeginAnimation(TranslateTransform.XProperty, anim); } else Console.WriteLine(E.Content); } } } ================================================ FILE: src/Captura/Windows/TrimmerWindow.xaml ================================================  ================================================ FILE: src/Captura/Windows/TrimmerWindow.xaml.cs ================================================ using System; using System.Windows.Controls; using System.Windows.Input; namespace Captura.Views { public partial class TrimmerWindow { public TrimmerWindow() { InitializeComponent(); if (DataContext is TrimmerViewModel vm) { vm.AssignPlayer(MediaElement); Closing += (S, E) => vm.Dispose(); } } public void Open(string FileName) { if (DataContext is TrimmerViewModel vm) { vm.Open(FileName); } } void Slider_PreviewMouseLeftButtonUp(object Sender, MouseButtonEventArgs E) { if (DataContext is TrimmerViewModel vm && Sender is Slider slider) { if (!vm.IsDragging) return; vm.PlaybackPosition = TimeSpan.FromSeconds(slider.Value); vm.IsDragging = false; } } void Slider_PreviewMouseLeftButtonDown(object Sender, MouseButtonEventArgs E) { if (DataContext is TrimmerViewModel vm) { vm.IsDragging = true; } } void Slider_MouseLeftButtonUp(object Sender, MouseButtonEventArgs E) { if (DataContext is TrimmerViewModel vm && Sender is Slider slider) { vm.PlaybackPosition = TimeSpan.FromSeconds(slider.Value); } } } } ================================================ FILE: src/Captura/Windows/VideoSourcePickerWindow.xaml ================================================