diff --git a/LICENSE.md b/LICENSE.md index 485ef83a5..eb9a11018 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License -(c) Copyright 2017 Mathew Sachin. +(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"), diff --git a/README.md b/README.md index 1205a4c29..3025c8906 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![MIT License](https://img.shields.io/github/license/MathewSachin/Captura.svg?style=flat-square)](LICENSE.md) [![Chat](https://img.shields.io/gitter/room/MathewSachin/Screna.svg?style=flat-square)](https://gitter.im/MathewSachin/Screna) [![Downloads](https://img.shields.io/github/downloads/MathewSachin/Captura/total.svg?style=flat-square)](https://github.com/MathewSachin/Captura/releases) -© [Copyright 2017](LICENSE.md) Mathew Sachin +© [Copyright 2018](LICENSE.md) Mathew Sachin :link: https://mathewsachin.github.io/Captura/ diff --git a/choco/captura.nuspec b/choco/captura.nuspec index 717d877a8..e9957cec5 100644 --- a/choco/captura.nuspec +++ b/choco/captura.nuspec @@ -13,7 +13,7 @@ https://github.com/MathewSachin/Captura/issues https://github.com/MathewSachin/Captura/wiki https://gitter.im/MathewSachin/Screna - (c) 2017 Mathew Sachin + (c) 2018 Mathew Sachin captura screen capture recording loopback screenshot screencast Capture Screen/Audio/Cursor/Clicks/Keystrokes diff --git a/licenses/Captura, Screna, ManagedBass.txt b/licenses/Captura, Screna, ManagedBass.txt index 1ecceb382..8d6efdbdb 100644 --- a/licenses/Captura, Screna, ManagedBass.txt +++ b/licenses/Captura, Screna, ManagedBass.txt @@ -1,6 +1,6 @@ The MIT License -(c) Copyright 2017 Mathew Sachin. +(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: diff --git a/src/Captura.Console/Program.cs b/src/Captura.Console/Program.cs index 581387c66..d5c5ad46d 100644 --- a/src/Captura.Console/Program.cs +++ b/src/Captura.Console/Program.cs @@ -77,124 +77,128 @@ static void List() { Banner(); - using (var vm = ServiceProvider.Get()) - { - vm.Init(false, false, false, false); - - var underline = $"\n{new string('-', 30)}"; - - var video = vm.VideoViewModel; + var underline = $"\n{new string('-', 30)}"; - #region FFmpeg - var ffmpegExists = FFMpegService.FFMpegExists; + #region FFmpeg + var ffmpegExists = FFMpegService.FFMpegExists; - WriteLine($"FFmpeg Available: {(ffmpegExists ? "YES" : "NO")}"); + WriteLine($"FFmpeg Available: {(ffmpegExists ? "YES" : "NO")}"); - WriteLine(); + WriteLine(); - if (ffmpegExists) - { - WriteLine("FFmpeg ENCODERS" + underline); + if (ffmpegExists) + { + WriteLine("FFmpeg ENCODERS" + underline); - video.SelectedVideoWriterKind = ServiceProvider.Get(); + var writerProvider = ServiceProvider.Get(); - for (var i = 0; i < video.AvailableVideoWriters.Count; ++i) - { - WriteLine($"{i.ToString().PadRight(2)}: {video.AvailableVideoWriters[i]}"); - } + var i = 0; - WriteLine(); + foreach (var codec in writerProvider) + { + WriteLine($"{i.ToString().PadRight(2)}: {codec}"); + ++i; } - #endregion - - #region SharpAvi - var sharpAviExists = ServiceProvider.FileExists("SharpAvi.dll"); - - WriteLine($"SharpAvi Available: {(sharpAviExists ? "YES" : "NO")}"); WriteLine(); + } + #endregion - if (sharpAviExists) - { - WriteLine("SharpAvi ENCODERS" + underline); + #region SharpAvi + var sharpAviExists = ServiceProvider.FileExists("SharpAvi.dll"); - video.SelectedVideoWriterKind = ServiceProvider.Get(); + WriteLine($"SharpAvi Available: {(sharpAviExists ? "YES" : "NO")}"); - for (var i = 0; i < video.AvailableVideoWriters.Count; ++i) - { - WriteLine($"{i.ToString().PadRight(2)}: {video.AvailableVideoWriters[i]}"); - } + WriteLine(); - WriteLine(); - } - #endregion + if (sharpAviExists) + { + WriteLine("SharpAvi ENCODERS" + underline); - #region Windows - WriteLine("AVAILABLE WINDOWS" + underline); + var writerProvider = ServiceProvider.Get(); - video.SelectedVideoSourceKind = ServiceProvider.Get(); + var i = 0; - foreach (var source in video.AvailableVideoSources.OfType()) + foreach (var codec in writerProvider) { - WriteLine($"{source.Window.Handle.ToString().PadRight(10)}: {source}"); + WriteLine($"{i.ToString().PadRight(2)}: {codec}"); + ++i; } WriteLine(); - #endregion + } + #endregion - #region Screens - WriteLine("AVAILABLE SCREENS" + underline); + #region Windows + WriteLine("AVAILABLE WINDOWS" + underline); - video.SelectedVideoSourceKind = ServiceProvider.Get(); + var winProvider = ServiceProvider.Get(); - for (var i = 0; i < video.AvailableVideoSources.Count; ++i) - { - WriteLine($"{i.ToString().PadRight(2)}: {video.AvailableVideoSources[i]}"); - } + foreach (var source in winProvider.OfType()) + { + WriteLine($"{source.Window.Handle.ToString().PadRight(10)}: {source}"); + } - WriteLine(); - #endregion + WriteLine(); + #endregion - #region MouseKeyHook - WriteLine($"MouseKeyHook Available: {(vm.MouseKeyHookAvailable ? "YES" : "NO")}"); + #region Screens + WriteLine("AVAILABLE SCREENS" + underline); - WriteLine(); - #endregion + var scrProvider = ServiceProvider.Get(); - var audio = vm.AudioViewModel.AudioSource; + var j = 0; - WriteLine($"ManagedBass Available: {(audio is BassAudioSource ? "YES" : "NO")}"); + // First is Full Screen + foreach (var screen in scrProvider.Skip(1)) + { + WriteLine($"{j.ToString().PadRight(2)}: {screen}"); - WriteLine(); + ++j; + } - #region Microphones - if (audio.AvailableRecordingSources.Count > 1) - { - WriteLine("AVAILABLE MICROPHONES" + underline); + WriteLine(); + #endregion - for (var i = 1; i < audio.AvailableRecordingSources.Count; ++i) - { - WriteLine($"{(i - 1).ToString().PadRight(2)}: {audio.AvailableRecordingSources[i]}"); - } + #region MouseKeyHook + WriteLine($"MouseKeyHook Available: {(ServiceProvider.Get().MouseKeyHookAvailable ? "YES" : "NO")}"); - WriteLine(); - } - #endregion + WriteLine(); + #endregion + + var audio = ServiceProvider.Get(); + + WriteLine($"ManagedBass Available: {(audio is BassAudioSource ? "YES" : "NO")}"); + + WriteLine(); + + #region Microphones + if (audio.AvailableRecordingSources.Count > 1) + { + WriteLine("AVAILABLE MICROPHONES" + underline); - #region Speaker - if (audio.AvailableLoopbackSources.Count > 1) + for (var i = 1; i < audio.AvailableRecordingSources.Count; ++i) { - WriteLine("AVAILABLE SPEAKER SOURCES" + underline); + WriteLine($"{(i - 1).ToString().PadRight(2)}: {audio.AvailableRecordingSources[i]}"); + } - for (var i = 1; i < audio.AvailableLoopbackSources.Count; ++i) - { - WriteLine($"{(i - 1).ToString().PadRight(2)}: {audio.AvailableLoopbackSources[i]}"); - } + WriteLine(); + } + #endregion - WriteLine(); + #region Speaker + if (audio.AvailableLoopbackSources.Count > 1) + { + WriteLine("AVAILABLE SPEAKER SOURCES" + underline); + + for (var i = 1; i < audio.AvailableLoopbackSources.Count; ++i) + { + WriteLine($"{(i - 1).ToString().PadRight(2)}: {audio.AvailableLoopbackSources[i]}"); } - #endregion + + WriteLine(); } + #endregion } static void Banner() @@ -202,7 +206,7 @@ static void Banner() var version = Assembly.GetExecutingAssembly().GetName().Version.ToString(3); WriteLine($@"Captura v{version} -(c) 2017 Mathew Sachin +(c) 2018 Mathew Sachin "); } diff --git a/src/Captura/Views/AboutView.xaml b/src/Captura/Views/AboutView.xaml index 1e74f7f0e..0d75f99d7 100644 --- a/src/Captura/Views/AboutView.xaml +++ b/src/Captura/Views/AboutView.xaml @@ -16,7 +16,7 @@ LineHeight="30" Style="{StaticResource TextColor}"> - (c) 2017 Mathew Sachin + (c) 2018 Mathew Sachin Point Transform Function. public OverlayedImageProvider(IImageProvider ImageProvider, Func Transform, params IOverlay[] Overlays) { - _imageProvider = ImageProvider; - _overlays = Overlays; - _transform = Transform; + _imageProvider = ImageProvider ?? throw new ArgumentNullException(nameof(ImageProvider)); + _overlays = Overlays ?? throw new ArgumentNullException(nameof(Overlays)); + _transform = Transform ?? throw new ArgumentNullException(nameof(Transform)); Width = ImageProvider.Width; Height = ImageProvider.Height; diff --git a/src/Screna/ImageProviders/WindowProvider.cs b/src/Screna/ImageProviders/WindowProvider.cs index 671af6a7d..0bfb762ec 100644 --- a/src/Screna/ImageProviders/WindowProvider.cs +++ b/src/Screna/ImageProviders/WindowProvider.cs @@ -73,7 +73,7 @@ static Func GetTransformer(Window Window) /// public WindowProvider(Window Window, bool IncludeCursor, out Func Transform) { - _window = Window; + _window = Window ?? throw new ArgumentNullException(nameof(Window)); _includeCursor = IncludeCursor; var size = Window.Rectangle.Even().Size; diff --git a/src/Screna/Overlays/MouseCursor.cs b/src/Screna/Overlays/MouseCursor.cs index bd72ce3e6..436368b99 100644 --- a/src/Screna/Overlays/MouseCursor.cs +++ b/src/Screna/Overlays/MouseCursor.cs @@ -49,7 +49,7 @@ public static Point CursorPosition } // hCursor -> (Icon, Hotspot) - static readonly Dictionary> _cursors = new Dictionary>(); + static readonly Dictionary> Cursors = new Dictionary>(); /// /// Draws this overlay. @@ -59,6 +59,7 @@ public static Point CursorPosition public static void Draw(Graphics g, Func Transform = null) { // ReSharper disable once RedundantAssignment + // ReSharper disable once InlineOutVariableDeclaration var cursorInfo = new CursorInfo { cbSize = Marshal.SizeOf() }; if (!GetCursorInfo(out cursorInfo)) @@ -70,9 +71,9 @@ public static void Draw(Graphics g, Func Transform = null) Bitmap icon; Point hotspot; - if (_cursors.ContainsKey(cursorInfo.hCursor)) + if (Cursors.ContainsKey(cursorInfo.hCursor)) { - var tuple = _cursors[cursorInfo.hCursor]; + var tuple = Cursors[cursorInfo.hCursor]; icon = tuple.Item1; hotspot = tuple.Item2; @@ -84,18 +85,18 @@ public static void Draw(Graphics g, Func Transform = null) if (hIcon == IntPtr.Zero) return; - if (!GetIconInfo(hIcon, out var _icInfo)) + if (!GetIconInfo(hIcon, out var icInfo)) return; icon = Icon.FromHandle(hIcon).ToBitmap(); - hotspot = new Point(_icInfo.xHotspot, _icInfo.yHotspot); + hotspot = new Point(icInfo.xHotspot, icInfo.yHotspot); - _cursors.Add(cursorInfo.hCursor, Tuple.Create(icon, hotspot)); + Cursors.Add(cursorInfo.hCursor, Tuple.Create(icon, hotspot)); DestroyIcon(hIcon); - DeleteObject(_icInfo.hbmColor); - DeleteObject(_icInfo.hbmMask); + DeleteObject(icInfo.hbmColor); + DeleteObject(icInfo.hbmMask); } var location = new Point(cursorInfo.ptScreenPos.X - hotspot.X, diff --git a/src/Screna/Recorder/Recorder.cs b/src/Screna/Recorder/Recorder.cs index cd77a266d..f2eda87ac 100644 --- a/src/Screna/Recorder/Recorder.cs +++ b/src/Screna/Recorder/Recorder.cs @@ -42,6 +42,9 @@ public Recorder(IVideoFileWriter VideoWriter, IImageProvider ImageProvider, int _imageProvider = ImageProvider ?? throw new ArgumentNullException(nameof(ImageProvider)); _audioProvider = AudioProvider; + if (FrameRate <= 0) + throw new ArgumentException("Frame Rate must be possitive", nameof(FrameRate)); + _frameRate = FrameRate; _continueCapturing = new ManualResetEvent(false); diff --git a/src/Screna/ScreenShot.cs b/src/Screna/ScreenShot.cs index 67a4ef84a..c029c1d89 100644 --- a/src/Screna/ScreenShot.cs +++ b/src/Screna/ScreenShot.cs @@ -39,14 +39,20 @@ public static class ScreenShot /// The Captured Image. public static Bitmap Capture(Screen Screen, bool IncludeCursor = false) { + if (Screen == null) + throw new ArgumentNullException(nameof(Screen)); + return Capture(Screen.Bounds, IncludeCursor); } public static Bitmap Capture(Window Window, bool IncludeCursor = false) { + if (Window == null) + throw new ArgumentNullException(nameof(Window)); + return Capture(Window.Rectangle, IncludeCursor); } - + /// /// Captures the entire Desktop. /// @@ -64,6 +70,9 @@ public static Bitmap Capture(bool IncludeCursor = false) /// Whether to include Mouse Cursor. public static Bitmap CaptureTransparent(Window Window, bool IncludeCursor = false) { + if (Window == null) + throw new ArgumentNullException(nameof(Window)); + var backdrop = new Form { AllowTransparency = true, @@ -137,6 +146,9 @@ public static Bitmap CaptureTransparent(Window Window, bool IncludeCursor = fals /// Capture Height. public static Bitmap CaptureTransparent(Window Window, bool IncludeCursor, bool DoResize, int ResizeWidth, int ResizeHeight) { + if (Window == null) + throw new ArgumentNullException(nameof(Window)); + var startButtonHandle = User32.FindWindow("Button", "Start"); var taskbarHandle = User32.FindWindow("Shell_TrayWnd", null); diff --git a/src/Tests/AudioFileWriterTests.cs b/src/Tests/AudioFileWriterTests.cs new file mode 100644 index 000000000..4450b4952 --- /dev/null +++ b/src/Tests/AudioFileWriterTests.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Screna.Audio; + +namespace Captura.Tests +{ + [TestClass] + public class AudioFileWriterTests + { + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void NullAudioOutputStream() + { + using (new AudioFileWriter(OutStream: null, Format: new WaveFormat())) + { + + } + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void NullWaveFormat() + { + using (new AudioFileWriter(Stream.Null, null)) + { + + } + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void NullFileName() + { + using (new AudioFileWriter(FileName: null, Format: new WaveFormat())) + { + + } + } + } +} \ No newline at end of file diff --git a/src/Tests/RecorderTests.cs b/src/Tests/RecorderTests.cs index cb8069578..8b9b89f30 100644 --- a/src/Tests/RecorderTests.cs +++ b/src/Tests/RecorderTests.cs @@ -67,5 +67,31 @@ public void NullGifWriter() } } + + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void NegativeFrameRate() + { + var imageProvider = ServiceProvider.Get(); + var videoWriter = ServiceProvider.Get(); + + using (new Recorder(videoWriter, imageProvider, -1)) + { + + } + } + + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void ZeroFrameRate() + { + var imageProvider = ServiceProvider.Get(); + var videoWriter = ServiceProvider.Get(); + + using (new Recorder(videoWriter, imageProvider, 0)) + { + + } + } } } diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 1e3c446d9..8df0e4657 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -96,6 +96,7 @@ +