示例#1
0
        static async Task fragmp4(int seconds)
        {
            // This generates a "fragmented" MP4 which should be larger than an MP4
            // with a normal single MOOV atom trailer at the end of the file. See:
            // https://superuser.com/a/1530949/143047
            // 10 seconds of "-badmp4" is 34MB
            // 10 seconds of "-fragmp4" is 26MB regardless of the other options described in the link
            // 60 seconds (bad) is 219MB versus 208MB (frag) and again we lose 2 seconds
            // -g is keyframe rate, default is 250
            // -flush_packets 1 flushes the I/O stream after each packet, decreasing latency (apparently)
            // adding two seconds to the requested duration approximates the regular file size (10s = 33MB, 60s = 218MB)

            seconds += 2; // HACK! see above

            var cam      = GetConfiguredCamera();
            var pathname = ramdiskPath + "video.mp4";

            Directory.CreateDirectory(ramdiskPath);
            File.Delete(pathname);

            Console.WriteLine("Preparing pipeline...");
            cam.ConfigureCameraSettings();

            using (var ffmpeg = new ExternalProcessCaptureHandler(
                       new ExternalProcessCaptureHandlerOptions
            {
                Filename = "ffmpeg",
                Arguments = $"-framerate 24 -i - -b:v 2500k -c copy -movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov {pathname}",
                EchoOutput = true,
                DrainOutputDelayMs = 500,                                     // default
                TerminationSignals = new[] { Signum.SIGINT, Signum.SIGQUIT }, // not the supposedly-correct SIGINT+SIGINT but this produces some exit output
            }))
            {
                // quality arg-help says set bitrate zero to use quality for VBR
                var portCfg = new MMALPortConfig(MMALEncoding.H264, MMALEncoding.I420, quality: 10, bitrate: 0, timeout: null);
                using var encoder  = new MMALVideoEncoder();
                using var renderer = new MMALVideoRenderer();
                encoder.ConfigureOutputPort(portCfg, ffmpeg);
                cam.Camera.VideoPort.ConnectTo(encoder);
                cam.Camera.PreviewPort.ConnectTo(renderer);

                Console.WriteLine("Camera warmup...");
                await Task.Delay(2000);

                Console.WriteLine($"Capturing MP4: {pathname}");
                var timerToken = new CancellationTokenSource(TimeSpan.FromSeconds(seconds));
                await Task.WhenAll(new Task[] {
                    ffmpeg.ManageProcessLifecycleAsync(timerToken.Token),
                    cam.ProcessAsync(cam.Camera.VideoPort, timerToken.Token),
                }).ConfigureAwait(false);
            }

            // can't use the convenient fall-through using or MMALCamera.Cleanup
            // throws: Argument is invalid. Unable to destroy component
            cam.Cleanup();

            Console.WriteLine("Exiting.");
        }
示例#2
0
        static async Task badmp4(int seconds)
        {
            Console.WriteLine("\n\nWARNING:\nffmpeg can't create a valid MP4 when running as a child process.\nSee repository README. This code is here for reference only.\n\nPress any key...");
            Console.ReadKey(true);

            var cam      = GetConfiguredCamera();
            var pathname = ramdiskPath + "video.mp4";

            Directory.CreateDirectory(ramdiskPath);
            File.Delete(pathname);

            Console.WriteLine("Preparing pipeline...");
            cam.ConfigureCameraSettings();

            using (var ffmpeg = new ExternalProcessCaptureHandler(
                       new ExternalProcessCaptureHandlerOptions
            {
                Filename = "ffmpeg",
                Arguments = $"-framerate 24 -i - -b:v 2500k -c copy {pathname}",
                EchoOutput = true,
                DrainOutputDelayMs = 500,                                     // default
                TerminationSignals = new[] { Signum.SIGINT, Signum.SIGQUIT }, // not the supposedly-correct SIGINT+SIGINT but this produces some exit output
            }))
            {
                // quality arg-help says set bitrate zero to use quality for VBR
                var portCfg = new MMALPortConfig(MMALEncoding.H264, MMALEncoding.I420, quality: 10, bitrate: 0, timeout: null);
                using var encoder  = new MMALVideoEncoder();
                using var renderer = new MMALVideoRenderer();
                encoder.ConfigureOutputPort(portCfg, ffmpeg);
                cam.Camera.VideoPort.ConnectTo(encoder);
                cam.Camera.PreviewPort.ConnectTo(renderer);

                Console.WriteLine("Camera warmup...");
                await Task.Delay(2000);

                Console.WriteLine($"Capturing MP4: {pathname}");
                var timerToken = new CancellationTokenSource(TimeSpan.FromSeconds(seconds));
                await Task.WhenAll(new Task[] {
                    ffmpeg.ManageProcessLifecycleAsync(timerToken.Token),
                    cam.ProcessAsync(cam.Camera.VideoPort, timerToken.Token),
                }).ConfigureAwait(false);
            }

            // can't use the convenient fall-through using or MMALCamera.Cleanup
            // throws: Argument is invalid. Unable to destroy component
            cam.Cleanup();

            Console.WriteLine("Exiting. Remember, video.mp4 is not valid.");
        }
示例#3
0
        static async Task stream(int seconds)
        {
            var cam = GetConfiguredCamera();

            MMALCameraConfig.VideoResolution = new MMALSharp.Common.Utility.Resolution(640, 480);
            MMALCameraConfig.SensorMode      = MMALSensorMode.Mode7; // for some reason mode 6 has a pinkish tinge
            MMALCameraConfig.VideoFramerate  = new MMAL_RATIONAL_T(20, 1);

            Console.WriteLine("Preparing pipeline...");
            cam.ConfigureCameraSettings();
            // note cvlc requires real quotes even though we used apostrophes for the command line equivalent
            using (var vlc = new ExternalProcessCaptureHandler(
                       new ExternalProcessCaptureHandlerOptions
            {
                Filename = "cvlc",
                Arguments = @"stream:///dev/stdin --sout ""#transcode{vcodec=mjpg,vb=2500,fps=20,acodec=none}:standard{access=http{mime=multipart/x-mixed-replace;boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8554/}"" :demux=h264",
                EchoOutput = true,
                DrainOutputDelayMs = 500,     // default
                TerminationSignals = ExternalProcessCaptureHandlerOptions.signalsVLC
            }))
            {
                var portCfg = new MMALPortConfig(MMALEncoding.H264, MMALEncoding.I420, quality: 0, bitrate: MMALVideoEncoder.MaxBitrateMJPEG, timeout: null);

                using var encoder  = new MMALVideoEncoder();
                using var renderer = new MMALVideoRenderer();
                encoder.ConfigureOutputPort(portCfg, vlc);
                cam.Camera.VideoPort.ConnectTo(encoder);
                cam.Camera.PreviewPort.ConnectTo(renderer);

                Console.WriteLine("Camera warmup...");
                await Task.Delay(2000);

                Console.WriteLine($"Streaming MJPEG for {seconds} sec to:");
                Console.WriteLine($"http://{Environment.MachineName}.local:8554/");
                var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(seconds));
                await Task.WhenAll(new Task[] {
                    vlc.ManageProcessLifecycleAsync(timeout.Token),
                    cam.ProcessAsync(cam.Camera.VideoPort, timeout.Token),
                }).ConfigureAwait(false);
            }

            // can't use the convenient fall-through using or MMALCamera.Cleanup
            // throws: Argument is invalid. Unable to destroy component
            cam.Cleanup();

            Console.WriteLine("Exiting.");
        }