Reputation: 3276
Prelude:
I'm going to preface this with, I have been learning C# in my spare time at work, and that I have been staring at code for a solid two days trying to wrap my head around this problem. I am developing some software to be used with a visualiser that connects by USB to a standard Desktop PC, the software detects the capture device and loads frames into bitmap using a New Frame Event, this is then displayed in a 'picture box' as a live video stream. The problem as it sits is trying to encorporate the ability to record the stream and save to file, preferably a WMV or a compressed AVI.
What's been tried:
I have considered and looked into the following:
SharpAVI - cant seem to get this to compress or save the frames properly as it appears to mainly look at existing AVI files.
AForge.Video.VFW - AVI files can be created but are far too large to be used, due to restrictions on the user areas of the individuals who will be using this software.
AForge.Video.FFMPEG - Again due to considerations of those using this software I can't have unmanaged DLL's sat in the output folder with the Executable file, and unfortunately this particular DLL cant be compiled properly using Costura Fody.
AVIFile Library Wrapper (From Code Project) - Again can't seem to get this to compress a stream correctly from Bitmaps from the New Frame Events.
DirectShow - Appears to use C++ and unfortunately is beyond my skill level at this time.
The Relevant Code Snippets:
Current References:
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Resources;
using System.Drawing.Imaging;
using System.IO;
//Aforge Video DLL's
using AForge.Video;
using AForge.Video.VFW;
using AForge.Video.DirectShow;
//Aforge Image DLL's
using AForge.Imaging;
using AForge.Imaging.Formats;
using AForge.Imaging.Filters;
//AviLibrary
using AviFile;
Global Variables:
#region Global Variables
private FilterInfoCollection CaptureDevice; // list of available devices
private VideoCaptureDevice videoSource;
public System.Drawing.Image CapturedImage;
bool toggleMic = false;
bool toggleRec = false;
//aforge
AVIWriter aviWriter;
Bitmap image;
#endregion
Code for Displaying Stream
#region Displays the Stream
void videoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
picBoxStream.SizeMode = PictureBoxSizeMode.Zoom;
picBoxStream.Image = (Bitmap)eventArgs.Frame.Clone();// clones the bitmap
if (toggleRec == true)
{
image = (Bitmap)eventArgs.Frame.Clone();
aviWriter.AddFrame(image);
}
}
#endregion
Current Code for Recording Stream
#region Record Button
private void btnRecord_Click(object sender, EventArgs e)
{
if (toggleRec == false)
{
saveAVI = new SaveFileDialog();
saveAVI.Filter = "AVI Files (*.avi)|*.avi";
if (saveAVI.ShowDialog() == DialogResult.OK)
{
aviWriter = new AVIWriter();
aviWriter.Open(saveAVI.FileName, 1280, 720);
toggleRec = true;
Label lblRec = new Label();
}
}
else if (toggleRec == true)
{
aviWriter.Close();
toggleRec = false;
}
}
#endregion
I apoligise if the above code doesn't look quite right, I have been swapping, changing and recoding those three sections a lot in order to find a working combination. This means that it's rather untidy but I didn't see the point in cleaning it all up until I had the code working. That being said really any help that you can provide is greatfully recieved, even if it's a case of what I want to do just cannot be done.
Thank you in advance.
EDIT: 2019:
It's been awhile since I posted this and it still gets the odd bit of interest here and there. Back when I posted this I was teaching myself to code and I had this weird quirk that I didn't like using 3rd party libraries if I could avoid it, I wanted to do my own work, since then I've learnt a lot and one of those things is that the open source world is immense, impressive and kind. So if there is a 3rd party library that does what you want just use it, it'll save you time.
Upvotes: 1
Views: 3695
Reputation: 1
namespace ip_androidcam
{
public partial class Form1 : Form
{
MJPEGStream stream;
AVIWriter writer;
bool toggleRec = false;
public Form1()
{
InitializeComponent() ;
}
void stream_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
pictureBox1.Image = bmp;
try
{
if (toggleRec == true)
{
bmp = (Bitmap)eventArgs.Frame.Clone();
bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
writer.AddFrame(bmp);
}
}
catch (Exception e)
{
}
}
private void button1_Click(object sender, EventArgs e)
{
try
{
stream = new MJPEGStream(textBox1.Text);
stream.NewFrame +=stream_NewFrame;
stream.Start();
}
catch
{
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
if (stream.IsRunning == true)
{
stream.Stop();
}
}
catch
{
}
}
private void button3_Click(object sender, EventArgs e)
{
try
{
pictureBox1.Image = (Bitmap)pictureBox1.Image.Clone();
pictureBox1.Image.Save("D:\\Pictures\\pix-" + DateTime.Now.ToString("dd-MM-yyyy_hh-mm-ss" + ".jpeg" + ImageFormat.Jpeg));
}
catch (Exception)
{
MessageBox.Show("Capture Image First");
}
}
private void button4_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
pictureBox1.ImageLocation = ofd.FileName;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button5_Click(object sender, EventArgs e)
{
if (toggleRec == false)
{
SaveFileDialog saveAVI = new SaveFileDialog();
saveAVI.Filter = "AVI Files (*.avi)|*.avi";
if (saveAVI.ShowDialog() == DialogResult.OK)
{
writer = new AVIWriter("XVID");
writer.Open(saveAVI.FileName , 480, 640);
toggleRec = true;
Label lblRec =new Label();
}
}
}
private void button6_Click(object sender, EventArgs e)
{
try
{
writer.Close();
MessageBox.Show("video recorded successfully");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
Upvotes: 0
Reputation: 1
the same problem as i just solved :) here is my code how to use the AviFile library dll to make avi file :)
private void MakeAvi(List<Bitmap> maps)
{
AviManager mana = new AviManager("local.avi", false);
//false means do not show the diag of the Compression
//21 means the fps of the video
//maplist[0] cover of the video the maplist is the val you should insert
VideoStream avistream = mana.AddVideoStream(false, 21, maplist[0]);
for (int i = 1; i < maps.Count; i++)
{
avistream.AddFrame(maplist[i]);
}
mana.Close();
MessageBox.Show("AddOk");
}
Upvotes: 0