nager / Nager.VideoStream

Get images from a network camera stream or webcam
MIT License
54 stars 10 forks source link

The process of the FFmpeg is not closed automatically #4

Closed yeshivsher closed 3 years ago

yeshivsher commented 3 years ago

The process of the FFmpeg is not closed automatically It seems like it continues running. how can I use it without the exe in case of docker or linux

tinohager commented 3 years ago

I think they need to get more into the ffmpeg project themselves. This project is not a one stop shop for ffmpeg support.

pplusawork commented 3 years ago

@yeshivsher It looks like this just wasn't explicitly shown in the sample.

Whenever you're done getting images, you need to trigger the Cancellation Token and it will stop the process and run any cleanup.

For example, the below sample will get 5 images, spaced about 200ms apart (i.e. 1 second at 5fps), then gracefully stop everything, including the ffmpeg process. I'm sure this could be done better for your use case, but it should cover this and issue #3

const Int32 MaxImages = 5;
const Int32 ImageFrequencyMs = 200;

VideoStreamClient Client;
CancellationTokenSource StreamCancellationSource = new CancellationTokenSource();
Stopwatch TimeSinceLastRead = new Stopwatch();
Int32 TotalImages = 0;

void Main()
{
        // Define the source
    var StreamInput = new StreamInputSource("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov");

    // Set up the client
    Client = new VideoStreamClient();

    // Bind the handler
    Client.NewImageReceived += NewImageReceived;

    // Start the stream reader
    var VideoStreamTask = Client.StartFrameReaderAsync(StreamInput, OutputImageFormat.Bmp, StreamCancellationSource.Token);

    // Do anything else you need to do.

    // Wait for the video client to finish shutting down.
    VideoStreamTask.Wait();
}

void NewImageReceived(Byte[] imageData)
{
    // This throttles how often an image is grabbed
    if(TimeSinceLastRead.IsRunning) {
        if(TimeSinceLastRead.ElapsedMilliseconds >= ImageFrequencyMs) {
            TimeSinceLastRead.Restart();
        }
        else {
            return;
        }
    }
    else {
        TimeSinceLastRead.Start();
    }

    // Do whatever you want with imageData bytes
    // E.g. I'm using LinqPad, so this will dump
    // the image to LinqPad's output window
    using (var stream = new MemoryStream(imageData))
    {
        new Bitmap(stream).Dump();
    }

    // This is the gate to stop after 5 images.
    TotalImages++;
    if (TotalImages == MaxImages)
    {
                // Unbind the handler
        Client.NewImageReceived -= NewImageReceived;
                // Trigger the stream to stop
        StreamCancellationSource.Cancel();
    }
}