How to get the video time in LibVLCSharp in c# - c#

My code is:
public Form1()
{
InitializeComponent();
Core.Initialize();
this.KeyPreview = true;
this.KeyDown += new KeyEventHandler(ShortcutEvent);
oldVideoSize = videoView1.Size;
oldFormSize = this.Size;
oldVideoLocation = videoView1.Location;
//VLC stuff
_libVLC = new LibVLC();
_mp = new MediaPlayer(_libVLC);
videoView1.MediaPlayer = _mp;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
TimeSpan Percent = TimeSpan.FromSeconds(_mp.Position);
label1.Text = Percent.ToString(#"hh\:mm\:ss");
TimeSpan time = TimeSpan.FromSeconds(_mp.Time);
label2.Text = time.ToString(#"hh\:mm\:ss");
TimeSpan length = TimeSpan.FromSeconds(_mp.Length);
label3.Text = length.ToString(#"hh\:mm\:ss");
}
The percentage part doesn't work at all, and the current time part doesn't run correctly and doesn't tick in a real clock but according to an illogical division, and the return of the total time of the video doesn't make sense in its conversion to the clock string.
It seems that the conversion doesn't fit here, or there is another code or an alternative, so I'm asking someone who has something that returns what I'm looking for, that is, how long the video actually is, and where it is now, in a way that looks like a clock, that is: .ToString(#"hh\ :mm:ss").
Thank you!

I know this is a little late, but your last question wasn't answered yet.
As mentioned in the comments you need to use milliseconds instead of seconds.
So, for your example above you would just need to change the TimeSpan method used like so
private void timer1_Tick(object sender, EventArgs e)
{
TimeSpan time = TimeSpan.FromMilliseconds(_mp.Time);
label2.Text = time.ToString(#"hh\:mm\:ss");
TimeSpan length = TimeSpan.FromMilliseconds(_mp.Length);
label3.Text = length.ToString(#"hh\:mm\:ss");
}
I've removed the position label because that is just a float that will be 0 to 1 so not useful in the TimeSpan.

Related

How can i make a countdown timer in C# that accounts for hours, minutes and seconds? [duplicate]

This question already has answers here:
How can I String.Format a TimeSpan object with a custom format in .NET?
(20 answers)
Closed 4 years ago.
I am not a good programmer, it's rather my hobby.
So please don't judge me for being bad at programming. This is my current code ive made for the countdown timer.
int i = 000000;
private void timer1_Tick(object sender, EventArgs e)
{
{
i++;
textBox1.Text = i.ToString() + "00:00:00";
}
}
When I run the timer. then the TextBox1 isn't showing 00:00:01, but it's showing 100;00;00.
Thank you for reading my post and again, sorry for having soo bad programming knowledge.
You can use this:
TimeSpan time = TimeSpan.FromSeconds(i);
textBox1.Text = time.ToString(#"hh\:mm\:ss");
Ok, so you know how to use Timer but your problem is with string, when you use + on string you are concatenating them, so say "hello" + " world" is equal to "hello world", so when you concat i with 00:00:00 the output you see is very logical.
you can use snippet below to achieve your goal(just replace your form class content with this)
private Timer _timer;
private Label _label;
private int _elapsedSeconds;
public Form1()
{
_timer = new Timer
{
Interval = 1000,
Enabled = true
};
_timer.Tick += (sender, args) =>
{
_elapsedSeconds++;
TimeSpan time = TimeSpan.FromSeconds(_elapsedSeconds);
_label.Text = time.ToString(#"hh\:mm\:ss");
};
_label = new Label();
Controls.Add(_label);
}
Edit
Tnx to #Juliet Wilson I edited how time is converted to string
I would suggest to use Stopwatch for that. It will do the magic you need. Here you can find good example of using Stopwatch class in C# https://www.dotnetperls.com/stopwatch.

Error message "Cannot evaluate expression because the current thread is in a stack overflow state"

I'm trying to create a recursive call to a method but receive error:
Cannot evaluate expression because the current thread is in a stack
overflow state
Just a bit of a background, I'm migrating a PowerBuilder app. to a C#.NET windows app., the PB app. has a timer that is done programmatically which will execute the main method at a specific time. The PB code runs on two machines, one timer is set at the '0' mark and on machine #2, it is set at the 30 second mark.
PB code below:
ue_wait event:
gi_offset = //Global variable set at the application open event, equivalent to program.cs - main event. Will be 0 or 30 depending on the machine.
li_difference = Integer( String( Now(), 'ss')) //Gets the seconds from the current date time.
DO UNTIL li_difference = gi_offset
ls_status = 'current second: ' + String( Now(), 'ss') + ' starting on:' + String( gi_offset)// Builds a string to display in a static text control in PB, label in C#.
IF st_status.Text <> ls_status THEN st_status.Text = ls_status
Yield()
li_difference = Integer( String( Now(), 'ss'))
LOOP
//execute main processing method.
ue_action().
//End of event
ue_action event
Do main processing.
Call ue_wait()
My C# code below:
private void Form1_Shown(Object sender, EventArgs e)
{
ue_wait();
}
private void wf_actions_Load(object sender, EventArgs e)
{
//Should fire after all of the form has loaded.
Shown += Form1_Shown;
}
private void ue_wait()
{
long todays_date_in_seconds = DateTime.Now.Second;
long ll_global_offset = 0;
string ls_status = "";
todays_date_in_seconds = DateTime.Now.Second;
while (!(todays_date_in_seconds == ll_global_offset))
{
ls_status = "Current second: " + DateTime.Now.Second.ToString() + " starting on: " + ll_global_offset.ToString();
lbl_status.Text = ls_status;
todays_date_in_seconds = DateTime.Now.Second;
}
ue_action();
}
private void ue_action()
{
//After the main processing is done, it goes back to ue_wait().
ue_wait();
}
So I have tried the two possibilities that I found on the Inet:
this.Shown += new System.EventHandler(this.Form1_Shown);
this.Activated += AfterLoading;
However when calling ue_action I get the error below in the ue_wait event for both...
{Cannot evaluate expression because the current thread is in a stack
overflow state.}
Fails on the first line: long todays_date_in_seconds = DateTime.Now.Second;
I found the .NET timer but it does not allow you to set the Start at a specific point in time, ie: seconds, Timer.Start() = 0 mark or Timer.Start() = 30 second mark (30000 milliseconds). The interval is one part that would work as I could set it to execute every 60 seconds.
After doing some googling, because there is 'recursive' programming, this is causing the 'Stack Overflow', how can I avoid the 'Stack Overflow' in the .NET environment or would there be another way to do what I need to do in the C#.NET environment?
The simplest approach would be to use a 1s System.Windows.Forms.Timer, that's a no brainer:
// timer initialization, somewhere
timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += Timer_Tick;
DateTime? _lastHandledTimestamp = null;
private void Timer_Tick(object sender, EventArgs e)
{
// get current timestamp
var currentTimestamp = DateTime.UtcNow;
var currentSecond = currentTimestamp.Second;
// not the correct second yet?
if (currentSecond <= TARGET_SECOND)
return;
// truncate seconds and check if we already handled this hh:mm
var flooredToNearestMinute = currentTimestamp.AddSeconds(-currentSecond);
if (_lastHandledTimestamp.HasValue &&
_lastHandledTimestamp.Value >= flooredToNearestMinute)
return;
// if we're here, we are good to go
_lastHandledTimestamp = flooredToNearestMinute;
DoStuff();
}
If you want to avoid triggering the tick event every second, use a System.Threading.Timer instead, and use its Timer.Change method to calculate the next time it needs to fire on each iteration.
Groo, thanks for the input on the timer, I tweaked it for what I need to do.
private void timer1_Tick(object sender, EventArgs e)
{
string ls_status = "";
var currentSecond = DateTime.Now.Second;
ls_status = "Current second: " + currentSecond.ToString() + " starting on: " + Il_offset.ToString();
lbl_status.Text = ls_status;
if (currentSecond == Il_offset && Ib_processing_completed)
{
//Main processing method
ue_action();
}
}
In the Tick event, I populate an instance variable of offset in the PageLoad, in this case it will be 1 or 31 and set a Boolean variable to true in the ue_action event after successful processing.
To get rid of the original problem, instead of doing recursive programming and looping, the Tick event was recommended instead which meets my needs.
Thank you, the .NET learning curve begins.
William.

How to define a timers interval from a textbox in C#

I am learning C# and I am coding a simple auto typer, and I am trying to make it so users' can set their own interval. I tried using:
timer1.Interval = textbox1.Text;
but that doesn't seem to be working. I put that code in a button.. How do I get this to work? And why isn't it working?
You could use something like this:
int value;
// if it is really a value
if (int.TryParse(textbox1.Text, out value))
{
// if the value is not negativ (or you can enter the lower boundary here)
if (value > 0)
{
timer1.Interval = value;
}
}
As Steve mentioned in his comment, you need to connect a callback function to the timer1.Elapsed event (Attention: The name of the event differs depending on the timer you are using. It could also be timer1.Tick). You would do this by using the following code:
timer1.Elapsed += TimerElapsedCB;
and you need to define the callback function itself:
private void TimerElapsedCB(object sender, ElapsedEventArgs e)
{
// Do something here ;-)
// (e.g. access the signal time by using e.SignalTime)
}
try this :
Timer timer1 = new Timer();
timer1.Interval = int.Parse(textbox1.Text);
but keep in mind that user must enter a number , so you might need to handle the case when the user enter wrong data .
Edit :
You might use TryParse to make sure it's a number :
int myInt = 0;
Timer timer1 = new Timer();
bool parsed = int.TryParse(textbox1.Text,out myInt);
if (parsed)
{
timer1.Interval = myInt;
}

using 2 datepickers to display days difference in a textbox

I have 2 datetime pickers and i want to display number of days between them on a text box if a user selects a date.. the problem with my code is that its not giving me correct answers and the time span doesnt seem to work.. i dont know where im going wrong thats why i asked for assistance.
I hope that explained better, please bear with me, its my first time to be on this site so im not familiar with the controls, sending stuff and updating
When i choose different dates it gives me answer 10.999998008713 days instead of 11 days and i dont know if i need to do math roundup
private void btnCalc_Click(object sender, EventArgs e)
{
DateTime start = ArrivalDate.Value;
DateTime finish = DepartureDate.Value;
TimeSpan numberOfNights = finish-start;
double TotalDays= numberOfNights.Days;
txtBoxNum.Text = (numberOfNights.ToString());
}
private void ArrivalDate_ValueChanged(object sender, EventArgs e)
{
DepartureDate.Value = ArrivalDate.Value.AddDays(1);
}
private void DepartureDate_ValueChanged(object sender, EventArgs e)
{
// setting messagebox to a sensible default message if no date or wrong date picked
if (DepartureDate.Value < ArrivalDate.Value)
{
MessageBox.Show("Cannot be less than previous date");
DepartureDate.Value = ArrivalDate.Value.AddDays(1);
}
else
{
double Days = (DepartureDate.Value - ArrivalDate.Value).TotalDays;
txtBoxNum.Text = Days.ToString();
return;
You need to get only the date part from your date picker:
DateTime start = ArrivalDate.Value.Date;
DateTime finish = DepartureDate.Value.Date;
Otherwise you also get time which interferes with your calculations.
Also, to display number of days as integer, use:
int TotalDays = numberOfNights.Days; // Days is int anyway
txtBoxNum.Text = TotalDays.ToString();
Or simply
txtBoxNum.Text = numberOfNights.Days.ToString();
You can actually put the whole code into one line:
txtBoxNum.Text = new TimeSpan(DepartureDate.Value.Date.Ticks - ArrivalDate.Value.Date.Ticks).Days.ToString();

Simple button animations

I am trying to learn .NET programming. As a part of my learning, I tried to make some effects on buttons. It is working... but not as smooth as I imagined! Is there any better way to do this? Thank you in advance!
My need:
There are 3 buttons.
When you hover the mouse over one of them, it expands and when you mouse out from that button, it returns to its initial size.
private void button1_MouseHover(object sender, EventArgs e)
{
button1.BackColor = Color.White;
button1.Width = 130;
button1.BringToFront();
}
private void button1_MouseLeave(object sender, EventArgs e)
{
button1.BackColor = Color.Red;
button1.Width = 75;
}
private void button2_MouseHover(object sender, EventArgs e)
{
button2.BackColor = Color.Gray;
button2.Width = 130;
button2.BringToFront();
}
private void Form1_MouseLeave(object sender, EventArgs e)
{
button2.BackColor = Color.Red;
button2.Width = 75;
}
private void button3_MouseHover(object sender, EventArgs e)
{
button3.BackColor = Color.DimGray;
button3.Width = 130;
button3.BringToFront();
}
private void button3_MouseLeave(object sender, EventArgs e)
{
button3.BackColor = Color.Red;
button3.Width = 75;
}
So first off, you don't want to do the exact same thing 3 times. Create a single method to add the appropriate handlers for a button, and then just write the code once to handle any given button.
Note that you can go into the expand/contract tick handlers and use the percentComplete value to set the height as well, to move the color along a spectrum (this would involve some mathematics of colors to do though) or to alter any other aspect of the button. If you're really motivated to generalize it you could add a parameter to the method of Action<double> that does something to the object based on the given percent progress.
public void AddAnimation(Button button)
{
var expandTimer = new System.Windows.Forms.Timer();
var contractTimer = new System.Windows.Forms.Timer();
expandTimer.Interval = 10;//can adjust to determine the refresh rate
contractTimer.Interval = 10;
DateTime animationStarted = DateTime.Now;
//TODO update as appropriate or make it a parameter
TimeSpan animationDuration = TimeSpan.FromMilliseconds(250);
int initialWidth = 75;
int endWidth = 130;
button.MouseHover += (_, args) =>
{
contractTimer.Stop();
expandTimer.Start();
animationStarted = DateTime.Now;
button.BackColor = Color.DimGray;
};
button.MouseLeave += (_, args) =>
{
expandTimer.Stop();
contractTimer.Start();
animationStarted = DateTime.Now;
button.BackColor = Color.Red;
};
expandTimer.Tick += (_, args) =>
{
double percentComplete = (DateTime.Now - animationStarted).Ticks
/ (double)animationDuration.Ticks;
if (percentComplete >= 1)
{
expandTimer.Stop();
}
else
{
button.Width = (int)(initialWidth +
(endWidth - initialWidth) * percentComplete);
}
};
contractTimer.Tick += (_, args) =>
{
double percentComplete = (DateTime.Now - animationStarted).Ticks
/ (double)animationDuration.Ticks;
if (percentComplete >= 1)
{
contractTimer.Stop();
}
else
{
button.Width = (int)(endWidth -
(endWidth - initialWidth) * percentComplete);
}
};
}
If you are using WinForms, animations are going to be rather painful and you will have to handle them yourself via Timer objects.
If you are getting into .NET and want to make cool-looking applications with animatons and styling, I highly recommend you look at WPF instead. It can do animations very easily though C# or XAML.
While it is still possible in WinForms, it will take far more development time where as those features are built into WPF already (and optimized).
When you modify a controls properties, it takes effect instantaneously. What you desire is something that is usually known as some type of fade or tweening. There might be libraries out there to do this, but if you wanted to write this yourself for fun, you can use a Timer object, and on each tick update the color.
What you would do is set a color as the TargetColor somewhere(this is a variable or property you make up), and then start a timer that ticks maybe every 10 milliseconds. In each tick, you look at the start time, and how long has passed since then. If you want the animation to take place of a full second, then that is 1000 milliseconds. So during each tick, you look at the amount of time that has passed, maybe 200 milliseconds, then divide 200/1000 to get the fraction of time that you have gone into the animation. Then you look at a difference between the Start and Target Color, multiply that difference by the fraction, and add the result to the start color. In other words, 200 milliseconds into an animation that last 1000 milliseconds, means you are 20% into the animation. Thus you want to set the color to be whatever color is 20% from the start color towards the end color.
There's alot you could do to refine this. Perhaps having a subclass Button control that encapsulates the timer and exposes functions/properties to track start/end color, animation transition time, etc. Most animated UI features like this let you specify how long the animation should last, and then it interpolates the inbetween states as it transitions. This is the origin of the term tweening, as it comes from transitioning from one state to another by inbetweening

Categories

Resources