Reputation: 1666
I'm trying to create Video To Gif converter using WPF MediaKit (MediaDetector class) library to extract video frame by time. I wanna to run StartButton_OnClick
method asynchronously using async/await.
I'm using the following code:
private async void StartButton_OnClick(object sender, RoutedEventArgs e)
{
if (_openFile != null &&
!String.IsNullOrEmpty(SaveToBox.Text))
{
await new LocalVideoConverter(_openFile.FileName, _from*1000, _to*1000,
SaveToBox.Text, InterpolationMode.Low, new System.Drawing.Size(320, 240))
.StartConverting();
}
else
MessageBox.Show("Choose video file and enter path for Gif");
}
StartConverting()
method:
public override Task StartConverting()
{
return Task.Run(() =>
{
Encoder.Start(GifPath);
Encoder.SetDelay(Ival);
Encoder.SetRepeat(0);
for (double i = From; i < To; i += Ival)
{
var frame = GetFrame(TimeSpan.FromMilliseconds(i));
frame = ResizeImage(frame);
AddFrame(frame);
}
Encoder.Finish();
});
}
GetFrame(TimeSpan ts)
method:
protected override Image GetFrame(TimeSpan ts)
{
var bitmapSource = _mediaDetector.GetImage(ts);
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapSource));
enc.Save(outStream);
return new Bitmap(outStream);
}
}
Also MediaDetector class has public unsafe BitmapSource GetImage(TimeSpan position)
method.
When I click on the StartButton, I get an System.InvalidOperationException with message "The calling thread cannot access this object because a different thread owns it"
in this line of GetImage()
method (look this)
if (string.IsNullOrEmpty(m_filename))
I the beginner in multi-threaded programming. How I can to solve this problem?
P.S. Sorry for my not good English:-)
Upvotes: 3
Views: 291
Reputation:
You might be able to get around async
/await
by using BeginInvoke
. Since it's WPF, I guess you could write
private void StartButton_OnClick(object sender, RoutedEventArgs e) {
if (_openFile != null && !String.IsNullOrEmpty(SaveToBox.Text)) {
this.Dispatcher.BeginInvoke(new Action(delegate() {
LocalVideoConverter lvc = new LocalVideoConverter(_openFile.FileName, _from*1000, _to*1000,
SaveToBox.Text, InterpolationMode.Low, new System.Drawing.Size(320, 240));
lvc.StartConverting();
}));
} else
MessageBox.Show("Choose video file and enter path for Gif");
}
BackgroundWorker
might be possible as well, although I'd not recommend it.
Upvotes: 3