Why it doesn't pick up any cameras? - c#

I'm in making barcode scanner but "VideoCaptureDevice can't pick up any objects" ?
I'm using AForge video and ZXing in visual studio 2019 C#
I want it to be able to scan barcodes from my laptop webcam.
I tried running it with the problem but in my combobox where are supposed to be cameras available for use but they are none. I even tried activating the webcam before opening up the program.
code:
FilterInfoCollection FilterInfoCollection;
VideoCaptureDevice VideoCaptureDevice;
private void Form1_Load(object sender, EventArgs e)
{
FilterInfoCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo device in FilterInfoCollection)
comboBox1.Items.Add(device.Name);
comboBox1.SelectedIndex = 0;
}
private void button1_Click(object sender, EventArgs e)
{
VideoCaptureDevice = new VideoCaptureDevice(FilterInfoCollection[comboBox1.SelectedIndex].MonikerString);
VideoCaptureDevice.NewFrame += VideoCaptureDevice_NewFrame;
VideoCaptureDevice.Start();
}
private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap bitmap = (Bitmap)eventArgs.Frame.Clone();
BarcodeReader reader = new BarcodeReader();
var result = reader.Decode(bitmap);
if (result != null)
{
textBox1.Invoke(new MethodInvoker(delegate ()
{
textBox1.Text = result.ToString();
}));
}
pictureBox1.Image = bitmap;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (VideoCaptureDevice != null)
{
if (VideoCaptureDevice.IsRunning)
VideoCaptureDevice.Stop();
}
}
}
}

Related

AForge experience and file manipulation

Morning all,
Does anyone on here have experience with using AForge and Video or webcam apps?
There is a .cs file called VideoCaptureDeviceForm that is part of AForge.DirectShow which provides a way of selecting a local video device i.e webcam.
I want to be able to automatically detect and start the webcam on my computer but a dialogbox pops up asking to select a webcam. I need a way to either bypass this in someway or automatically press the OK button.
Dialogbox
I have tried using SendKeys.Send("{ENTER}") within the open dialogbox button method i.e Start camera but I get errors.
Within VideoCaptureDeviceForm.cs, there is a method called okButton_Click and the next idea is to manipulate this to do what I want the app to do.
Unfortunately I don't have the experience to figure this out. Can anyone advise on how to do this or what I should do next? Thank you.
VideoCaptureDeviceForm.cs is below:
using System;
using System.Threading;
using System.Windows.Input;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using Accord.Video.FFMPEG;
using AForge.Video.VFW;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private FilterInfoCollection VideoCaptureDevices;
private VideoCaptureDevice FinalVideo = null;
private VideoCaptureDeviceForm captureDevice;
private Bitmap video;
private VideoFileWriter FileWriter = new VideoFileWriter();
private SaveFileDialog saveAvi;
public Form1()
{
InitializeComponent();
Start_Vid();
}
private void Form1_Load(object sender, EventArgs e)
{
VideoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
captureDevice = new VideoCaptureDeviceForm();
}
void FinalVideo_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
if (Stop.Text == "Stop Record")
{
video = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
//AVIwriter.Quality = 0;
FileWriter.WriteVideoFrame(video);
//AVIwriter.AddFrame(video);
}
else
{
video = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
}
}
private void Stop_Vid()
{
if (Stop.Text == "Stop Record")
{
Stop.Text = "Stop";
if (FinalVideo == null)
{ return; }
if (FinalVideo.IsRunning)
{
//this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
pictureBox1.Image = null;
}
}
else
{
this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
pictureBox1.Image = null;
}
}
private void butstop_Click(object sender, EventArgs e)
{
if (Stop.Text == "Stop Record")
{
Stop.Text = "Stop";
if (FinalVideo == null)
{ return; }
if (FinalVideo.IsRunning)
{
//this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
pictureBox1.Image = null;
}
}
else
{
this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
pictureBox1.Image = null;
}
}
private void button3_Click(object sender, EventArgs e)
{
pictureBox1.Image.Save("IMG" + DateTime.Now.ToString("hhmmss") + ".jpg");
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (FinalVideo == null)
{ return; }
if (FinalVideo.IsRunning)
{
this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
}
}
private void Save_Click(object sender, EventArgs e)
{
saveAvi = new SaveFileDialog();
saveAvi.Filter = "Avi Files (*.avi)|*.avi";
saveAvi.FileName = "New Vid1";
if (saveAvi.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
int h = captureDevice.VideoDevice.VideoResolution.FrameSize.Height;
int w = captureDevice.VideoDevice.VideoResolution.FrameSize.Width;
FileWriter.Open(saveAvi.FileName, w, h, 25, VideoCodec.Default, 5000000);
FileWriter.WriteVideoFrame(video);
//AVIwriter.Open(saveAvi.FileName, w, h);
Stop.Text = "Stop Record";
//FinalVideo = captureDevice.VideoDevice;
//FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
//FinalVideo.Start();
}
}
//##############################################//
// Method not working //
//##############################################//
private void Start_Vid()
{
SendKeys.Send("{ENTER}");
if (captureDevice.ShowDialog(this) == DialogResult.OK)
{
VideoCaptureDevice videoSource = captureDevice.VideoDevice;
FinalVideo = captureDevice.VideoDevice;
FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
FinalVideo.Start();
}
}
//##############################################//
// Method working //
//##############################################//
private void Start_Click(object sender, EventArgs e)
{
SendKeys.Send("{ENTER}");
if (captureDevice.ShowDialog(this) == DialogResult.OK)
{
VideoCaptureDevice videoSource = captureDevice.VideoDevice;
FinalVideo = captureDevice.VideoDevice;
FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
FinalVideo.Start();
}
}
private void Close_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
1) First, you need to find all webcam device is attached with you system
public FilterInfoCollection LoaclWebCamsCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
2) Then which webcam you want to use select "MonikerString" of that webcam
VideoCaptureDevice videoSource = new VideoCaptureDevice(LoaclWebCamsCollection["Select webcam you want to user"].MonikerString);
OR
VideoCaptureDevice videoSource = new VideoCaptureDevice(LoaclWebCamsCollection[0].MonikerString);
private void Start_Vid()
{
FinalVideo = new
VideoCaptureDevice(LoaclWebCamsCollection[0].MonikerString);
FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
FinalVideo.Start();
}

automatic speech detection and recording

I am new to coding in c#. I am building an application to detect the speech and automatically record it. All the information available is based on windows speech recognition engine but my requirement is, the program should detect the speech and record it.
after recording that file is used for processing using hidden markov model(HMM).
namespace Application
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button_1_Click(object sender, EventArgs e)
{
List<NAudio.Wave.WaveInCapabilities> sources = new List<NAudio.Wave.WaveInCapabilities>();
for (int i = 0; i < NAudio.Wave.WaveIn.DeviceCount; i++)
{
sources.Add(NAudio.Wave.WaveIn.GetCapabilities(i));
}
sourceList.Items.Clear();
foreach (var source in sources)
{
ListViewItem item = new ListViewItem(source.ProductName);
item.SubItems.Add(new ListViewItem.ListViewSubItem(item, source.Channels.ToString()));
sourceList.Items.Add(item);
}
}
NAudio.Wave.WaveIn sourceStream = null;
NAudio.Wave.DirectSoundOut waveOut = null;
NAudio.Wave.WaveFileWriter waveWriter = null;
private void button_2_click(object sender, MouseEventArgs e)
{
if (sourceList.SelectedItems.Count == 0) return;
int deviceNumber = sourceList.SelectedItems[0].Index;
sourceStream = new NAudio.Wave.WaveIn();
sourceStream.DeviceNumber = deviceNumber;
sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(16000, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels);
sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable);
waveWriter = new NAudio.Wave.WaveFileWriter("test.wav", sourceStream.WaveFormat);
sourceStream.StartRecording();
}
private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
{
if (waveWriter == null) return;
waveWriter.WriteData(e.Buffer, 0, e.BytesRecorded);
waveWriter.Flush();
}
private void button_3_click(object sender, EventArgs e)
{
if (waveOut != null)
{
waveOut.Stop();
waveOut.Dispose();
waveOut = null;
}
if (sourceStream != null)
{
sourceStream.StopRecording();
sourceStream.Dispose();
sourceStream = null;
}
if (waveWriter != null)
{
waveWriter.Dispose();
waveWriter = null;
}
speechprocessing.Model_test.speech();
}
private void button4_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
this suits my requirement but it has two button to initiate and terminate the recording process which is not under my requirement..
the program should be running and when the speech is detected it must be recorded and further processed. the words which it should detect is also not too much only a few set of words for which we have made the models using hidden markov model..
so please help me out from this problem.

AForge Convertation and problems with HD

First of all, I can't play and record HD video(1920x1080), when I change my camera resolution to 1920x1080 program show and record black background, if camera resolution is 720x576 it works without problems. I'm sure that the problem is in my solution because, when I use DesktopVideo(Software which is included with Blackmagic Decklink Studio 2) it shows HD video from camera.
Second, How do I convert video with AForge? like changing resolution and framerate, I can change codecs and bitrate, but when I change Resolution and FrameRate in "FileWriter.Open"
command I get Error Resolution and FrameRate must be the same as Bitmap I'm capturing from camera.
If anybody knows how to solve these problems please share information, thanks!
Here is the code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Video.FFMPEG;
using AForge.Video.VFW;
namespace WindowsFormsApplication12
{
public partial class Form1 : Form
{
private FilterInfoCollection VideoCaptureDevices;
private VideoCaptureDevice FinalVideo = null;
private VideoCaptureDeviceForm captureDevice;
private Bitmap video;
//private AVIWriter AVIwriter = new AVIWriter();
private VideoFileWriter FileWriter = new VideoFileWriter();
private SaveFileDialog saveAvi;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
VideoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
captureDevice = new VideoCaptureDeviceForm();
}
private void button1_Click(object sender, EventArgs e)
{
/////capture device list
if (captureDevice.ShowDialog(this) == DialogResult.OK)
{
VideoCaptureDevice videoSource = captureDevice.VideoDevice;
FinalVideo = captureDevice.VideoDevice;
FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
FinalVideo.Start();
}
}
void FinalVideo_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
if (butStop.Text == "Stop Record")
{
video = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
//AVIwriter.Quality = 0;
FileWriter.WriteVideoFrame(video);
//AVIwriter.AddFrame(video);
}
else
{
video = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
}
}
private void button2_Click(object sender, EventArgs e)
{
////record button
saveAvi = new SaveFileDialog();
saveAvi.Filter = "Avi Files (*.avi)|*.avi";
if (saveAvi.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
int h = captureDevice.VideoDevice.VideoResolution.FrameSize.Height;
int w = captureDevice.VideoDevice.VideoResolution.FrameSize.Width;
FileWriter.Open(saveAvi.FileName, w, h,25,VideoCodec.Default,5000000);
FileWriter.WriteVideoFrame(video);
//AVIwriter.Open(saveAvi.FileName, w, h);
butStop.Text = "Stop Record";
//FinalVideo = captureDevice.VideoDevice;
//FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
//FinalVideo.Start();
}
}
private void butStop_Click(object sender, EventArgs e)
{
if (butStop.Text == "Stop Record")
{
butStop.Text = "Stop";
if (FinalVideo == null)
{ return; }
if (FinalVideo.IsRunning)
{
//this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
pictureBox1.Image = null;
}
}
else
{
this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
pictureBox1.Image = null;
}
}
private void button3_Click(object sender, EventArgs e)
{
pictureBox1.Image.Save("IMG" + DateTime.Now.ToString("hhmmss") + ".jpg");
}
private void button4_Click(object sender, EventArgs e)
{
this.Close();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (FinalVideo == null)
{ return; }
if (FinalVideo.IsRunning)
{
this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
}
}
}
}
The provided code simply captures and saves in the format currently active/selected for the capture device. In general, resolution change is an "expensive" operation is not available as a complimentary operation.
You want to change resolution right on capture device by switching it to more appropriate format, then capture in this resolution and have all further data manipulation in correct resolution. Available resolutions and options might be hardware specific there.
If/when no suitable capture resolution option is available, you typically resample the video to new resolution. Even though Windows API has suitable functionality, in your particular case you are interested to have this integrated with AForge library and you need to check its documentation to find out whether it provides a respective wrapper and whether it can be integrated into capture process overall (or, you need to write this code yourself to handle scaling).

Can I use a combo box to change the voice of my speech synthesizer to one of the system TTS voices?

I would like to have a combo box on my form which allows the user to select the voice which they would like to use. How can I implement such a feature?
Currently, my form consists of four buttons and a combo box. The code behind the buttons and the synthesizer is as follows:
private void button1_Click(object sender, EventArgs e)
{
reader.Dispose();
if (Basic_Word_Processor.Instance.richTextBoxPrintCtrl1.Text != "")
{
reader = new SpeechSynthesizer();
reader.SpeakAsync(Basic_Word_Processor.Instance.richTextBoxPrintCtrl1.Text)
button2.Enabled = true;
button4.Enabled = true;
reader.SpeakCompleted += new EventHandler<SpeakCompletedEventArgs>(reader_SpeakCompleted);
}
else
{
MessageBox.Show("Please insert text before launching Text to Speech.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
void reader_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
{
button2.Enabled = false;
button3.Enabled = false;
button4.Enabled = false;
}
private void button2_Click(object sender, EventArgs e)
{
if (reader != null)
{
if (reader.State == SynthesizerState.Speaking)
{
reader.Pause();
button3.Enabled = true;
}
private void button3_Click(object sender, EventArgs e)
{
if (reader != null)
{
if (reader.State == SynthesizerState.Paused)
{
reader.Resume();
}
button3.Enabled = false;
}
}
private void button4_Click(object sender, EventArgs e)
{
if (reader != null)
{
reader.Dispose();
button2.Enabled = false;
button3.Enabled = false;
button4.Enabled = false;
}
I would like to populate a combo box with a list of currently installed voices, which, when the user clicks one, reads the text from richTextBoxPrintCtrl1 in the selected voice. Currently, the synthesizer works, but I would like to add this feature to my Text to Speech feature.
Thanks.
This code should do roughly what you are after (if you are still interested:). You will need to drag on a new comboxbox called 'comboBox1' onto your form
private SpeechSynthesizer reader = new SpeechSynthesizer();
private void PopulateInstalledVoices()
{
foreach (InstalledVoice voice in
reader.GetInstalledVoices(new CultureInfo("en-US")))
{
VoiceInfo info = voice.VoiceInfo;
comboBox1.Items.Add(info.Name);
}
}
private void Form1_Load(object sender, EventArgs e)
{
PopulateInstalledVoices();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var voice = comboBox1.SelectedItem as String;
if (voice != null)
{
reader.SelectVoice(voice);
}
}
private void button1_Click(object sender, EventArgs e)
{
reader.SpeakAsync("this is a test message");
}

Hearing the Incoming audio from mic

i just want to hear what i say to microphone using NAudio and this is my code so far but the problem is i can't hear anything. any help would be appreciated.
public partial class frmMain : Form
{
private WaveIn waveIn; // Gets an audio from microphone
private WaveOut waveOut; // Sends audio to speaker
private BufferedWaveProvider waveProvider; // Gets an audio from stream
public frmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
waveOut = new WaveOut();
waveIn = new WaveIn();
waveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
waveOut.Init(waveProvider);
waveIn.DataAvailable += waveIn_DataAvailable;
waveOut.Play();
}
private void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
waveProvider.Read(e.Buffer, 0, e.BytesRecorded);
}
private void btnStop_Click(object sender, EventArgs e)
{
waveIn.StopRecording();
waveIn.Dispose();
}
private void btnStart_Click(object sender, EventArgs e)
{
waveIn.StartRecording();
}
}
i will use this scenario in network programming on which i send the data from microphone to the socket then on the client side the BufferedWaveProvider will read the data then send it to the speaker. Please put also some comment if what is the better way to do it.
TIA
Sample code as promised. Code is for a form with two buttons (named StartBtn and StopBtn).
public partial class Form1 : Form
{
private WaveIn waveIn = null;
private BufferedWaveProvider waveProvider = null;
private WaveOut waveOut = null;
public Form1()
{
InitializeComponent();
}
private void StartBtn_Click(object sender, EventArgs e)
{
if (waveIn != null)
return;
// create wave input from mic
waveIn = new WaveIn(this.Handle);
waveIn.BufferMilliseconds = 25;
waveIn.RecordingStopped += waveIn_RecordingStopped;
waveIn.DataAvailable += waveIn_DataAvailable;
// create wave provider
waveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
// create wave output to speakers
waveOut = new WaveOut();
waveOut.DesiredLatency = 100;
waveOut.Init(waveProvider);
waveOut.PlaybackStopped += wavePlayer_PlaybackStopped;
// start recording and playback
waveIn.StartRecording();
waveOut.Play();
}
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
// add received data to waveProvider buffer
if (waveProvider != null)
waveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
}
private void StopBtn_Click(object sender, EventArgs e)
{
if (waveIn != null)
waveIn.StopRecording();
}
void waveIn_RecordingStopped(object sender, StoppedEventArgs e)
{
// stop playback
if (waveOut != null)
waveOut.Stop();
// dispose of wave input
if (waveIn != null)
{
waveIn.Dispose();
waveIn = null;
}
// drop wave provider
waveProvider = null;
}
void wavePlayer_PlaybackStopped(object sender, StoppedEventArgs e)
{
// stop recording
if (waveIn != null)
waveIn.StopRecording();
// dispose of wave output
if (waveOut != null)
{
waveOut.Dispose();
waveOut = null;
}
}
}
Note especially the waveIn.BufferMilliseconds and waveOut.DesiredLatency settings to reduce the lag times.
For compressing the data for network transmission I suggest using a different library to process the data blocks. You might need to tune the BufferMilliseconds value to reduce the overheads and get better compression ratios.
The Opus Codec looks like a reasonable option, with Opus.NET for C#.

Categories