Example #1
0
    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());
            }
        }
    }
Example #2
0
    /** 找到可用的动作配置 */
    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);
    }
Example #3
0
    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();
        }
Example #6
0
        /// <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)
                );
        }
Example #7
0
        // 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.");
        }
Example #8
0
        // 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.");
        }
Example #9
0
 /// <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);
 }
Example #10
0
        public async Task <IActionResult> Update([FromBody] MotionConfig config)
        {
            await _motionService.UpdateConfig(config);

            return(new OkResult());
        }
Example #11
0
 /// <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);
 }
Example #12
0
        public async Task <MotionConfig> UpdateConfig(MotionConfig config)
        {
            await _motionConfigHandler.SaveConfiguration(config);

            return(await GetConfig());
        }
Example #13
0
 /// <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;
 }
Example #14
0
 /// <inheritdoc />
 public void ConfigureMotionDetection(MotionConfig config, Action onDetect)
 {
     _driver = new FrameDiffDriver(config, onDetect);
     this.EnableMotionDetection();
 }