how to capture a video frame from a video file - c#

any one can help me with a c# code to grab frames from a video file,
I am working on a live streaming server on (Asp.Net & c#)..
so when a user uploads his files after live streaming, at the point I have to capture a video frame, so that it can be listed
in the format of a you-tube video list...
thanks

Take a look at AForge.NET - it is a mature set of libraries for processing images and video.

You should be try this it works nice:
private Capture capture = null;
private void btnStart_Click(object sender, System.EventArgs e)
{
try
{
if ( capture == null )
throw new ApplicationException( "Please select a video and/or audio device." );
if ( !capture.Cued )
capture.Filename = txtFilename.Text;
capture.Start();
btnCue.Enabled = false;
btnStart.Enabled = false;
}
catch (Exception ex)
{
MessageBox.Show( ex.Message + "\n\n" + ex.ToString() );
}
}

Related

CrossMedia Plugin Only Opens Picture mode instead of Video

I have a button in my xamarin application where I want to be able to record a video. The only problem is that when I click on it, it takes the camera instead of video (see photo).
This is the method I am currently using.
private async Task TakeVideoAndSave()
{
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakeVideoSupported)
{
await DisplayAlert("No Camera", "No camera avaialble.", "OK");
return;
}
var createdInAppOn = _declaration.CreatedInAppOn.Value.ToString("s").Replace(":", string.Empty);
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var videoPath = Path.Combine(path, createdInAppOn + ".mp4");
var file = await CrossMedia.Current.TakeVideoAsync(new Plugin.Media.Abstractions.StoreVideoOptions
{
Name = createdInAppOn + ".mp4",
Quality = VideoQuality.Low,
});
if (file == null)
return;
await DisplayAlert("Video Recorded", "Location: " + file.Path, "OK");
file.Dispose();
}
How do I manage to get the video camera from android instead of the photo camera?
Thanks in advance
The MediaPicker class lets a user pick or take a photo or video on the device.
You can use CaptureVideoAsync which Opens the camera to take a video.
Here is the API documentation of MediaPicker:https://learn.microsoft.com/en-us/dotnet/api/xamarin.essentials.mediapicker?view=xamarin-essentials

Closed Captions resolving error System.UnauthorizedAccessException

So, I'm trying to implement closed captions support to my UWP video player (using MediaElement), I've followed this example to do so.
I'm getting an error when resolving it called "Error resolving track due to error NetworkError System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
I do it like this: I open a file using filepicker and then get the SRT of the video that was picked. After that I show it. Unfortunately, nothing appears.
Here is my OpenButton function:
private async void BtnOpenMedia_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.ViewMode = PickerViewMode.Thumbnail;
filePicker.SuggestedStartLocation = PickerLocationId.VideosLibrary;
filePicker.FileTypeFilter.Add(".mp4");
filePicker.FileTypeFilter.Add(".wmv");
filePicker.FileTypeFilter.Add(".mpg");
filePicker.FileTypeFilter.Add(".mpeg");
filePicker.FileTypeFilter.Add("*");
StorageFile storageFile = await filePicker.PickSingleFileAsync();
if (storageFile != null && mElement != null)
{
string strSource = Path.GetDirectoryName(storageFile.Path) + #"\" + storageFile.DisplayName + ".srt";
var mediaSource = MediaSource.CreateFromStorageFile(storageFile);
var ttsStream = TimedTextSource.CreateFromUri(new Uri(strSource));
ttsStream.Resolved += TtsStream_Resolved;
mediaSource.ExternalTimedTextSources.Add(ttsStream);
var mediaPlayback = new MediaPlaybackItem(mediaSource);
mElement.SetPlaybackSource(mediaPlayback);
}
}
Here is my resolve function:
private void TtsStream_Resolved(TimedTextSource sender, TimedTextSourceResolveResultEventArgs args)
{
if (args.Error != null)
{
var ignoreAwaitWarning = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
var msg = new MessageDialog("Error resolving track " + " due to error " + args.Error.ErrorCode + " " + args.Error.ExtendedError);
await msg.ShowAsync();
});
return;
}
}
P.S: Also, I don't know if this is duplicated or not, that's why I'm adding it in this but I've done my research and found nothing. How to preview frames of MediaElement ? For example like YouTube you can preview thumbnails in the slider, I don't know how to achieve that, thanks!
You used a FileOpenPicker to select the Video file, but use a Path to access the .srt file. The .srt file is also in the Video file's folder. I reproduced your problem here:
The error message is clear, you have no access to this file, this file indicates the .srt file, so the problem is where did you store this .srt file. Just have a test, seems TimedTextSource.CreateFromUri(Uri) | createFromUri(Uri) method does not support to access the files in the local machine, but you can use TimedTextSource.CreateFromStream(IRandomAccessStream) | createFromStream(IRandomAccessStream) method for example like this:
if (storageFile != null && mElement != null)
{
//string strSource = Path.GetDirectoryName(storageFile.Path) + #"\" + storageFile.DisplayName + ".srt";
var fileSource = await KnownFolders.VideosLibrary.GetFileAsync(storageFile.DisplayName + ".srt");
IRandomAccessStream strSource = await fileSource.OpenReadAsync();
var mediaSource = MediaSource.CreateFromStorageFile(storageFile);
//var ttsStream = TimedTextSource.CreateFromUri(new Uri(strSource));
var ttsStream = TimedTextSource.CreateFromStream(strSource);
ttsStream.Resolved += TtsStream_Resolved;
mediaSource.ExternalTimedTextSources.Add(ttsStream);
var mediaPlayback = new MediaPlaybackItem(mediaSource);
mediaPlayback.TimedMetadataTracksChanged += (sender1, args) =>
{
mediaPlayback.TimedMetadataTracks.SetPresentationMode(0, TimedMetadataTrackPresentationMode.PlatformPresented);
};
mElement.SetPlaybackSource(mediaPlayback);
}
When using this code, the .srt file and video file should in the Video lib and the capability "Videos Library" should be enabled in the manifest.
In an UWP app, you can only access the files in known folder like picture lib, music lib and video lib and doc lib or local folder of your app, if your video is not in these folders, you should also handle the exception when access is denied in this scenario.
How to preview frames of MediaElement ? For example like YouTube you can preview thumbnails in the slider.
For this question, I can't find any ready-made sample for you, but I think the scenario 4 of official Media editing sample can be a direction, it shows a overlay layer on MediaElement, maybe you can set the "baseVideoFile" and the "overlayVideoFile" with the same source. The problem is when and where to show this overlay layer, it's related to the transport control of MediaElement. This is for now just a mind, you can have a try.

How can i save the image from the webBrowser control?

In the top of form1 i did
WebBrowser webbrowser1;
Then in the constructor
webbrowser1 = new WebBrowser(); webbrowser1.Navigate("http://www.ims.gov.il/IMS/tazpiot/RainRadar.htm");
webbrowser1.DocumentCompleted += webbrowser1_DocumentCompleted;
Then in the DocumentCompleted event
void webbrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.AbsoluteUri != webbrowser1.Url.AbsoluteUri)
{
return;
}
IHTMLDocument2 doc = (IHTMLDocument2)webbrowser1.Document.DomDocument;
IHTMLControlRange imgRange = (IHTMLControlRange)((HTMLBody)doc.body).createControlRange();
foreach (IHTMLImgElement img in doc.images)
{
imgRange.add((IHTMLControlElement)img);
imgRange.execCommand("Copy", false, null);
using (Bitmap bmp = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap))
{
bmp.Save(#"E:\newimages\" + img.nameProp);
}
}
}
I'm getting on the hard disk 20 images saved.
But not the one i needed. The one i need to save from this page in the webBrowser is the image in this link: http://www.ims.gov.il/Ims/Pages/RadarImage.aspx?Row=9&TotalImages=10&LangID=1&Location=
The radar it self image. I can make save as...
And i can use like i'm doing today WebClient...
But WebClient is not working all the time. So i'm trying to surf to the site and get the image of the radar from the webBrowser. But without success.
UPDATE
This is my webclient how i'm downloading the radar image today:
private void fileDownloadRadar()
{
if (Client.IsBusy == true)
{
Client.CancelAsync();
}
else
{
try
{
Client.DownloadFileAsync(myUri, Path.Combine(combinedTemp));
}
catch(Exception errors)
{
string errors2 = errors.ToString();
}
}
}
Client is WebClient
Now i'm going to the directory of where it was downloaded combinedTemp and i see that the downloaded file is 0kb empty.
The url in myUri is:
http://www.ims.gov.il/Ims/Pages/RadarImage.aspx?Row=9&TotalImages=10&LangID=1&Location=
When i put this link in my chrome and surf to it i see the latest radar image but when i'm looking in my hard disk it's 0kb the downloaded file.
And i will add this is not happening now but some time ago some months ago i had another problem in some cases not all the time but in many times when i downloaded the image i had another error i even have open question about it one year ago : Why i'm getting exception: Too many automatic redirections were attempted on webclient?
So in general it's two problems but now the problem is that the downloaded file is 0kb.
This is the Client completed event:
private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
try
{
client_Error_counter = client_Error_counter + 1;
if (client_Error_counter == 5)
{
Logger.Write("Tried to download radar image file " + client_Error_counter + " times without success");
Logger.Write("Error Tried to download radar image file : " + e.Error);
client_Error_counter = 0;
}
else
{
Client.DownloadFileAsync(myUri, Path.Combine(combinedTemp));
Logger.Write("Times tried to download radar image file: " + client_Error_counter);
Logger.Write("Error Tried to download radar image file : " + e.Error);
}
}
catch(Exception errors)
{
string myerr = errors.ToString();
}
}
And i see now i missed it that when it's getting to the DownloadFileCompleted event there is an error:
e.Error show: e.Error = {"Too many automatic redirections were attempted."}
StackTRace:
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)
This is why i tried to use the WebBrowser. I can't find a way to solve this "Too many automatic redirections were attempted" problem.
That's why i see the file 0kb on my hard disk.
Another thing is today few hours ago it did download fine some radar images but now it's making this error again.

How to dowload/upload file onto a users onedrive

I am in a Highschool club where we create windows store apps. I am in charge of the code that allows the user to either download files from their online onedrive storage, or upload files. So far I have successfully logged the user in and gained access to onedrive and display the users name with the following code:
private async void LoadProfile()
{
bool connected = false;
string text = "No Error:";
try
{
var authClient = new LiveAuthClient();
LiveLoginResult result = await authClient.LoginAsync(new List<string>() {"wl.signin", "wl.skydrive"});
if (result.Status == LiveConnectSessionStatus.Connected)
{
connected = true;
var connectClient = new LiveConnectClient(result.Session);
var meResult = await connectClient.GetAsync("me");
dynamic meData = meResult.Result;
Textblock_profilename.Text = meData.name;
}
}
catch (LiveAuthException ex)
{
//Set text to corresponding error
text = ex.ToString();
}
catch (LiveConnectException ex)
{
//Set text to corresponding error
text = ex.ToString();
}
if (text[0].ToString() != "N")
{
var dialog = new Windows.UI.Popups.MessageDialog(text);
await dialog.ShowAsync();
}
}
I gained the code from the following MSDN tutorial: http://msdn.microsoft.com/en-us/library/dn631823.aspx
However when I try to follow the next step, downloading and uploading files, I cannot get it to work. Right now I am just trying to press a button, and have the code download a test file:
private async void Button_downloadFile_Click(object sender, RoutedEventArgs e)
{
try
{
LiveDownloadOperation operation = await connectClient.CreateBackgroundDownloadAsync("skydrive/documents/enter_path");
var result = await operation.StartAsync();
//DO SOMETHING WITH RESULT HERE
}
catch
{
// Handle any errors.
}
}
However this code throws the following errors:
This is straight from the MSDN tutorial, and can't figure out how to fix the error. My best guess is I'm missing a "using" statement, but can't figure out what I am missing. Thanks for any and all help!
Make sure you're updated to use the Live SDK 5.6 binary. Be sure to let us know if you have any other problems with OneDrive integration!

IO Exception - File In Use By Another Process

C# / .NET 3.5, WindowsForms.
I have this Windows form that displays an image from a file, and whenever user saves the record this code is executed:
string oldLoc = itemsBO.ImageLoc;
if (oldLoc != SystemSettings.NoImageLocation)
{
if (File.Exists(oldLoc))
{
try { File.Delete(oldLoc); }
catch (IOException ex)
{
MessageBox.Show("1 - " + ex.GetType().ToString() + " " + ex.Message);
}
}
}
string saveLoc = itemsBO.ImageSearchLoc + ".jpg";
if (File.Exists(saveLoc))
{
try { File.Delete(saveLoc); }
catch (IOException ex)
{
MessageBox.Show("2 - " + ex.GetType().ToString() + " " + ex.Message);
}
}
try
{
if (pictureBox2.Image != null)
pictureBox2.Image.Save(saveLoc, System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (IOException ex)
{
MessageBox.Show("3 - " + ex.GetType().ToString() + " " + ex.Message);
}
Disregard the poor MessageBox messages, but it errors out in each Catch statement. It can't delete the "existing" Image because it says it's in use by another process. Can't save because a file exists in that same path because it's not deleting.
This is the code that sets the Image when they try to add a new picture;
Image clipImage = Clipboard.GetImage();
if (tabControl2.SelectedTab == tabPage5)
{
pictureBox1.Image = clipImage;
itemsBO.IsDirtyImage = true;
}
else if (tabControl2.SelectedTab == tabPage6)
{
pictureBox2.Image = clipImage;
itemsBO.IsDirtyImage2 = true;
}
Then when the form loads up an existing record with an image, this is the code used to fetch/display it:
byte[] bits = File.ReadAllBytes(imgfil);
msImage = new MemoryStream(bits, 0, bits.Length);
if (tabControl2.SelectedTab == tabPage5)
pictureBox1.Image = Image.FromStream(msImage);
else if (tabControl2.SelectedTab == tabPage6)
pictureBox2.Image = Image.FromStream(msImage);
imgfil being a path to the image, of course.
Absolutely no idea where to begin...
I have this Windows form that displays an image from a file, and whenever user saves the record
If you're still displaying the image when they save the file, the application will still be accessing the file if I'm not mistaken. Try disposing of the file first, probably by setting the picture box's (or whatever you're using to display the image) image to null, or load a blank picture before you perform the operation.
If it says file in use by another process, well then it must be in use by another process :)
Have you tried monitoring the file lock using Process Explorer.
Once you have identified what's holding your file, close that file handle using Process Explorer and then try to run your code.
This might help-
How to find out what processes have folder or file locked?
So I had inherited this application from another user, turns out the pictureBoxes were having their Image set in another chunk of code independent of that third block of code in the original post. It was because of this that the IOException was happening :(

Categories