Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is this library good for Real-time IP Camera Video capturing and recording? #21

Open
shujaatak opened this issue Jun 22, 2020 · 1 comment

Comments

@shujaatak
Copy link

shujaatak commented Jun 22, 2020

First of all, Thank you so much for this awesome project!
Secondly can you please mention if this library is good for real-time IP Camera Video capturing and recording? If yes, can you please include an example project in samples showing how to use this repository to record a live stream? I mean a live video is usually an endless video so how we can configure this library to save the video continuously or after an interval?

A sample rtsp stream address:
rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov

Best regards

@Raveler
Copy link
Owner

Raveler commented Jun 22, 2020

Hey,

This is actually the use case I developed this library for, so I can confirm this works.

We were using this library to receive video data frame by frame and record it to a h264-encoded file. In our case, the video data came from a render engine, but it can come from a video, as long as the video data is in a format ffmpeg can understand.

Here's the code we used to write frame by frame from whatever source. EncodeFrame is called with a raw, unencoded RGBA byte array that whenever a frame arrives from the source.

// AniHub.LipSync.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"

#include <string>
#include <iostream>
#include <stdio.h>
#include <io.h>
#include <filesystem>
#include <fstream>
#include <sstream>

using namespace std;
using namespace ffmpegcpp;


struct Context
{
  VideoCodec* codec = nullptr;
  Muxer* muxer = nullptr;
  RawVideoDataSource* source = nullptr;
  VideoFrameSink* encoder = nullptr;
};

void CleanUp(Context* ctx)
{
  if (ctx->muxer != nullptr) delete ctx->muxer;

  if (ctx->source != nullptr) delete ctx->source;
  if (ctx->encoder != nullptr) delete ctx->encoder;

  delete ctx;
}

void* StartExport(const char* outputFileName, int width, int height, int framesPerSecond)
{
  Context* ctx = new Context();
  try
  {
    // create the output muxer
    ctx->muxer = new Muxer(outputFileName);

    // create the codec based on the output extension
    H264NVEncCodec* h264codec = new H264NVEncCodec();
    h264codec->SetPreset("losslesshp");
    ctx->codec = h264codec;

    // create the encoder that will link the source and muxer together
    ctx->encoder = new VideoEncoder(ctx->codec, ctx->muxer);

    // if we need to extract alpha, we need to send the A-channel to the filter
    // and we let the filter take care of the conversion to the final pixel format.
    ctx->source = new RawVideoDataSource(width, height, AV_PIX_FMT_BGRA, AV_PIX_FMT_RGBA, framesPerSecond, ctx->encoder);

    return ctx;
  }
  catch (FFmpegException e)
  {
    CleanUp(ctx);
    return nullptr;
  }
}

int EncodeFrame(void* handle, void* frameData, int bytesPerRow)
{
  Context* ctx = (Context*)handle;

  // push to the source
  try
  {
    ctx->source->WriteFrame(frameData, bytesPerRow);
    return 0;
  }
  catch (FFmpegException e)
  {
    return -1;
  }
}

void Cancel(void* handle)
{
  Context* ctx = (Context*)handle;
  CleanUp(ctx);
}

int Close(void* handle)
{
  Context* ctx = (Context*)handle;
  try
  {
    ctx->muxer->Close();
    CleanUp(ctx);
    return 0;
  }
  catch (FFmpegException e)
  {
    return -1;
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants