How to play a video from the Internet in WPF? - c#

I want to play a video from the Internet in WPF. I used the code below. It can play the video but it always breaks down and the speed is very slow. I don't know how to solve this problem.
mediaElement.MediaFailed += mediaElement_MediaFailed;
mediaElement.LoadedBehavior = MediaState.Play;
mediaElement.Source = new Uri(#"http://media2.neu6.edu.cn/hls/cctv6hd.m3u8", UriKind.Absolute);

As I understand this is a long term issue with Media Element itself. Try using WPFMediaKit
instead.

Related

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();

Synchronous sound playback from video source in VideoSourcePlayer control

I'm using the Video Source Player control from AForge.Controls to play a few video clips within a winforms application.
The code is something like this.
string fileName = #"C:\path\to\file.example";
videoSourcePlayer.VideoSource = new AForge.Video.AsyncVideoSource(new FileVideoSource(fileName), true);
videoSourcePlayer.Start();
The video file includes both audio and video streams, however as far I'm aware the control only handles video and not audio.
How can I then play the audio stream in a synchronous fashion with the video source player control?
Thank you.
EDIT:
The Video Source Player control has a event named NewFrame, which allows to determine the precise video position which could be useful to keep the audio being played synchronized with the video.
Since you mentioned:
I'm only looking for other alternative in which is possible to
reproduce the audio contained the video file and somehow keep it
synchronized with the video player control...
Maybe you can have a better luck by using a ElementHost and using WPF media control.
If this solution is eligible for you follow this steps:
Create a new WPF UserControl and add to your WindowsForms app.
In this UserControl add a media element and configure the way you want.
Build the solution.
Now in the toolbox must appear YourSolutionName Controls and you controls must be there.
Just drag it to your WindowsForms app and it must create an ElementHost.
I've created the UserControl as follow:
<MediaElement Name="VideoMediaElement"
Source="Media/Wildlife.wmv"
LoadedBehavior="Manual"/>
Just remember in this example this file must be side-by-side with your app in a Media folder. If you miss this step it will give you the strange and not helpful error 0xC00D11B1.
The loaded behavior Manual will give you the chance to control de video more freely.
After that you can do whathever you want in this UserControl like create Play and Pause:
internal void Play()
{
this.VideoMediaElement.Play();
}
And to access them in WindowsForms do this:
private void WindowsFormsButton_Click(object sender, EventArgs e)
{
var videoControl = this.MyElementHost.Child as VideoUserControl;
videoControl.Pause();
}
Hope this helps. WPF MediaElement is much more easy to seach for than other libs.

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.

Trackview or timeline in Naudio

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.

Accessing Windows Media Player's Playback Speed controls

Is there a way to access WMP10+'s playback speed controls in a dotnet app?
User level information on the Playback control information
Add the AxWMPLib to your VB/C# project.
Add an AxWindowsMediaPlayer control to your form.
Use the following method to access playback rate:
AxWindowsMediaPlayer1.URL = "e:\song.mp3"
AxWindowsMediaPlayer1.Ctlcontrols.play()
AxWindowsMediaPlayer1.settings.rate = 0.5
*Note that rate may not always be available depending on the media type. A safer method of accessing rate would look like:
If (player.settings.isAvailable("Rate")) Then
player.settings.rate = 0.5
End If
If that isn't what you're looking for, there also exists the MediaPlayer COM object. I didn't investigate it thoroughly, but intellisense yielded:
Dim mpMediaPlayer As New MediaPlayer.MediaPlayer
mpMediaPlayer.FileName = "e:\song.mp3"
mpMediaPlayer.Rate = 0.5
mpMediaPlayer.Play()
Hope that helps.
If you are using a MediaElement object, I would suggest adjusting the SpeedRatio property. Here is an example from Microsoft.
From your comment, it sounds like the SpeedRatio is the way to go. Because it allows you to adjust the playback speed. The MediaElement or MediaPlayer is basically just a Windows Media Player.

Categories