MediaElement doesn't play sound effect - c#

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.

Related

C# gif medialement how to change position

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.

Sharpdx tookit input won't work with windows 10 universal apps

I'm trying out sharpdx tookit with universal app in windows 10 and can't get the input to work. I know I have to create different input for different devices but for now I just want to try keyboard.
So I follow this link first to set up the project: Is there a SharpDx Template, for a Windows Universal App?
And right now I'm trying input like I usually do it:
In the constuctor:
_keyboardManager = new KeyboardManager(this);
In the update method:
var state = _keyboardManager.GetState();
if (state.IsKeyDown(Keys.B))
{
//do stuff
}
But he never register that the key B is down (or any other key I have tried). I have also tried GetDownKeys() but the list is always empty.
So does any one have any idea what to do here?
And there's an another, better, easier version:
using Windows.UI.Core;
using SharpDX.Toolkit;
using Windows.System;
namespace Example
{
class MyGame : Game
{
public MyGame()
{
CoreWindow.GetForCurrentThread().KeyDown += MyGame_KeyDown;
}
void MyGame_KeyDown(CoreWindow sender, KeyEventArgs args)
{
System.Diagnostics.Debug.WriteLine(args.VirtualKey);
}
}
}
You have to subscribe to the CoreWindow's event, that's it :)
HEUREKA!
I had the same problem, but with windows 8.1. It took me 2 days to find a solution. It's the foolish SwapChainPanel, which can't be in focus because the class doesn't inherit from Control class, so it won't handle keyboard events.
The solution is HERE that is to say, you have to put an XAML element that's inherited from the Control class, like Button to handle the event. My XAML file is like this:
<SwapChainPanel x:Name="_swapChainPanel"
Loaded="_swapChainPanel_Loaded"
KeyDown="_swapChainPanel_KeyDown">
<Button x:Name="_swapChainButton"
Content="Button"
HorizontalAlignment="Left"
Height="0"
VerticalAlignment="Top"
Width="0"
KeyDown="_swapChainButton_KeyDown">
</Button>
</SwapChainPanel>
In the XAML.cs I handled the events this way:
private void _swapChainButton_KeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
e.Handled = false; //This will pass the event to its parent, which is the _swapChainPanel
}
private void _swapChainPanel_KeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
game.KeyboardEvent();
}
In the KeyboardEvent() method I put the if things... and you have to make the button in focus manually, with code. "_swapChainButton.Focus(FocusState.Programmatic);"
But last, it's not so good for me, it's so slow. It has delay. :/

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

Does form.onload exist in WPF?

I would like to run some code onload of a form in WPF. Is it possible to do this? I am not able to find where to write code for form onload.
Judging by the responses below it seems like what I am asking is not something that is typically done in WPF? In Vb.Net winforms it is easy, you just go to the onload event and add the code that you need ran on load. For whatever reason, in C# WPF it seem very difficult or there is no standard way to do this. Can someone please tell me what is the best way to do this?
You can subscribe to the Window's Loaded event and do your work in the event handler:
public MyWindow()
{
Loaded += MyWindow_Loaded;
}
private void MyWindow_Loaded(object sender, RoutedEventArgs e)
{
// do work here
}
Alternatively, depending on your scenario, you may be able to do your work in OnInitialized instead. See the Loaded event docs for a discussion of the difference between the two.
Use the Loaded event of the Window. You can configure this in the XAML like below:
<Window x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Your App" Loaded="Window_Loaded">
Here is what the Window_Loaded event would look like:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// do stuff
}
This question was asked 4 years ago, but this answer may help others too so here goes -->
To do it simply and quickly - down and dirty, put the code you want to run in a method in the code-behind. then simply call the method before the MainWindow() InitializeComponent(). This poses dangers, but most times it works because the components are loaded before window initiation/display.
(This is working code from one of my projects.)
Let's say you want to play a short wave file when the app fires up. It would look like this;
using ...
using System.Windows.Media;
namespace yourNamespace_Name
{
/// sumary >
/// Interaction logic for MainWindow.xaml
/// /sumary>
public partial class MainWindow : System.Windows.Window
{
public MainWindow()
{
/*call your pre-written method w/ all the code you wish to
* run on project load. It is wise to set the method access
* modifier to 'private' so as to minimize security risks.*/
playTada();
InitializeComponent();
}
private void playTada()
{
var player = new System.Media.SoundPlayer();
player.Stream = Properties.Resources.tada;
// add the waveFile to resources, the easiest way is to copy the file to
// the desktop, resize the IDE window so the file is visible, right
// click the Project in the solution explorer & select properties, click
// the resources tab, & drag and drop the wave file into the resources
// window. Then just reference it in the method.
// for example: "player.Stream = Properties.Resources.tada;"
player.Play();
//add garbage collection before initialization of main window
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}
Hope this helps those that are searching. :-)
Loaded event is raised after project is build. To do stuff before, you can ovveride OnStartup method in App.xaml.cs.
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
//...
base.OnStartup(e);
}
}

Silverlight media player

I am using VSTS 2008 with C# to develop Silverlight application embedded in web page of an ASP.Net web application. I have embedded in XAML a MediaElement item. My question is, I want to embed the page a Silverlight media player, which could let end user to control the MediaElement item manually to -- play/pause/stop/rewind/forward. Are there any references samples?
thanks in advance,
George
EDIT1: add more accurate requirements,
Actually, I want to control play manually, which means I want to handle the player play/pause/stop/rewind/forward events and add my code for the event handlers to control the MediaElement and do something else.
EDIT2: My needs are, I want to play two overlapped video. Screen as background video and camera as foreground video (place at right bottom corner). Here is my modification of code, my current issue is, only background video is played, foreground right bottom video is never played. Does anyone have any ideas why?
BTW: my modified code and current work is based on http://www.codeplex.com/sl2videoplayer
http://www.yourfilehost.com/media.php?cat=other&file=sl2videoplayer_24325_new.zip
Here is a brief description of my major modified code,
mediaControls.xaml.cs
private MediaElement _media = null;
private MediaElement _camera = null;
public MediaElement Camera
{
set
{
_camera = value;
}
}
void btnPlay_Checked(object sender, RoutedEventArgs e)
{
_camera.Play();
_media.Play();
OnPlayClicked();
}
Page.xaml
<MediaElement HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="mediaPlayer" Stretch="Uniform" VerticalAlignment="Stretch" AutoPlay="false"/>
<MediaElement Width="100" Height="100" x:Name="cameraPlayer" AutoPlay="false" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
Page.xaml.cs
cameraPlayer.Source = App.Current.Resources["c"] as Uri;
App.xaml.cs (Application_Startup function)
else if (item.Key.ToLower() == "c")
{
FormatUri(e.InitParams["c"].ToString(), "c", false);
}
default.html
<param name="initParams" value="cc=true,markers=true,markerpath=markers_movie21.xml,m=http://localhost/screen.wmv,c=http://localhost/camera.wmv" />
Oh baby have I got the media player for you: Sl2 Video Player. MSPL open sourced and awesome.
To add the ability to control the player pragmatically, add ScriptableMembers.
You'll see the registration statement already in the code:
HtmlPage.RegisterScriptableObject("Page", page);
Now look at an example ScriptableMember:
[ScriptableMember]
public void SeekPlayback(string time)
{
TimeSpan tsTime = TimeSpan.Parse(time);
mediaControls.Seek(tsTime);
}
already exists in the code. Add more methods to do what you want to have happen. Then you can call the methods from managed code in another SL player:
HtmlElement videoPlugin = HtmlPage.Document.GetElementById("VideoPlayer");
if (videoPlugin != null)
{
ScriptObject mediaPlayer = (ScriptObject)((ScriptObject)videoPlugin.GetProperty("Content")).GetProperty("Page");
mediaPlayer.Invoke("SeekPlayback", TimeSpan.FromSeconds(seconds).ToString());
}
or from javascript:
var sl = document.getElementById("VideoPlayer");
var content = sl.Content.Page;
content.SeekPlayback('55');
If they are two seperate xap packages, there will be no way for the two to communicate since Silverlight sandboxes both individually.
SL2videoplayer says it supports streaming video. But when I try giving a media services broadcast url (OnDemand and Live) to init param 'm' nothing showed up. In the init param example page also a remote wmv file being played is shown.
Also are there any known issues of using this with SL 3?

Categories

Resources