Trackview or timeline in Naudio - c#

How can I use trackview or timeline in Naudio in C#?
Here is my code and it's not working.
I want to see my line going as track is playing.
NAudio.Wave.WaveStream pcm = NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(new NAudio.Wave.Mp3FileReader(open.FileName));
customWaveViewer2.WaveStream = pcm;
stream = new NAudio.Wave.BlockAlignReductionStream(pcm);
trackView1.NowTime = stream.CurrentTime;

Unfortunately, TrackView and TimeLine are not completed controls, and you would be better off writing your own custom control to place a vertical line at a position that represents the now playing time.
You would probably be best using a timer to invalidate your custom wave viewer, and in the Paint method, drawing a vertical line that represents the current play time.

Related

How to set the start time of MediaClips in c# MediaComposition?

I have a UWP Desktop application in which I use a MediaComposition with multiple images. The problem is that all images have a specific time to appear and a duration. How do I set the start time for each MediaClip?
MediaComposition mediaComposition = new MediaComposition();
var clipCover = await MediaClip.CreateFromImageFileAsync(stgCover, tmsCompositionDuration);
mediaComposition.Clips.Add(clip);
How to set the start time of MediaClips in c# MediaComposition?
Currently, there is not such api to set start time for the MediaClip, you just make image clip with specific duration and insert it into mediaComposition list. for the start time, you need calculate it manually (previous clips duration summation).
For your scenario, you could use MediaClip.CreateFromColor to make empty color frame and insert it into specific index to update the clip's start time.
for more detail, please refer to this Media compositions and editing tutorial.
You can use Overlays:
Because overlays are stacked on top of each other instead of being played sequentially, all overlays start playback at the beginning of the composition by default. To cause an overlay to be begin playback at another time, set the Delay property to the desired time offset (source)

C# move cursor on screen based on where text appears on desktop

So I have searched and can't seem to find the right resources or tools for what I am wanting to do so I thought I'd ask for some help. Below is what I am wanting to do.
I am making a .Net core application that will simulate some key strokes and that is all working fine, but I want to also move the mouse based on where certain text appears on the screen, however, I will not have control over the application where the text appears, so I will need to somehow either be streaming the desktop view and using something to analyze it, or constantly taking a screen shot every 10 seconds or so and analyzing that screen shot if the text is there and then move the mouse to that position of text and simulate a left click.
I am not really confident in the screenshot approach as I am not sure how I'd get the mouse coordinates, so I have a feeling I will need to feed a desktop stream into something in order to get the image I am analyzing and then overlay my own transparent overlay on top of that in order to move the cursor to appropriate position.
I hope this makes sense and any libraries or whatever that is recommended to do this is appreciated. I know how to move the cursor on the screen and left click, just haven't found on google the right library for analyzing a desktop screen in real time and getting coordinates based on searching conditions.
Thank you everyone.
So I figured out what I needed to do. Trying to match the text with and OCR proved to be impossible as the text was layered into an image where they actively tried to prevent detection, this is because its a video game and they don't want automation I guess. So what I did was determine I will always know what the button is going to look like, so I took a screen shot of the button and now I take screenshots of the game every 10 seconds and then search that image for my button template image. If the image has a match, then I generate coordinates and send mouse there and click it. Below is the code I used and you will need the libraries from AForge to use this code.
Bitmap sourceImage = (Bitmap)Bitmap.FromFile(#"C:\testjpg.jpg");
Bitmap template = (Bitmap)Bitmap.FromFile(#"C:\buttonjpg.jpg");
// create template matching algorithm's instance
//Resize value
var resizePercent = 0.4;
//Resizing images to increase process time. Please note this will result in skewed coordinates.
//You must divide the coordinates by your resizePercent to get native coordinates taken from screen shots.
sourceImage = new ResizeBicubic((int)(sourceImage.Width * resizePercent), (int)(sourceImage.Height * resizePercent)).Apply(sourceImage);
template = new ResizeBicubic((int)(template.Width * resizePercent), (int)(template.Height * resizePercent)).Apply(template);
// (set similarity threshold to 0.951f = 95.1%)
ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0.951f);
// find all matchings with specified above similarity
TemplateMatch[] matchings = tm.ProcessImage(sourceImage, template);
// highlight found matchings
BitmapData data = sourceImage.LockBits(
new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
ImageLockMode.ReadWrite, sourceImage.PixelFormat);
foreach (TemplateMatch m in matchings)
{
Drawing.Rectangle(data, m.Rectangle, Color.White);
Console.WriteLine(m.Rectangle.Location.ToString());
var x = m.Rectangle.Location.X;
var y = m.Rectangle.Location.Y;
//Fixing the coordinates to reflex the origins of the original screenshot, not the resized one.
var xResized = (int)(x / resizePercent);
var yResized = (int)(y / resizePercent);
// do something else with matching
}
sourceImage.UnlockBits(data);
I did notice my coordinates were off usually around ~4.5%-8% from dead center(the button still gets clicked, but I want a perfect center click), so for me I am calculating a range of coordinates, which in this range are not very many to ensure the button I want to click is clicked and not missed and just having program click all the potential coordinates.
So I hope this helps someone!
Kind Regards,
Aaron
Depending on the application there are a number of approaches you might want to try.
For example, using Application Insights and UI Automation, you might be able to capture the text directly.
If you have the exe file, then you might be able to decompile it with something like dotPeek and then use Visual Studio's Live debugging feature to access the text.
You might be able to inspect the heap of the running process via a tool like HeapMemView.
Optical Character Recognition might be an option worth considering. In that case Tesseract is an open source OCR engine worth considering. This can be used in conjunction with screenshots to extract text.

Import frames from a video

I'm using MediaPlayer to open a video and DrawingContext.DrawVideo() to get a specific frame from a video source.
The problem is that I can't know if the MediaPlayer is positioned at the right place.
Therad.Sleep(500) is a hack.
Is there another easy way of getting frames from a video source? Or should I start looking for a DirectShow solution?
There's a somewhat elderly but potentially useful implementation of frame grabbing with a MediaPlayer here:
dlaa.me/blog/post/8921665
Here is the simple structure of the media grabber:
LoadVideo();
//Add event handler to the Changed event.
GetFirstFrame();
//Change video Position.
//When the Changed event fires:
GetCurrentFrame();

NAudio display both channels in WaveViewer

I am using NAudio's WaveViewer UI control where I display the waveform using
this.customWaveViewer1.WaveStream = new NAudio.Wave.WaveFileReader(filename);
I am wondering how can I display each channel in it's own WaveViewer?
WaveViewer is a very simple example of how to show waveforms. If you want stereo, I'd recommend copying the source code for it, and modifying the OnPaint method to draw two lines, one for the left channel and one for the right.

Save video from WPF animation / storyboard

I have a really complex Storyboard which works perfectly when run on a "live" window but I have trouble manually animating this storyboard to get a frame-by-frame animation which I can save to individual PNG files. All of the generated images are 1st animation frame.
I have see this, this, this and ultimately this. There is also this MSDN sample but all of them talk about animating a single DependencyProperty. What I need is the ability to step through frame by frame having a complex Storyboard, not just one DP.
I have searched everywhere without any luck. Also my experiments have all failed. Any help is appreciated. Here is a bit of non-functional code.
storyboard.Begin(grid, true);
//storyboard.Pause();
//var clock = storyboard.CreateClock();
//clock.Controller.Pause();
var secs = Enumerable.Range(0, totalFrames).Select(t => (((double)t) / FPS));
grid.Measure(new Size(480, 340));
grid.Arrange(new Rect(grid.DesiredSize));
foreach (var sec in secs)
{
//clock.Controller.SeekAlignedToLastTick(TimeSpan.FromSeconds(sec), TimeSeekOrigin.BeginTime);
storyboard.SeekAlignedToLastTick(TimeSpan.FromSeconds(sec), TimeSeekOrigin.BeginTime);
grid.InvalidateVisual();
grid.UpdateLayout();
var filename = Path.Combine(tempFolder, string.Format("image{0}.png", sec));
var rtb = new RenderTargetBitmap((int) grid.ActualWidth, (int) grid.ActualHeight, 96, 96, PixelFormats.Pbgra32);
rtb.Render(grid);
var png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(rtb));
using (var stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite))
{
png.Save(stream);
}
}
#wpfwannabe: thanks a lot for the insight.
I used your code and it worked out, although with a minor modification as shown below:
rootStoryBoard.SeekAlignedToLastTick(Program.AnimPlots.canvs, TargetTmspn, System.Windows.Media.Animation.TimeSeekOrigin.BeginTime);
In the above line of code: Program.AnimPlots.canvs is the area of snapshot, in your case it is grid and TargetTmspn is the object of type TimeSpan.
Hope this helps someone :)
Here's another approach that you may find useful. If you've exhausted all options for animating your XAML Storyboard frame-by-frame then another option you could explore would be to create your Storyboard in code instead, here's an example: Animation in codebehind for loop, using RenderTransform
The benefit of that is then you'd have total programmatic control over your Storyboard to step through the individual key frames one-by-one, where you could then save an image after each frame.
I did something conceptually similar in jQuery a while back. Basically I wrote a line drawing signature app that saved coordinate data points. I could then reload the data points back into the algorithm and reproduce the animation. http://kodekreachor.com/prototypes/
I know it's a very different technology but it's the idea of being able to completely control the sequential animation from code that should be the take-away and hopefully serve as some inspiration for you.

Categories