MonoGame Mediaplayer plays only one song - xna

I use:
MediaPlayer.Play(song1);
to play a song.
Then I use
MediaPlayer.Play(song2);
to play second song. But Mediaplayer still plays song1. I tried to stop player and play song2 again but it doesn't work. When I swap song1 and song2, it plays only song2.
Edit:
I have this class:
public class SoundHelper
{
public static void PlaySong(Song song)
{
MediaPlayer.Stop();
MediaPlayer.Play(song);
}
public static void StopSong()
{
MediaPlayer.Stop();
}
}
I use:
SoundHelper.PlaySong(Content.Load<Song>("Sounds/Songs/MenuTheme"));
to play song when game starts and it works.
Then I use:
SoundHelper.PlaySong(Content.Load<Song>("Sounds/Songs/Battle"));
to play next song in battle but then MenuTheme is played from beginning.

you have to stop playing current song
if (PlaySong1) {
MediaPlayer.Stop();
MediaPlayer.Play(Song1);
}
else{
MediaPlayer.Stop();
MediaPlayer.Play(Song2);
}
EDIT
you code looks fine, make sure that you call "SoundHelper" only once,
on loading menu or battle.
also try with "try" and "catch" on MediaPlayser.Stop() not sure, but
maybe will throw exception if no song is loaded.
it's better to load songs in your "loadcontent" instead.
song1 = Content.Load<Song>("song1"); song2 = Content.Load<Song>("song2");
also maybe adding MediaPlayer.IsRepeating = true; could be solve.
this is so far all i could remember.

Unfortunately it seems to be a bug in MonoGame. Had that same issue.
With version 3.3 your approach should work.

Related

How to stop currently playing audio automatically when another play button in different UITableView cells are pressed? - Swift

I am a swift beginner currently working on my first iOS app.
I have a TableViewController which has several cells and each cell contains a play button. When a few play buttons are pressed, a few different audios are played at the same time, but I would like to stop a currently playing audio when another playing play button is pressed.
Here are the sample codes I created.
Please give me an advice. Thank you so much!
The problem is that every single cell has its own independent player. You want just one player, so that you can stop it and start a new sound. For example, make the one player a property of the view controller. Every cell can see it but there is just one.
create an extension for AVPlayer because AVPlayer does not own condition for playing. extension given below.
extension AVPlayer {
var isPlaying: Bool {
return rate != 0 && error == nil
}
}
use it while tap on play like this.
if player?.isPlaying == true {
player?.pause()
player?.seek(to: CMTime(seconds: 0, preferredTimescale: 60))
}
//set up you audio file to player
player?.play()

Player-swift library, how to adjust playback rate

I am using the Player library https://github.com/piemonte/Player for video playback in my app.
I'm trying to figure out how to add the functionality to change the playback speed/rate of the video, like this: https://developer.apple.com/reference/avfoundation/avplayer/1388846-rate
I didn't see a playback function to allow this type of direct control in the Player docs.
Is there a way to change the "rate" of the underlying AVPlayer?
In this lib have the Player.swift, there you can access "_avplayer" variable that is a AVPlayer object..
You can make _avplayer public and access it from everywhere, or you can just make a getter and setter like:
open var rate: Float {
get {
return self._avplayer.rate
}
set {
self._avplayer.rate = newValue
}
}

Keep AVAudioPlayer sound in the memory

I use AVAudioPlayer to play a click sound if the user taps on a button.
Because there is a delay between the tap and the sound, I play the sound once in viewDidAppear with volume = 0
I found that if the user taps on the button within a time period the sound plays immediately, but after a certain time there is a delay between the tap and the sound in this case also.
It seems like in the first case the sound comes from cache of the initial play, and in the second case the app has to load the sound again.
Therefore now I play the sound every 2 seconds with volume = 0 and when the user actually taps on the button the sound comes right away.
My question is there a better approach for this?
My goal would be to keep the sound in cache within the whole lifetime of the app.
Thank you,
To avoid audio lag, use the .prepareToPlay() method of AVAudioPlayer.
Apple's Documentation on Prepare To Play
Calling this method preloads buffers and acquires the audio hardware
needed for playback, which minimizes the lag between calling the
play() method and the start of sound output.
If player is declared as an AVAudioPlayer then player.prepareToPlay() can be called to avoid the audio lag. Example code:
struct AudioPlayerManager {
var player: AVAudioPlayer? = AVAudioPlayer()
mutating func setupPlayer(soundName: String, soundType: SoundType) {
if let soundURL = Bundle.main.url(forResource: soundName, withExtension: soundType.rawValue) {
do {
player = try AVAudioPlayer(contentsOf: soundURL)
player?.prepareToPlay()
}
catch {
print(error.localizedDescription)
}
} else {
print("Sound file was missing, name is misspelled or wrong case.")
}
}
Then play() can be called with minimal lag:
player?.play()
If you save the pointer to AVAudioPlayer then your sound remains in memory and no other lag will occur.
First delay is caused by sound loading, so your 1st playback in viewDidAppear is right.

XNA MediaPlayer loading music timing

I load music with the following code in my load content function:
song = Content.Load<Song>("music/game");
MediaPlayer.IsRepeating = false;
MediaPlayer.Play(song);
nothing strange there, but each round in my game is 2 minutes long and should sync up with the music (that is 2 minutes long) but the music ends betweem 2-4s early. This wouldn't be a problem if it was always the same time.
My guess is that it has something to do with load times? any advice?
One thing you could do is move the Content.Load<Song> to Load method and check if it is playing in the update, and if not, play. Eg,
public void LoadContent(ConentManager content)
{
song = content.Load<Song>("music/game");
gameSongStartedPlaying = false; // this variable to hold if you have starting playing this song already
MediaPlayer.IsRepeating = false;
}
public void Update(GameTime gameTime)
{
if(MediaPlayer.State == MediaState.Stopped && !gameSongStartedPlaying)
{
MediaPlayer.Play(song);
gameSongStartedPlaying = true;
}
}
This should start playing the song on the first pass of the Update method rather than in the Loading phase where the song is 'playing' while all resources after Content.Load<Song> are still loading (this would be the reason your song finishes early).

XNA SOUND Playing problem

I am currently working on an XNA game, however when i command it to play a mp3 file it throws a DRM error when my file is not DRM protected. Can anyone explain to me why this is happening?
public class SoundEffects : GameComponent
{
private Song explosion;
private Song thunder;
public SoundEffects(Game game):base(game)
{
explosion = Game.Content.Load<Song>("explosion");
thunder = Game.Content.Load<Song>("thunder");
}
/*protected override void LoadContent()
{
explosion = Game.Content.Load<Song>("explosion"); // Put the name of your song in instead of "song_title"
thunder = Game.Content.Load<Song>("thunder"); // Put the name of your song in instead of "song_title"
}*/
public void playMusicThunder()
{
MediaPlayer.Play(thunder);
}
public void playMusicExplosion()
{
MediaPlayer.Play(this.explosion);
}
If you attempt to play a song file while the device is connected to the PC via Zune it will throw an exception (DRM). You can either test the game after disconnecting the device or instead of using Zune use the WPconnect tool (which I believe was in the October WPDT update)

Resources