Microsoft MediaPlayer Memory Leak winforms - c#

Hello when I play a video on a loop more and more memory is continually gobbled up. When I try to dispose of the MediaPlayer control only some of the memory is freed up.
My program needs to play hundreds / thousands of audios but this is results in my program getting larger and larger and slowing down.
Any ideas?
private void button10_Click(object sender, EventArgs e)
{
addTimer.Tick += addTimer_Tick;
addTimer.Interval = 1000;
addTimer.Start();
}
void addTimer_Tick(object sender, EventArgs e)
{
//axWindowsMediaPlayer1.URL = #"c:\temp\Catching.avi";
if (this.axWindowsMediaPlayer1.currentMedia != null)
{
this.axWindowsMediaPlayer1.Ctlcontrols.stop();
this.axWindowsMediaPlayer1.currentPlaylist.clear();
}
WMPLib.IWMPMedia currentMedia = this.axWindowsMediaPlayer1.newMedia(#"c:\temp\Catching.avi");
this.axWindowsMediaPlayer1.currentMedia = currentMedia;
}
private void button11_Click(object sender, EventArgs e)
{
this.Controls.RemoveByKey("wmp");
axWindowsMediaPlayer1.close();
axWindowsMediaPlayer1.Dispose();
GC.Collect();
}

Related

Invoke control - copy file blocks another thread

I have a problem with backgroundworker. I wrote program to copying files from local disc to network disk and I want to shows progressbar spinning in circles (not shows progress) when process is running.When I set backgroundworker into empty button everything works fine, but when I set backgroundworker into button which have function to coping files progressbar shows when copying process is finished. Why and how can I solved that? Below code.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
circularProgressBar1.BeginInvoke(new MethodInvoker(sd));
}
public void sd()
{
circularProgressBar1.Visible = true;
circularProgressBar1.Enabled = true;
circularProgressBar1.Style = ProgressBarStyle.Marquee;
}
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
circularProgressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
MessageBox.Show("End");
}
private void button1_Click_1(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void copy_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
List<string> pathList = new List<string>();
// for example add 1000 path
pathList.add("C:\test\2.jpg");
pathList.add("C:\test\3.jpg");
foreach(string in in pathList)
{
File.Copy(in,"D:\test2",true);
}
}
You need to put the File.Copy in backgroundWorker1_DoWork - this is where the background work is done.
You may activate the circularProgressBar before the call to backgroundWorker1.RunWorkerAsync and disable it in backgroundWorker1_RunWorkerCompleted.

Replay a BufferedWaveProvider

I use NAudio to record datas from microphone, then i need to playback audio without writing a wav file yet.
Play / Pause / Stop work well, but how can I set back the position to the beginning of bwp and play back from start the audio.
I can't write a wav file yet, because I need to play back the file, navigate throught it with a slider, then erase the end of buffer with new recorded datas, then save the modified file.
private void btn_Start_Click(object sender, EventArgs e)
{
if (sourceList.SelectedItems.Count == 0)
return;
int deviceNumber = sourceList.SelectedItems[0].Index;
wo = new WaveOutEvent();
wi = new WaveIn();
wi.DeviceNumber = deviceNumber;
wi.WaveFormat = new WaveFormat(44100, WaveIn.GetCapabilities(deviceNumber).Channels);
wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable);
bwp = new BufferedWaveProvider(wi.WaveFormat);
bwp.BufferDuration = new TimeSpan(1, 0, 0);
bwp.DiscardOnBufferOverflow = false;
wi.StartRecording();
}
private void wi_DataAvailable(object sender, WaveInEventArgs e)
{
bwp.AddSamples(e.Buffer, 0, e.BytesRecorded);
}
private void btn_Stop_Click(object sender, EventArgs e)
{
wi.StopRecording();
wo.Init(bwp);
}
private void btn_InitWaveOut_Click(object sender, EventArgs e)
{
wo.Play();
}
private void btn_StopWaveOut_Click(object sender, EventArgs e)
{
wo.Stop();
}
private void btn_PauseWaveOut_Click(object sender, EventArgs e)
{
wo.Pause();
}
The BufferedWaveProvider is not designed to support repositioning. If you want that you should make your own IWaveProvider derived class that holds onto all bytes received to allow repositioning. Obviously you'd want to be careful about how much memory you use up as audio data can grow quite large over time.

Using AFORGE to record the videos in c#

i've try the following way to record the video from the Webcam by 25 Frame-rate per sec for 10sec but when i get the out put video it is of 2sec and the frames are played to fast as compare to the video stream.
The code is as follows.
using System;
using System.Drawing;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Threading;
using AForge.Video.FFMPEG;
namespace AforgeTutorial
{
public partial class Form1 : Form
{
private FilterInfoCollection ListOfCams;
private VideoCaptureDevice SelectedCam; //From where we will take image
System.Timers.Timer tim;
Thread t;
bool isNewFrame = false;
VideoFileWriter writer;
public Form1()
{
InitializeComponent();
tim = new System.Timers.Timer(10000);
tim.Elapsed += new System.Timers.ElapsedEventHandler(tim_Elapsed);
t = new Thread(saveVideo);
}
void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (isRecord)
{
writer.Close();
isRecord = false;
}
}
private void Form1_Load(object sender, EventArgs e)
{
ListOfCams = new FilterInfoCollection(FilterCategory.VideoInputDevice);
if (ListOfCams.Count == 0)
return;
comboBox1.Items.Clear();
foreach (FilterInfo Cam in ListOfCams)
{
comboBox1.Items.Add(Cam.Name);
}
}
private void StopCamera()
{
SelectedCam.SignalToStop();
SelectedCam.Stop();
}
bool isRecord = false;
private void Start_Click(object sender, EventArgs e)
{
if (comboBox1.Text == string.Empty)
return;
SelectedCam = new VideoCaptureDevice(ListOfCams[comboBox1.SelectedIndex].MonikerString);
SelectedCam.NewFrame += new NewFrameEventHandler(SelectedCam_NewFrame);
SelectedCam.Start();
}
Bitmap image;
void SelectedCam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
image = (Bitmap)eventArgs.Frame.Clone();
isNewFrame = true;
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
StopCamera();
}
private void Stop_Click(object sender, EventArgs e)
{
StopCamera();
}
private void btnRecord_Click(object sender, EventArgs e)
{
tim.Start();
if (!isRecord)
{
writer = new VideoFileWriter();
writer.Open(#"C:/code-bude_test_video.mp4", 640, 480, 25, VideoCodec.MPEG4,10000);
}
isRecord = !isRecord;
if (isRecord)
t.Start();
}
void saveVideo()
{
while (isRecord)
{
if (isNewFrame)
{
writer.WriteVideoFrame(image);
isNewFrame = false;
}
}
}
}
}
You have multi-threading issues in your code. You can't write to shared variables like that and expect it to synchronize.
You have three threads: user interface, streaming and saving. (SelectedCam_NewFrame runs in the AForge streaming thread). Make a list of all variables that are accessed in at least two threads (isRecord, isNewFrame, etc) and add proper synchronization.
You can check this very good reference on threading in C#.
Note that even with synchronization, you may miss frames if your writer thread is busy while several images arrive. What you might want to do is collect the frames produced by the camera in a queue and consume that queue in the writer thread. Check the producer/consumer patterns.

C# checkedlistbox mouse enter/leave error

I want my checkedlistbox to expand to a certain size when the mouse enters and then go back to a its original size after mouse leaves. Below is the code is have. However, I receive an error when i have another program selected and my mouse goes over the checkedlistbox while the application is not active.
Any suggestions on how to fix?
private void checkedListBox1_MouseEnter(object sender, EventArgs e)
{
Search.ActiveForm.Height = 552;
checkedListBox1.Height = 130;
}
private void checkedListBox1_MouseLeave(object sender, EventArgs e)
{
Search.ActiveForm.Height = 452;
checkedListBox1.Height = 34;}
Error Code - Object Reference not set to an instance of an object.
Try this
private void checkedListBox1_MouseEnter(object sender, EventArgs e)
{
checkedListBox1.Size = new Size(Width,Height);
}
This of course would work so that no exception is thrown, but I hope it's also what you want:
private void checkedListBox1_MouseEnter(object sender, EventArgs e)
{
if(Search.ActiveForm == null) return;
Search.ActiveForm.Height = 552;
checkedListBox1.Height = 130;
}
private void checkedListBox1_MouseLeave(object sender, EventArgs e)
{
if(Search.ActiveForm == null) return;
Search.ActiveForm.Height = 452;
checkedListBox1.Height = 34;
}

WPF MediaElement how to resume playing from where it pause?

i have 2 buttons , Play and Pause , When i click pause , the music stops and when i click Play it starts the audio from beginning . I want to do it like when i press Play , it resume from where i have stopped.
private void PlayAudio()
{
McMediaElement.LoadedBehavior = MediaState.Manual;
McMediaElement.Source = new Uri("../../SingAlong/Food Fit For A King/old king cole.mp3", UriKind.RelativeOrAbsolute);
McMediaElement.Play();
}
private void button1_Click_1(object sender, RoutedEventArgs e)
{
PlayAudio();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
McMediaElement.Pause();
}
Your PlayAudio() method reloads the media file when you set the Source property. This causes your object to play the newly loaded media from the beginning when you call Play(). Instead of doing this in the event handler button1_Click_1, you should call the Play() method only:
private void button1_Click_1(object sender, RoutedEventArgs e)
{
McMediaElement.Play();
}
This worked for me..
private void button1_Click_1(object sender, RoutedEventArgs e)
{
McMediaElement.LoadedBehavior = MediaState.Pause;
}
private void button2_Click_1(object sender, RoutedEventArgs e)
{
McMediaElement.LoadedBehavior = MediaState.Play;
}

Categories

Resources