i have a function that i use to stop or play the song like below:
class Utils(object):
def __init__(self):
self.paused = pygame.mixer.music.get_busy()
def ToggleAudio(self):
if self.paused:
pygame.mixer.music.unpause()
if not self.paused:
pygame.mixer.music.pause()
self.paused = not self.paused
then i have another one function that i use to set the song playing position if the user moves the trackbar:
def SetSongPos(self):
index = 0
currentsong = UTILS.CurrentSongname
for song in songs:
if song == currentsong:
MainPlayer.unload()
MainPlayer.load(song)
value = self.root.ids.track.value
MainPlayer.play(0,value)
PS(songs is the full list of mp3's paths).
when i call this function the mp3 audio toggler that is inside the class ToggleAudio stops working and when i press the stop button it stops the song for a sec then keep playing it
OK so I created this same project using Pygame in Tkinter 8 month ago .you can get reference from my project.
check code of m_player.py
I think in your case you have to stop your mixer before loading song
pygame.mixer.music.stop()
Then load mp3 file and then play your song
pygame.mixer.music.play()
and set self.paused to False
I can help better if you share your full code!
Related
I'm working on a tour in webvr and using a-frame to build it. I have a bizarre problem. I seem to be able to get aframe to play a video inside a videosphere and correctly display every second of it the first time I enter a new scene, but whenever I exit from it and try to enter it again, only the sound works as supposed. I'm wondering if I'm doing something wrong in the loading of the video or something
I'm collecting the path to the video from a json file in which I describe what each rooms contains (they may have interactable pins for 16:9 video, images and the sort, and also pins that simply load a new scene).
After loading the json, I set the source of the videosphere, name image360, as such:
document.getElementById("image360").setAttribute('src', "#" + jsonArray.zones[zoneID].locations[locationID].name);
I then play the video using the following code :
video = document.querySelector('#' + jsonArray.zones[zoneID].locations[locationID].name);
video.muted = false;
video.addEventListener("ended", videoEnded);
video.play();
The event listener I add to the video takes care of taking the user back to the previous scene once the video ends, which I do using this code:
//This function is called immediately after the end of a 360 video. Thus it first starts by obtaining the scene it should load after the end of the scene
var thisEl = document.querySelector('#' + jsonArray.zones[zoneID].locations[locationID].name);
var currentLocation = jsonArray.zones[zoneID].locations[locationID];
var locationToReturnTo = currentLocation.locationToReturnTo;
var zoneToReturnTo = currentLocation.zoneToReturnTo;
//With the information obtained, the room is then loaded
generateRoom(zoneToReturnTo, locationToReturnTo);
//After loading the room, time to generate the correct pins
generatePins(zoneToReturnTo, locationToReturnTo);
I'm truly at a loss here, and have no idea why this doesn't work. I should note that javascript and aframe are not my area of expertise at all, I just had to pick up this project after a former colleague of mine, who was working on it, left the company abruptly, so excuse me if I'm making a basic mistake.
Thanks in advance.
Switching videos directly on a entity may not work properly:
document.querySelector("a-video").setAttribute("src", "vid.mp4")
because of the current tmp <video> handling.
You should try using the assets management system:
<a-assets>
<video id="vid" src="derby.mp4"></video>
</a-assets>
<!-- Scene. -->
<a-plane src="#vid"></a-plane>
JS
(#vid).setAttribute("src", "newvid.mp4")
So, first of all, my overall goal is to play a different background music depending on where the player is on the map. I want one track to fade out and the other to fade in when the player reaches a certain point.
Here are my problems:
I've created a "Fader" class, with the help of Fade Between Two Music Tracks in-progress in Pygame. This allows me to fade tracks in and out, but it doesn't specify how to adapt the code to use pygame.mixer.music instead of pygame.mixer.Sound.
If I play both tracks as a Sound, on different Channels, the program slows wayyyyyy down - rendering it unusable. Research has shown that this is because music is played one bit at a time, while sounds are loaded in all at once and then played - which obviously takes quite a bit of processing power.
However, I can't seem to play them as music - and here we come to the heart of my problem. This is my Fader class written to play the music as a Sound:
class Fader(object):
def __init__(self, filename):
self.sound = pygame.mixer.Sound(filename)
# the speed at which it will fade
self.increment = 0.5
# the volume to which it will fade
self.next_vol = 1
def fade_to(self, new_vol):
self.next_vol = new_vol
curr_volume = self.get_volume()
if self.next_vol > curr_volume:
self.set_volume(curr_volume + self.increment)
elif self.next_vol < curr_volume:
self.sound.set_volume(curr_volume - self.increment)
This doesn't work, for reasons stated above. However, I cannot for the life of me achieve the same effect with music. The code written to play music as Music is the same except for line 3, which is now:
self.sound = pygame.mixer.music(filename)
I then get an error message saying "pygame.mixer.music is not callable." I understand that to mean that I'm not creating an object with that line, so I tried:
self.sound = pygame.mixer.music.load(filename)
...as I understood that to be the line that creates the Music object. However, here I get "NoneType object has no attribute 'play'" when I try to play the track.
I can't seem to figure this out, no one else seems to have this problem, and - go figure - the pygame website is down, so I can't look at the docs.
according to the documentation on https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.load
The pygame.mixer.music.load(filename) function loads the music stream into the mixer , and returns None
so to play the sound, replace
self.sound = pygame.mixer.music.load(filename)
with pygame.mixer.music.load(filename)
followed by pygame.mixer.music.play(filename)
I'm working on an animation that requires "Next" buttons at the end of each scene.
The movie resumes after the button is pressed. During the pause, I'd like the background music to pause as well. I've tried several solutions but none seemed to work.
I am using Flash Professional CS 5.5
Assume you are using "timeline" instead pure AS3.
At the start of whole project(MySound is your specified sound):
var position:Number = 0;
var mySound:Sound = new MySound();
var sc:SoundChannel;
When you start to play every scene(or press on resume button):
sc = mySound.play(position);
End of scene:
position = sc.position;
sc.stop();
When creating an AS3 project and adding audio what I usually do is drag the audio I want to use (for a game menu for example) and when I want to stop the audio I enter
SoundMixer.stopAll();
I do this because if I say go to the about game frame in this menu then I will have the audio, but if I come back to the main frame where I originally had the music it sorta doubles in and the two different timings of the music are playing at the same time.How do I stop this without having to disable the audio when I change frame?
In these cases, it is easier to start and stop the sound directly via code. First, right click the sound clip in your Library panel, and select Properties. In the ActionScript tab, check "Export for ActionScript", and give it a class name of, say, Music. Then, to play and stop this clip, you can use this code:
import flash.media.Sound;
// create the music Sound object so that we can start playing
var music : Sound = new Music();
var musicChannel : SoundChannel;
// play the music
// the play() method returns a SoundChannel,
// which you can later use to stop the music
// notice that we first check to make sure musicChannel is null
// if it isn't null, music is already playing, so don't play it twice
if(musicChannel != null) musicChannel = music.play();
// when you switch screens, stop the music
// clear out the channel, so that we know that it is safe to start the music again
musicChannel.stop();
musicChannel = null;
Alternatively, if you play music and sounds by placing them on the timeline, you can stop it by using the Sync setting of the frame. On the timeline, create a keyframe where you switch screens and want the music to stop playing. Select that frame, and drag the sound clip you want to stop onto that frame. In the Properties panel, change the Sync option to Stop. This will cause only the selected sound to stop playing.
Yet another method is to create an empty MovieClip with the sound placed inside of it. Change the Sync setting to Stream, and pad the clip out with empty frames so that it will play the entire clip. Then, if you place this clip on your main menu screen, then it will only play during the main menu. Stream sounds only play the sound for as long as the MovieClip exists and is playing. Compare this to normal Event sounds, which will play the entire sound regardless.
The latter methods are more old-school and movie-centric. If you are programming a game, it would be more appropriate to use the former method to give you more control of the audio in code.
My question is, how to pause the audio in "scene 1" and have it so that when you go to "scene 3" (which has a different audio file attached that is going to be played) it still has the audio in general muted but when you click on the "on" button it plays the respective song of the scene, kind of like how in games you can mute the music at the main menu but then unmute it throughout gameplay;
Also in general how would I go about making a play/pause button (I am assuming an "if else" statement might work but not sure)
This really depends on whether you want to actually PAUSE the audio, STOP the audio, or just MUTE the audio. Each has a different use.
However, for your usage, it sounds like you'll want to use a "mute" button. There are, I'm sure, a number of ways to do this. What I recommend is creating an AS3 class specifically for audio. Then, you'll want to set up this class inside of your document class.
Go to File --> New... and select ActionScript 3.0 Class. Name it "gamesounds.as". Before you click save, create a new folder in the same directory as your .fla. Name this folder "gamecore", and then save "gamesounds.as" inside of it. The reason I just did that is, you'll want to keep all your custom classes of this sort together.
Now, here's the basic structure for your class:
package gamecore
{
public class GameSounds
{
//constructor code
}
}
Before we do anything else, we need to ensure that our game will be able to access this class. We don't want to be creating a million copies, because that will undermine the class' primary functionality. Open up your document class (Making a new document class is outside the scope of this answer. Look it up.) Of course, the document class must be in the same directory as the gamecore folder (NOT IN the gamecore folder).
Above the class declaration in the document class, enter this line of code:
import gamecore.GameSounds;
Then, inside your class declaration, enter this line:
public static var GameSounds:GameSounds = new GameSounds();
Save, obviously, and then go back to your gamesounds.as file. Here's the code you'll want to use. I've added comments to illustrate what the different code does.
I'm assuming you've imported all your songs into your .fla's library, and created their actionscript bindings. You can modify this for playing songs externally, too, though I won't go into that here.
The following should replace //constructor code
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
//Create a variable to indicate whether the music is muted.
var isMuted:Boolean = false;
/*Create a string variable for the name of the song that should be playing. Alternatively, you could just name this an int and store the scene number. It all depends on what you want to do.*/
var songName:String;
//Create a sound channel for playing audio.
var musicChannel:SoundChannel = new SoundChannel();
//Import your songs.
var fooForYou:Sound = new fooForYou();
var iveBeenAFoo:Sound = new iveBeenAFoo();
var pityTheFoo:Sound = new pityTheFoo();
/*This function sets the target song based on location. Just pass it the integer of the stage. Alternatively, you can make this work with the stage name as a String.*/
function startMusic(targetScene:int):void
{
/*Depending on the targetScene number, set the correct song name. Note these match the song declarations above.*/
switch(targetScene)
{
case 1:
songName = "fooForYou";
break;
case 2:
songName = "iveBeenAFoo";
break;
case 3:
songName = "pityTheFoo;
break;
}
//Start the actual music playing.
playMusic();
}
/*This function starts the music itself. Keep it separate, in case you need to bypass the startMusic code for some reason.*/
function playMusic():void
{
//I'd imagine you want your music looped, so int.MAX_VALUE accommodates for that.
musicChannel = this[songName].play(0, int.MAX_VALUE);
//Mute or unmute depending on that variable above.
adjustVolume();
}
//This function mutes or unmutes depending on the variable condition.
function adjustVolume():void
{
//We create a SoundTransform.
var transform:SoundTransform = musicChannel.soundTransform;
//We set the volume to 0 or 1, depending on the isMuted variable.
if(isMuted)
{
transform.volume = 0;
}
else
{
transform.volume = 1;
}
//We apply the transform to the song.
musicChannel.soundTransform = transform;
}
/*This function is present for convenience's sake. Calling this adjusts the variable AND the music that is currently playing.*/
function setMute(mute:Boolean):void
{
//Sets the isMuted variable to the mute argument.
isMuted = mute;
//Mutes or unmutes the currently playing sound.
adjustVolume();
}
Now, you only need to use two functions in your .fla itself. I'm going to assume that "DocClass" is the name of your document class. At the start of every stage, call this line of code, replacing the "1" in the argument with the stage number (or name, if you've opted for that route.)
DocClass.GameSounds.startMusic(1);
It will start the music in effect, but it can only be heard if the music isn't set to be muted.
Add this code to your mute button to mute, replacing "true" with "false" to unmute.
DocClass.GameSounds.setMute(true);
--
In regards to the pause button, this question should be asked separately. I will tell you that if you intend to loop your music, pausing it when using SoundChannel is going to create an issue for ya, in that the music will loop from the point it was last paused.
I hope that's helpful to you! I've been using that sort of code for over a year now in my project, and I've never had a problem with it.
First include the SoundMixer class:
import flash.media.SoundMixer;
Then to stop the sounds call the stopAll method:
SoundMixer.stopAll();