C# gif medialement how to change position - c#

I just want to change the position of the gif in the MediaElement, so when i don't hover it with the mouse it should display a certain image of the GIF (the selected position) and when i move the cursor on the MediaElement the GIF should start playing from position zero. But i am not able to change the position of the GIF at all.
It starts playing and i can pause it, but setting position and the stop() method have no influence at all.
XAML Code:
<MediaElement x:Name="mediaElement" Source="C:\temp\smartGif.gif"
ScrubbingEnabled="True" Loaded="mediaElement_Loaded"
MouseLeave="mediaElement_MouseLeave"
MouseEnter="mediaElement_MouseEnter"
LoadedBehavior="Manual"
HorizontalAlignment="Left"
Height="600"
Width="800"
VerticalAlignment="Top"/>
Basic Code:
public UserWindow()
{
InitializeComponent();
}
private void mediaElement_Loaded(object sender, RoutedEventArgs e)
{
mediaElement.Play();
mediaElement.Position = TimeSpan.FromMilliseconds(100);
mediaElement.Pause();
}
private void mediaElement_MouseEnter(object sender, MouseEventArgs e)
{
mediaElement.Play();
mediaElement.Position = TimeSpan.Zero;
}
private void mediaElement_MouseLeave(object sender, MouseEventArgs e)
{
mediaElement.Position = TimeSpan.FromMilliseconds(100);
mediaElement.Pause();
}
Is it right that the MediaElement needs to play that the position can be changed?
Changes: As suggested i added this:
MediaFailed="mediaElement_MediaFailed"
and that:
private void mediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e)
{
MessageBox.Show("failed");
}
But it does not show up, i dont know what to do. Is the gif then working fine or what could cause this? Do i need to download gifs in a special way to ensure it supports normal features? I tried it with different gifs and its still not working.

Surprisingly no one on the internet has reported this yet and lots of pepople say that it´s working, but it is actually not possible to change the position of a gif running in a MediaElement. The normal way is above in my question, which works for *.mp4 for example, but not for gifs. To convince you the easy way try out to play a gif in the Windows Media Player. As the MediaElement is very thin wrapped around Windows Media Player you will see the same result, changing the position is disabled.
There is a very ugly way how to reset a gif to play it from the beginning, but i dont suggest to use it if you have other options. This can be applied to any event/trigger.
private void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
{
if (mediaElement.Source.ToString() == "file:///C:/temp/newGif1.gif")
{
mediaElement.Source = new Uri("C:\\temp\\newGif.gif");
mediaElement.Play();
}
else
{
mediaElement.Source = new Uri("C:\\temp\\newGif1.gif");
mediaElement.Play();
}
}
The only way is to reset the source to start the gif from the beginning, but you need a copy of your gif, because if it is the same source the MediaElement won´t update the source. In generell when you set the source for a MediaElement you have to set the fullpath. In XAML you can choose the gif from anywhere on your pc, it does not need to be set as a resource in your project.
But setting the source in the normal code, requires the gif to bet set as a resource in the project. So normally it is not temp like in the example but rather something like
C:\Users\UnknownUser\Documents\Visual Studio 2015\Projects\RandomTestProject\Ressources.
If you dont rely on using gifs i suggest you to use *.mp4, because it is easier to handle and works the expected way and you can convert your *.gif easy to *.mp4.

This is hardly the ideal solution but I've found that you can loop a .gif image by subscribing to the MediaEnded event and setting the Position property to TimeSpan.FromMilliseconds(1) then calling the Play method.
e.g.
// Subscribe to the event
mediaElement.MediaEnded += mediaElement_MediaEnded;
private void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
{
// set the `Position` property to a 1ms `TimeSpan` and `Play`
mediaElement.Position = TimeSpan.FromMilliseconds(1);
mediaElement.Play();
}
Calling Play after setting the TimeSpan to 0 was not working for me. I'm unsure of the underlying cause.

Related

Draging a picturebox image outside the form

I've been attempting to drag an image from a Picturebox outside my form boundaries just in the same manners that Windows Explorer does, so for instance, dropping it into an external webbrowser to view, Skype to send etc
Switched to VB.NET to find the most basic solution, but no luck there unfortunately. The drag n' drop effect shows outside my form, however, no application accepts or properly responses to the image drop.
Code is ran on the MouseDown event of the Picturebox.
Me.DoDragDrop(PictureBox1.Image, DragDropEffects.All)
Any ideas? C# or VB.NET, both are fine for me.
Thanks
I found this solution for WPF: Drag and drop to Desktop / Explorer
For winforms works like this:
private void DragDropImage()
{
var filename = "filename.jpg";
var path = Path.Combine(Path.GetTempPath(), filename);
this.pictureBox1.Image.Save(path);
var paths = new[] { path };
this.pictureBox1.DoDragDrop(new DataObject(DataFormats.FileDrop, paths), DragDropEffects.Copy);
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
this.DragDropImage();
}
This will copy the content of your picturebox to a temp directory. Then makes a dodragdrop. Its tested and works for me. Code is executed in MouseMove and checks if mouse is clicked.
feal's code worked, however, I didn't see the need to waste time/processing power on saving the image so I modified it to the following in case somebody faces the same issue in the future. Code is inserted in the MouseDown event of the control.
VB.NET:
Me.DoDragDrop(New DataObject(DataFormats.FileDrop, {"Image Path"}), DragDropEffects.All)
C#:
this.DoDragDrop(new DataObject(DataFormats.FileDrop, new[] {#"Image Path"}), DragDropEffects.All);
Thanks a lot, feal.

How to hide MediaPlayer control in UWP

I am using MedialPlayer control to play sound effects in my app as explained here. Sounds are short sound effects that play "in the background" when something happens in the app, user should not see any sort of media playback control.
Code is fairly straight forward, looks something like this:
MediaPlayer mPlayer = new MediaPlayer();
mPlayer.Source = MediaSource.CreateFromUri(pathUri);
mPlayer.Play();
This works well, except, when user presses volume control button on the keyboard, a mini media player control appears next to volume control and the user can press play button to play the last sound again (see picture). I want to hide this. User should not see this or be able to replay sounds.
Solutions offered in question 14578867 do not work. Properties mentioned in the answers do not exist (e.g. IsPlayPauseVisible, uImode, IsInteractive). I tried using similar properties from SystemMediaTransportControls but it makes no difference. I think these are meant for the control that appears in the app (which I do not have), not for the "OS media control" that I want to hide.
mPlayer.SystemMediaTransportControls.IsEnabled = false;
mPlayer.SystemMediaTransportControls.IsPlayEnabled = false;
How can I disable/hide this?
Here is a step-by-step guide to replicate the issue:
Create a new Windows Universal Visual C# Blank App
Add a button to MainPage.xaml and mp3 file to assets
Paste below code to MainPage.cs
Run the app, click button
On the keyboard press volume up button
Observe the "media control" with play button next to volume control (see image above).
Pressing play button plays the sound again. If you are quick you can also pause the playback. SystemMediaTransportControls properties make no difference.
using Windows.Media.Core;
using Windows.Media.Playback;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
namespace App2
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Button_Tapped(object sender, TappedRoutedEventArgs e)
{
MediaPlayer mPlayer = new MediaPlayer();
mPlayer.Source = MediaSource.CreateFromUri(new System.Uri("ms-appx:///Assets/clap.mp3"));
mPlayer.SystemMediaTransportControls.IsPlayEnabled = false;
mPlayer.SystemMediaTransportControls.IsEnabled = false;
mPlayer.Play();
}
}
}
It seems it is caused by the MediaPlayer is not ready, when we set false to the MediaPlayer.SystemMediaTransportControls.IsPlayEnabled.
We should be able to add MediaOpened event of the MediaPlayer, then we can set false to the MediaPlayer.SystemMediaTransportControls.IsPlayEnabled in the MediaOpened event.
For example:
MediaPlayer mPlayer;
private void Button_Click(object sender, RoutedEventArgs e)
{
mPlayer = new MediaPlayer();
mPlayer.Source = MediaSource.CreateFromUri(new System.Uri("ms-appx:///Assets/xxxxx.mp3"));
mPlayer.MediaOpened += MPlayer_MediaOpened;
mPlayer.Play();
}
private void MPlayer_MediaOpened(MediaPlayer sender, object args)
{
mPlayer.SystemMediaTransportControls.IsEnabled = false;
}
If you just disable the button that in SystemMediaTransportControls, you should be able to set false to MediaPlayer.CommandManager.IsEnabled.
If you are using MediaPlayer to play media, you can get an instance of the SystemMediaTransportControls class by accessing the MediaPlayer.SystemMediaTransportControls property. If you are going to manually control the SMTC, you should disable the automatic integration provided by MediaPlayer by setting the CommandManager.IsEnabled property to false.+
If you disable the MediaPlaybackCommandManager of the MediaPlayer by setting IsEnabled to false, it will break the link between the MediaPlayer the TransportControls provided by the MediaPlayerElement, so the built-in transport controls will no longer automatically control the playback of the player. Instead, you must implement your own controls to control the MediaPlayer.
For more info, see Set up transport controls.
For example:
_mediaPlayer = new MediaPlayer();
_systemMediaTransportControls = _mediaPlayer.SystemMediaTransportControls;
_mediaPlayer.CommandManager.IsEnabled = false;

MediaElement doesn't play sound effect

I want to play a beep sound effect when the user clicks.
I have a beep.mp3 file added to the project (isn't in a folder). In it's properties I see Build Action is set to Content
and this MediaElement:
<MediaElement Name="beep" Source="beep.mp3" Volume="1" AutoPlay="False"/>
then I can't hear any sounds after this:
beep.Play();
I've build a simple example (following your code) and everything should be ok. Just to ensure that everything is all right I'll perform some checkups described below:
In XAML:
<Button x:Name="myButton" VerticalAlignment="Cener" Content="BEEP"/>
<MediaElement Name="beep" Source="beep.mp3" Volume="1" AutoPlay="False" MediaFailed="beep_MediaFailed" MediaOpened="beep_MediaOpened"/>
Code behind:
public MainPage()
{
InitializeComponent();
myButton.Click += (sender, e) => { beep.Play(); };
// this below checks if your file exists
if (Application.GetResourceStream(new Uri("beep.mp3", UriKind.Relative)) == null)
MessageBox.Show("File not Exists!");
}
private void beep_MediaFailed(object sender, ExceptionRoutedEventArgs e)
{
// Show Message when opening failed
MessageBox.Show("There was an error: " + e.ErrorException.Message);
}
private void beep_MediaOpened(object sender, RoutedEventArgs e)
{
// as it's subscribed in xaml, juts after opening the App you should hear beep
beep.Play();
MessageBox.Show("Media opened");
}
First - in Constructor I perform a check up if my beep.mp3 exist (check if I can get it as a resource stream). If everything is ok, there you shouldn't see a message. Then after a while you should see one of the messages (Failed/Opened). If opened, then you should also hear beep.mp3.
Just be aware that if you for example put beep.Play() just after InitializeComponent, then you probably won't hear it - that's becasue the media must be opened before it's played (of course normally there is no need to subscribe to that event if you don't need to, but if you are having problems then it's nice to know if the media was opened).
On the other hand I would probably follow WiredPraire suggestion (in comment) and used SoundEffect to play short sounds.
Hope this helps a little.
Had something similar in Silverlight project. Try to add it into Assets folder, set to Content/Resource and Copy always to output.

MediaElement doesn't play after resuming app

Here is my xaml code:
<MediaElement x:Name="beepSound" Source="/Sounds/beep.mp3" AutoPlay="False" Visibility="Collapsed"/>
C# code:
private void ButtonClick(object sender, RoutedEventArgs e)
{
if (beepSound.CurrentState == System.Windows.Media.MediaElementState.Playing)
beepSound.Pause();
else
beepSound.Play();
}
This code works perfectly. But after I resume the app (by pressing start button and then back again into the app) the sound doesn't play. What causes this behavior? Is there anything wrong with my code?
There is nothing wrong in your code
Its just that, Media Element stops working in the background. CurrentState of the media elements gives a "Closed" when we get back to the app after pressing the start button.
You need to use a player that plays the sound even when the app goes in the background(start key press/lock key press). And BackgroundAudioPlayer follows over your requirement.
I am not very much aware with how it works but I can suggest you with some links at this point of time.
Please have a look at the BackgroundAudiolayer
and also its namespace.
And a Sample
Enjoy!
After a bit of research I found out that, after the app resumes it loses its source information. So you have to set the source again. Here is how I did it.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
beepSound.Source = new Uri("/Sounds/beep.mp3", UriKind.Relative);
}

AxWindowsMediaPlayer as image slideshow

AxWindowsMediaPlayer can be used for showing images to user. If you set URL to example.png, image will be shown to user for exactly 5seconds (read from Ctlcontrols.currentPosition value).
Although image will be shown to user for 5seconds, value of "currentMedia.duration" equals to 0. Moreover you cannot set duration using setItemInfo to value you would like to.
Is there any way how to show image to user using AxWindowsMediaPlayer for eg. 37.5seconds? Is there any easy way how to change that interval for different images, or is it somewhere hard-coded constant?
I am sure that much better solution would be to use different components (eg. pictureBox and timer) but I am looking for solution using AxWindowsMediaPlayer. And I am sure that desired behavior could be done by changing current position for demanded period of time :-) - but I would like to avoid this.
Prereq: WinForms, .NET 4.0, WMP 12 for Windows 7
Thanks a lot
In PlayStateChange event handler detect 'newState == 3` (Playing).
After this, call wmp.Ctlcontrols.pause() and start timer. On timer.Tick event release paused media item.
To release pause call wmp.Ctlcontrols.play(), but be carrefull. This will trigger "newState == 3" again.
Also, timer interval should be substracted for 5 seconds, and you can't set slide to less than 5 seconds.
Sample bellow is not tested, but I implement something like this:
private System.Windows.Forms.Timer timer;
private void OnPlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
switch (e.newState)
{
case 3:
if (!timer.Enabled)
{
this.player.Ctlcontrols.pause();
this.timer.Interval = (37 - 5) * 1000; // 37 seconds
this.timer.Start();
}
break;
}
}
protected override void OnTimerTick(object sender, EventArgs e)
{
this.player.Ctlcontrols.play();
this.timer.Stop();
}

Categories

Resources