protected override void toPlayMotion(int id, float speed, float startFrame, bool isLoop) { string useName = MotionConfig.get(id).useName; if (_animator != null) { _animator.speed = speed; try { _animator.CrossFade(useName, 0f, 0, 0f); } catch (Exception e) { Ctrl.errorLog(e, "播放动画失败", useName, _unit.avatar.getModelID()); } } else if (_animation != null) { _animation.wrapMode = isLoop ? WrapMode.Loop : WrapMode.Once; try { _animation.CrossFade(useName); _animationState = _animation[useName]; _animationState.speed = speed; } catch (Exception e) { Ctrl.errorLog(e, "播放动画失败", useName, _unit.avatar.getModelID()); } } }
/** 找到可用的动作配置 */ private ModelMotionConfig findUseMotionConfig(int modelID, int id) { ModelMotionConfig config = ModelMotionConfig.get(modelID, id); if (config == null) { int backID; MotionConfig mConfig; if ((mConfig = MotionConfig.get(id)) == null) { return(null); } if ((backID = mConfig.backID) == id) { return(null); } return(findUseMotionConfig(modelID, backID)); } return(config); }
private void prePlayMotion(int id, float speed, float startTime, bool isLoop) { int modelID; if ((modelID = _data.avatar != null ? _data.avatar.modelID : -1) <= 0) { return; } _currentMotionID = id; ModelMotionConfig config = findUseMotionConfig(modelID, id); if (config != null) { id = config.id; _currentMotionMaxTime = config.motionTime; } else { _currentMotionMaxTime = MotionConfig.get(id).defaultMotionTime; } _currentMotionUseID = id; _currentMotionSpeed = speed; _currentMotionPassTime = startTime; _currentIsLoop = isLoop; toPlayMotion(id, speed, startTime, isLoop); }
/// <summary> /// Call to enable motion detection. /// </summary> /// <param name="config">The motion configuration.</param> /// <param name="onDetect">A callback for when motion is detected.</param> /// <param name="imageContext">The frame metadata.</param> public void DetectMotion(MotionConfig config, Action onDetect, IImageContext imageContext) { this.Config = config; this.ShouldDetectMotion = true; if (this.MotionType == MotionType.FrameDiff) { this.Analyser = new FrameDiffAnalyser(config, onDetect, imageContext); } else { // TODO: Motion vector analyser } }
/// <summary> /// Call to enable motion detection. /// </summary> /// <param name="config">The motion configuration.</param> /// <param name="onDetect">A callback for when motion is detected.</param> /// <param name="onStopDetect">An optional callback for when the record duration has passed.</param> public void ConfigureMotionDetection(MotionConfig config, Action onDetect, Action onStopDetect = null) { _config = config; _onStopDetect = onStopDetect; if (this.MotionType == MotionType.FrameDiff) { _analyser = new FrameDiffAnalyser(config, onDetect); } else { // TODO: Motion vector analyser } this.EnableMotionDetection(); }
/// <summary> /// Uses configuration settings to prepare the motion detection algorithm and frame /// buffering behaviors. /// </summary> private void ConfigureMotionDetection() { Console.WriteLine("Configuring motion detection."); var motionAlgorithm = new MotionAlgorithmRGBDiff( rgbThreshold: AppConfig.Get.Motion.RgbThreshold, cellPixelPercentage: AppConfig.Get.Motion.CellPercentage, cellCountThreshold: AppConfig.Get.Motion.CellCount ); motionConfig = new MotionConfig( algorithm: motionAlgorithm, testFrameInterval: TimeSpan.FromSeconds(AppConfig.Get.Motion.TestFrameInterval), testFrameCooldown: TimeSpan.FromSeconds(AppConfig.Get.Motion.TestFrameCooldown) ); }
// motion without raw recording, decouple from onDetect event static async Task motion(int totalSeconds, int recordSeconds, int sensitivity) { DeleteFiles(ramdiskPath, "*.h264"); DeleteFiles(ramdiskPath, "*.raw"); var cam = GetConfiguredCamera(); // No longer cut-and-paste from the MMALSharp wiki: // The built-in MotionConfig "recordingTime" argument only applies to calling StartRecording // on the motion buffer, which is RAW (and huge). That also means the onStopDetect action // for cam.WithMotionDetection is not especially useful. So this variation doesn't record the // RAW stream and instead uses a token timeout to terminate the recording. // When using H.264 encoding we require key frames to be generated for the Circular buffer capture handler. MMALCameraConfig.InlineHeaders = true; Console.WriteLine("Preparing pipeline..."); using (var splitter = new MMALSplitterComponent()) { // Two capture handlers are being used here, one for motion detection and the other to record a H.264 stream. using var vidCaptureHandler = new CircularBufferCaptureHandler(4000000, "/media/ramdisk", "h264"); using var motionCircularBufferCaptureHandler = new CircularBufferCaptureHandler(4000000, "/media/ramdisk", "raw"); using var resizer = new MMALIspComponent(); using var vidEncoder = new MMALVideoEncoder(); using var renderer = new MMALVideoRenderer(); cam.ConfigureCameraSettings(); var splitterPortConfig = new MMALPortConfig(MMALEncoding.OPAQUE, MMALEncoding.I420, 0, 0, null); var vidEncoderPortConfig = new MMALPortConfig(MMALEncoding.H264, MMALEncoding.I420, 0, MMALVideoEncoder.MaxBitrateLevel4, null); // The ISP resizer is being used for better performance. Frame difference motion detection will only work if using raw video data. Do not encode to H.264/MJPEG. // Resizing to a smaller image may improve performance, but ensure that the width/height are multiples of 32 and 16 respectively to avoid cropping. var resizerPortConfig = new MMALPortConfig(MMALEncoding.RGB24, MMALEncoding.RGB24, 640, 480, 0, 0, 0, false, null); splitter.ConfigureInputPort(new MMALPortConfig(MMALEncoding.OPAQUE, MMALEncoding.I420), cam.Camera.VideoPort, null); splitter.ConfigureOutputPort(0, splitterPortConfig, null); splitter.ConfigureOutputPort(1, splitterPortConfig, null); resizer.ConfigureOutputPort <VideoPort>(0, resizerPortConfig, motionCircularBufferCaptureHandler); vidEncoder.ConfigureInputPort(new MMALPortConfig(MMALEncoding.OPAQUE, MMALEncoding.I420), splitter.Outputs[1], null); vidEncoder.ConfigureOutputPort(vidEncoderPortConfig, vidCaptureHandler); cam.Camera.VideoPort.ConnectTo(splitter); cam.Camera.PreviewPort.ConnectTo(renderer); splitter.Outputs[0].ConnectTo(resizer); splitter.Outputs[1].ConnectTo(vidEncoder); Console.WriteLine("Camera warmup..."); await Task.Delay(2000); Console.WriteLine($"Detecting motion for {totalSeconds} seconds with sensitivity threshold {sensitivity}..."); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(totalSeconds)); // The recording duration doesn't matter; see notes at top of this method. var motionConfig = new MotionConfig(TimeSpan.FromSeconds(10), sensitivity); // Stephen Cleary says CTS disposal is unnecessary as long as you cancel! https://stackoverflow.com/a/19005066/152997 var startRecordingCTS = LocalPrepareToRecord(); await cam.WithMotionDetection( motionCircularBufferCaptureHandler, motionConfig, // This callback will be invoked when motion has been detected. () => { // This has no effect if the token is already cancelled. startRecordingCTS.Cancel(); }) .ProcessAsync(cam.Camera.VideoPort, cts.Token); CancellationTokenSource LocalPrepareToRecord() { var cts = new CancellationTokenSource(); cts.Token.Register(LocalStartRecording); return(cts); } async void LocalStartRecording() { Console.WriteLine($"Motion detected, recording {recordSeconds} seconds..."); motionCircularBufferCaptureHandler.DisableMotionDetection(); vidCaptureHandler.StartRecording(); vidEncoder.RequestIFrame(); // Prepare to record // Stephen Cleary says CTS disposal is unnecessary as long as you cancel! https://stackoverflow.com/a/19005066/152997 var recordingCTS = new CancellationTokenSource(); // When the token expires, stop recording and re-enable capture recordingCTS.Token.Register(LocalEndRecording); // Start the clock recordingCTS.CancelAfter(recordSeconds * 1000); // Record until the duration passes or the overall motion detection token expires await Task.WhenAny(new Task[] { cts.Token.AsTask(), recordingCTS.Token.AsTask() }); if (!recordingCTS.IsCancellationRequested) { recordingCTS.Cancel(); } } void LocalEndRecording() { Console.WriteLine("...recording stopped."); startRecordingCTS = LocalPrepareToRecord(); motionCircularBufferCaptureHandler.EnableMotionDetection(); vidCaptureHandler.StopRecording(); vidCaptureHandler.Split(); } } // can't use the convenient fall-through using or MMALCamera.Cleanup // throws: Argument is invalid. Unable to destroy component cam.Cleanup(); Console.WriteLine("Exiting."); }
// motion as in the wiki (records raw file) static async Task motion_record_raw(int totalSeconds, int recordSeconds, int sensitivity) { DeleteFiles(ramdiskPath, "*.h264"); DeleteFiles(ramdiskPath, "*.raw"); var cam = GetConfiguredCamera(); // When using H.264 encoding we require key frames to be generated for the Circular buffer capture handler. MMALCameraConfig.InlineHeaders = true; Console.WriteLine("Preparing pipeline..."); using (var splitter = new MMALSplitterComponent()) { // Two capture handlers are being used here, one for motion detection and the other to record a H.264 stream. using var vidCaptureHandler = new CircularBufferCaptureHandler(4000000, "/media/ramdisk", "h264"); using var motionCircularBufferCaptureHandler = new CircularBufferCaptureHandler(4000000, "/media/ramdisk", "raw"); using var resizer = new MMALIspComponent(); using var vidEncoder = new MMALVideoEncoder(); using var renderer = new MMALVideoRenderer(); cam.ConfigureCameraSettings(); // The ISP resizer is being used for better performance. Frame difference motion detection will only work if using raw video data. Do not encode to H.264/MJPEG. // Resizing to a smaller image may improve performance, but ensure that the width/height are multiples of 32 and 16 respectively to avoid cropping. var resizerPortConfig = new MMALPortConfig(MMALEncoding.RGB24, MMALEncoding.RGB24, 640, 480, 0, 0, 0, false, null); var vidEncoderPortConfig = new MMALPortConfig(MMALEncoding.H264, MMALEncoding.I420, 0, MMALVideoEncoder.MaxBitrateLevel4, null); var splitterPortConfig = new MMALPortConfig(MMALEncoding.OPAQUE, MMALEncoding.I420, 0, 0, null); splitter.ConfigureInputPort(new MMALPortConfig(MMALEncoding.OPAQUE, MMALEncoding.I420), cam.Camera.VideoPort, null); splitter.ConfigureOutputPort(0, splitterPortConfig, null); splitter.ConfigureOutputPort(1, splitterPortConfig, null); resizer.ConfigureOutputPort <VideoPort>(0, resizerPortConfig, motionCircularBufferCaptureHandler); vidEncoder.ConfigureInputPort(new MMALPortConfig(MMALEncoding.OPAQUE, MMALEncoding.I420), splitter.Outputs[1], null); vidEncoder.ConfigureOutputPort(vidEncoderPortConfig, vidCaptureHandler); cam.Camera.VideoPort.ConnectTo(splitter); cam.Camera.PreviewPort.ConnectTo(renderer); splitter.Outputs[0].ConnectTo(resizer); splitter.Outputs[1].ConnectTo(vidEncoder); Console.WriteLine("Camera warmup..."); await Task.Delay(2000); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(totalSeconds)); var motionConfig = new MotionConfig(TimeSpan.FromSeconds(recordSeconds), sensitivity); Console.WriteLine($"Detecting motion for {totalSeconds} seconds with sensitivity threshold {sensitivity}..."); await cam.WithMotionDetection( motionCircularBufferCaptureHandler, motionConfig, // This callback will be invoked when motion has been detected. () => { Console.WriteLine($"Motion detected, recording {recordSeconds} seconds..."); // Stop motion detection while we are recording. motionCircularBufferCaptureHandler.DisableMotionDetection(); // Start recording our H.264 video. vidCaptureHandler.StartRecording(); motionCircularBufferCaptureHandler.StartRecording(); // Request a key frame to be immediately generated by the h.264 encoder. vidEncoder.RequestIFrame(); }, // Invoked when motion handler recording-time expires () => { // We want to re-enable the motion detection. motionCircularBufferCaptureHandler.EnableMotionDetection(); // Stop recording on our capture handlers. motionCircularBufferCaptureHandler.StopRecording(); vidCaptureHandler.StopRecording(); // Optionally create new file for our next recording run (don't do the RAW file, we don't want it). vidCaptureHandler.Split(); Console.WriteLine("...recording stopped."); }) .ProcessAsync(cam.Camera.VideoPort, cts.Token); } // can't use the convenient fall-through using or MMALCamera.Cleanup // throws: Argument is invalid. Unable to destroy component cam.Cleanup(); Console.WriteLine("Exiting."); }
/// <summary> /// Call to enable motion detection. /// </summary> /// <param name="handler">The motion capture handler.</param> /// <param name="config">The motion configuration object.</param> /// <param name="onDetect">The callback when motion is detected.</param> /// <param name="onStopDetect">An optional callback which is called when the record duration has passed.</param> /// <returns>The camera instance.</returns> public MMALCamera WithMotionDetection(IMotionCaptureHandler handler, MotionConfig config, Action onDetect, Action onStopDetect = null) { MMALCameraConfig.InlineMotionVectors = true; handler.ConfigureMotionDetection(config, onDetect, onStopDetect); return(this); }
public async Task <IActionResult> Update([FromBody] MotionConfig config) { await _motionService.UpdateConfig(config); return(new OkResult()); }
/// <summary> /// Call to enable motion detection. /// </summary> /// <param name="handler">The motion capture handler.</param> /// <param name="config">The motion configuration object.</param> /// <param name="onDetect">The callback when motion is detected.</param> /// <param name="imageContext">The image metadata.</param> /// <returns>The camera instance.</returns> public MMALCamera WithMotionDetection(IMotionCaptureHandler handler, MotionConfig config, Action onDetect, IImageContext imageContext) { MMALCameraConfig.InlineMotionVectors = true; handler.DetectMotion(config, onDetect, imageContext); return(this); }
public async Task <MotionConfig> UpdateConfig(MotionConfig config) { await _motionConfigHandler.SaveConfiguration(config); return(await GetConfig()); }
/// <summary> /// Creates a new <see cref="FrameBufferCaptureHandler"/> configured for motion detection analysis (either using a recorded /// raw video stream where MMALStandalone.Instance is used, or when the camera is used but triggering motion detection events /// is unnecessary). If motion detection events are desired, use the camera's WithMotionDetection method. /// </summary> /// <param name="motionConfig">The motion configuration.</param> /// <param name="onDetect">A callback for when motion is detected.</param> public FrameBufferCaptureHandler(MotionConfig motionConfig, Action onDetect) : base() { _driver = new FrameDiffDriver(motionConfig, onDetect); _detectingMotion = true; }
/// <inheritdoc /> public void ConfigureMotionDetection(MotionConfig config, Action onDetect) { _driver = new FrameDiffDriver(config, onDetect); this.EnableMotionDetection(); }