I am creating a WP7 application that requires various sound effects to be played (on button press) over looped background music. The background music is initiated by pressing Button 1 and loops fine. When I press button3 (triggers a sound effect), the sound effect overlays on the background music fine on first press. However, when I press button3 again, the background music stops. I cannot figure out why this might be happening!? I have pasted the relevant portions of code below. Would appreciate any help.
public partial class MainPage : PhoneApplicationPage
{
SoundEffect soundEffect;
Stream soundfile;
// Constructor
public MainPage()
{
InitializeComponent();
}
static protected void LoopClip(SoundEffect soundEffect)
{
{
SoundEffectInstance instance = soundEffect.CreateInstance();
instance.IsLooped = true;
FrameworkDispatcher.Update();
instance.Play();
}
}
public void PlaySound(string soundFile)
{
using (var stream = TitleContainer.OpenStream(soundFile))
{
var effect = SoundEffect.FromStream(stream);
effect.Play();
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
soundfile = TitleContainer.OpenStream("BackgroundMusic.wav");
soundEffect = SoundEffect.FromStream(soundfile);
LoopClip(soundEffect);
}
private void button3_Click(object sender, RoutedEventArgs e)
{
PlaySound("sound3.wav");
}
}
}
This should work if you are always working with Instances so change your code to this and it should clear up the problem:
public partial class MainPage : PhoneApplicationPage
{
SoundEffectInstance loopedSound = null;
// Constructor
public MainPage()
{
InitializeComponent();
}
static protected void LoopClip(SoundEffect soundEffect)
{
loopedSound = soundEffect.CreateInstance();
loopedSound.IsLooped = true;
loopedSound.Play();
}
public void PlaySound(string soundFile)
{
SoundEffect sound = SoundEffect.FromStream(Application.GetResourceStream(new Uri(soundFile, UriKind.Relative)).Stream);
SoundEffectInstance instance = sound.CreateInstance();
instance.Play();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
SoundEffect sound = SoundEffect.FromStream(Application.GetResourceStream(new Uri(#"BackgroundMusic.wav", UriKind.Relative)).Stream);
LoopClip(sound);
}
private void button3_Click(object sender, RoutedEventArgs e)
{
PlaySound("sound3.wav");
}
}
The above example assumes your sound files are set with Build Action = Content and are in the top level directory.
You will need to play each sound from a separate thread.
What seems to be happening here is that the different Play method calls are interfering with each other since they are in the same thread.
Try just putting the background music in a separate thread and see if that solves the problem you mention in the question. If so, split the others out as well.
Related
Attached is a screenshot as well as the code. There isn't much of it.
When I first open the window, everything is rendered with an offset.
If I close the window and reopen it, it renders correctly the second time.
public partial class frmTwinklyLogin : Form
{
public ChromiumWebBrowser webBrowser;
public frmTwinklyLogin()
{
InitializeComponent();
InitializeBrowser();
}
private void frmTwinklyLogin_Load(object sender, EventArgs e)
{
}
private void InitializeBrowser()
{
webBrowser = new ChromiumWebBrowser("https://api.twinkly.com/v2/auth/login?response_type=code&client_id=omen-hp-client&redirect_uri=http://localhost:8487/login");
webBrowser.AddressChanged += Browser_AddressChanged;
this.Controls.Add(webBrowser);
webBrowser.Dock = DockStyle.Fill;
webBrowser.Refresh();
}
private void Browser_AddressChanged(object sender, AddressChangedEventArgs e)
{
var x = e.Address;
if (x.Contains("code="))
{
var code = x.Split('=')[1];
TwinklyWebApi.SetCode(code);
}
}
}
and the initialization of the library is in application load.
static void Main()
{
CefSettings settings = new CefSettings();
Cef.Initialize(settings);
I can only assume I've got something in the wrong event. Either that or my monitor dpi is screwing with it. Note: It's merely rendered off-center. The click areas for the controls are still where they are supposed to be, which makes the page unusable.
I have a button that when clicked, changes its background image and opens another Form. I want that this background image changes again when I close the 2nd form (Cam) clicking on the X cross at the right corner. How can I do that? Should I use FormClosed() or FormClosing() events? Thank you.
private void CamBox1btn_Click(object sender, EventArgs e)
{
Camera Cam = new Camera();
if (bln)
{
CamBox1btn.Image = imageList1.Images[10];
Cam.ShowDialog();
}
else
{
CamBox1btn.Image = imageList1.Images[8];
}
bln = !bln;
}
Form 1:
private void CamBox1btn_Click(object sender, EventArgs e)
{
Camera Cam = new Camera();
if (Cam_bln)
{
CamBox1btn.BackgroundImage = Properties.Resources.Camera_button_ON;
Cam.eventForm += new ShowFrm(backgroundcolor_change_CAM);
Cam.ShowDialog();
}
else
{
CamBox1btn.BackgroundImage = Properties.Resources.Camera_button_OFF;
}
Cam_bln = !Cam_bln;
}
void backgroundcolor_change_CAM()
{
Cam_bln = false;
CamBox1btn.BackgroundImage = Properties.Resources.Camera_button_OFF;
}
Form2:
public delegate void ShowFrm();
public partial class Camera : Form
{
public event ShowFrm eventForm;
private void Camera_FormClosing(object sender, FormClosingEventArgs e)
{
eventForm?.Invoke();
}
}
I want to use MediaPlayer class to play .flv file int UWP app. Here are some test code is't very easy, but it doesn't work. If I play .mp4 file, it's OK, what have to do to play .flv file?
namespace mediaPlayer
{
public sealed partial class MainPage : Page
{
private MediaPlayer player = null;
public MainPage()
{
this.InitializeComponent();
}
private void Start_Click(object sender, RoutedEventArgs e)
{
mediaPlayer.Source = MediaSource.CreateFromUri(new Uri("http://10.160.72.72/vod/1987.flv "));
player = mediaPlayer.MediaPlayer;
player.Play();
}
private void Pause_Click(object sender, RoutedEventArgs e)
{
player.Pause();
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
player.Dispose();
}
}
}
I don't think it's possible. MediaPlayer can't play .flv format. Read this link:
I would suggest you convert it to different format: https://msdn.microsoft.com/en-us/library/windows/apps/hh986969.aspx
One possible way is this Player Framework. Haven't tried it out, but it should play .flv format.
Hope it helps!
You could use FFMpegInterop. It isn't easy to set up but the Github page for it and articles online could help you get it up and running, I used it for a project in the past and it has worked for me.
I want to make 2 button. 1 of them to play music and another one to stop the music. But i make just the first one. How i make the stop music button ?
private void Play()
{
string soundfile = #"D:\song.wav";
var sound = new System.Media.SoundPlayer(soundfile);
sound.Play();
}
private void button1_Click(object sender, EventArgs e)
{
Play();
}
The SoundPlayer class you're using has a method to stop playback, just like it has Play. The problem is that you're not storing the instance of SoundPlayer that's playing, so you don't have a reference to it.
Try storing the sound variable as a class-level member. Then you can call it from a different method as well:
private SoundPlayer _player;
private void Play()
{
string soundFile = #"D:\Song.wav";
_player = new System.Media.SoundPlayer(soundFile);
_player.Play();
}
private void Stop()
{
if (_player != null)
{
_player.Stop();
}
}
This way the SoundPlayer is a shared member for all class methods. Note, though, the != null check, which makes sure that calling Stop before Play won't crash.
I have 2 custom controls in my silverlight application and each one is having its own animations. I want to play all of the animations in order but when they play at the same time, the animations are not playing properly. How can I put some delay between them?
private void button1_Click(object sender, RoutedEventArgs e)
{
Dispatcher.BeginInvoke(() => {
myCustomControl1.Play();
Thread.Sleep(200);
Dispatcher.BeginInvoke(() => { myCustomControl2.Play(); });
}
I'm assuming your controls are using a StoryBoard to play the animations. StoryBoard has a "Completed" event that fires after it completes running. So, you could do something like:
public class CustomControl:Control
{
public override void ApplyTemplate()
{
_storyBoard=GetTemplateChild("AnimationStoryBoard") as Storyboard;
_storyBoard.Completed+=OnCompleted;
}
public event eventhandler AnimationCompleted;
public void Play()
{
_storyBoard.Begin();
}
private void OnCompleted(object sender, EventArgs args)
{
if(AnimationCompleted!=null)
AnimationCompleted(this,EventArg.Empty);
}
}
What you can then do is chain your animations together:
myCustomControl1.AnimationCompleted+=RunSecondAnimation;
myCustomControl1.Play();
private void RunSecondAnimation(object sender, EventArgs args)
{
myCustomControl2.Play();
}
Now we can guarantee that animation 2 will always happen after animation 1.