RecorderMode, 三种:Video, Steps, Replay.
VideoSourcesViewModel 在ViewCore里面,主要为Captura服务的。视频源ViewModel
VideoWritersViewModel 在ViewCore里面,主要为Captura服务的。视频Writer view model.
SelectedVideoWriter 选中的视频Writer。
IVideoWriterItem里面有个函数返回IVideoFileWriter. 从单独的frame里面创建一个视频,并写入到一个文件里面。
把frame写入到视频里面, 帧实际上是IBitmapFrame
IBitmapFrame是个接口,主要包含时间戳,CopyTo(byte[] Buffer), CopyTo(IntPtr Buffer)
MF media foundation, 微软出的,Vista之后的系统都有。
MfWriter继承自IVideoFileWriter
实际的录制对象在Screna工程里面,
Recorder.cs
函数DoRecord, 里面调用了FrameWriter
_fpsManager?.OnFrame();
如果_fpsManager为null,就停止,否则调用OnFrame函数。
WithPreviewWriter实现接口IVideoFileWriter, 有个函数WriteFrame, 调用MfWriter的WriteFrame函数。
MfWriterProvider : IVideoWriterProvider
SharpAviWriterProvider: IVideoWriterProvider
FFmpegWriterProvider : IVideoWriterProvider
IVideoWriterProvider : IEnumerable<IVideoWriterItem>
接口里面有个重要函数:ParseCli(string Cli) 返回IVideoWriterItem.
选择是录制全屏,窗口,屏幕,还是区域是在Screna项目里面,VideoSourceProviders目录当中:
1. FullScreenSourceProvider
2. RegionSourceProvider
3. ScreenSourceProvider
4. VideoSourceProvider
5. WindowSourceProvider
如果不想用ffmpeg,可以用Windows自身的media foundation, 需要工程Captura.Windows
在Core项目中OnLoad函数中调用BindVideoSourceProvider(Binder), 在改函数中调用
Binder.BindAsInterfaceAndClass<IVideoSourceProvider, RegionSourceProvider>();
首先在App.xaml.cs中Application_Startup调用静态ServiceProvider.LoadModule(new CoreModule());
再次盗用Kernel.Load(new Binder(Module));
在Base项目中Binder.cs类中调用Load()--》_module.OnLoad(this);
Base项目中ServiceProvider.cs中List<IModule> 添加Module.
选择窗口还是区域等,是在ServiceLocator.cs中,有个ScreenShotViewModel(在ViewCore项目当中)
在ScreenShotModel中,有个函数ScreenshotRegion, 调用IVideoSourcePicker.PickRegion();
在VideoSourcePicker类中,调用RegionPickerWindow.PickRegion, 显示picker.ShowDialog();
在RegionSelectorProvider类中定义了readonly Lazy<RegionSelector> _regionSelector;
RegionItem包含IRegionProvider和IPlatformService, IRegionProvider里面有个Rectangle和IVideoItem
RegionSelectorProvider实现IRegionProvider
RegionSelectorProvider有个属性SelectedRegion, 引用的是RegionSelectorViewModel里面的SelectedRegion
IPlatformService用来枚举系统里面所有的屏幕,窗口,光标位置,IImageProvider
RegionProvider实现了IImageProvider接口。
WindowsPlatformServices.cs类中有个函数GetRegionProvider
在RecordingViewModel类中的StartRecording函数中,
录制的时候需要三个东西:
IVideoSourcedProvider 定义窗口还是区域大小等。
VideoWriter,写帧到文件里面
Microphone, 需要录制麦克风?
IAudioPlayer接口只有一个函数Play
AudioPlayer类实现了IAudioPlayer接口。该类中有声音设置和MediaPlayer播放器,用于录制声音。
暂停的时候,调用_audioPlayer.Play(SoundKind.Pause)和RecordingModel.OnPauseExecute();
在Core模块里面设计到RecordingModel, 里面有函数OnPauseExecute,涉及到定时器TimerModel(也在Core项目中)。
调用User32.RegisterHotKey注册热键。如果返回false,已经被别的程序注册了。
AudioSettings,音频设置,比如quality默认为80,这个设置包含在Settings里面
在Application_Startup中var settings = ServiceProvider.Get<Settings>();获取所有的设置。
三个DI模块:
1. CoreModule, Core project
2. ViewCoreModule, ViewCore project
3. MainModule, 主项目
Overlay覆盖层:
1. KeyOverlay 按键覆盖
2. MouseClickOverlay 鼠标覆盖
3. MouseKeyOverlay
4. ScrollOverlay
5. ImageOverlay
6. MousePointerOverlay
7. TextOverlay
Screna项目中有很多Overlay
MessageProvider里面包含一个ILocalizationProvider,主要显示出错信息,显示异常信息, 显示是或者否等,容易替换。
ServiceName枚举类型
None, ScreenShot, Pause, DesktopScreenShot, ActiveScreenShot, ToggleMouseClicks, ToggleKeystrokes, ScreenShotRegion, ...
Service就是显示ServiceName用的。构造函数有个ServiceName,
Modifiers, 枚举类型
1. None
2. Alt
3. Ctrl
4. Shift
IHotkeyListener, 接口,里面有个HotkeyReceived事件
HotkeyModel, 快捷键模型, 从Hotkeys.json文件中读出来。形成一个一个的HotkeyModel
然后由HotkeyModel生成Hotkey
Hotkey的IsActive,set的时候该注册的注册,该卸载的卸载
在MainWindow的构造函数里面调用_helper.HotkeySetup.Setup();进行快捷键的注册,从json中读入等动作。
在创建ServiceProvider.Get<MainViewModel>的时候创建HotKeyManager, 而在创建HotKeyManager的时候,因为构造函数里面有
所有的按键事件处理函数在HotKeyManager中,ProcessHotkey(int Id)
再依次调用HotkeyPressed += M => {
foreach (var actor in HotkeyActors)
{
actor.Act(M);
}
HotkeyActor按钮处理对象,由该对象处理按键。
RecordingViewModel构造函数传进来一个RecordingModel
在MainViewModel的Dispose函数里面,把当前的选项保存起来,调用Remember函数实现的。
录制框如何出来的?
1. RestoreVideoSource, 从Settings.Video.Source里面反序列化得到配置参数。
2. 由配置参数得到录制区域大小, RegionSourceProvider.Deserialize函数
3. 设置RegionSelectorProvider的SelectorVisible为true,调用_regionSelector.Value.Show()显示选择框。
4. RegionSelectorProvider实现IRegionProvider接口。
5. 从单例里面获取录制区域的大小,设置RegionSelectorProvider的SelectorVisible属性,控制窗口的显示与否。
6. 先要设置窗口大小,再把visible属性设置为true就可以了。
7. 本来是再MainWindow的构造函数里面实现的,改为按钮控制。
8. 要想显示,需要获取RegionSelectorProvider的对象,在MainModule的OnLoad函数里面绑定了。
9. 录制框出来之后,注册热键
启动的时候在RegionSourceProvider里面设置SelectorVisible = true;的,然后显示框。
Settings.GetOutputPath()最后生成的mp4的目录
VideoSourcesViewModel是单例的,里面包含
public IEnumerable<IVideoSourceProvider> VideoSources { get; }
IVideoSourceProvider
RegionSourceProvider继承自VideoSourceProviderBase
VideoSourceProviderBase实现IVideoSourceProvider接口
而RegionSourceProvider里面包含_regionProvider.是IRegionProvider接口类型
而RegionSelectorProvider实现IRegionProvider接口。
切换录课方框是通过VideoSourcesViewModel里面的VideoSources获取唯一的选项,然后获取
RegionSourceProvider, 进一步获取RegionSourceProvider, 再调用RegionSourceProvider的OnUnselect()函数即可。
通过单例RecordingViewModel来获取RecordingModel,进一步获取视频文件名称。
RecordingModel是单例
overlay相关的:
TextOverlays, ImageOverlays,都实现IOverlay接口, 在Scre项目中。
RecordingModel里面有GetOverlays或者overlay的方法。该类中还有一个方法就是GetImageProviderWithOverlays
--》这个方法同时又被SetupVideoRecorder方法调用,
--》在StartRecording方法中调用
在开始录制时,需要建立VideoRecorder,此时会调用GetImageProviderWithOverlays, 接着调用GetOverlays
登陆时,获取成员信息,如果满足,不铺设overlay,如果不满足,则铺设overlay
需要制定一个接口,根据外部条件决定是否添加overlay
RegionProvider实现IImageProvider接口,提供图片,
在设置里添加overlay,会调用OverlayListViewModel类的OnAddExecute函数,但是这个应该只在设置里起到作用?
图片是CustomImageOverlay, 看看是如何添加到
图片都是OverlayedImageProvider提供的, 它的构造函数里面有个IOverlay[] Overlays, 这个是由GetOverlays函数提供
这个函数里面由一系列的yield return
登录时,根据条件在Settings.ImageOverlays添加图片即可。
只要构造一个ImageOverlays,然后把他添加到Settings.ImageOverlays里面即可。
ImageOverlays里面包含CustomImageOverlaySettings : ImageOverlaySettings
里面重要的两个参数一个时Source,一个时Resize, ResizeWidth, ResizeHeight, 透明度
CustomImageOverlaysViewModel : OverlayListViewModel, 而且是单例很好,
应该是调整好大小,准备录制时定制水印大小,因为要调整位置。
CustomImageOverlay有函数Draw和GetPosition
最后往每一帧视频里面写的时候,需要