- Home /
The question is answered, right answer was accepted
Why Music Player Pause and Stop Buttons Do Not Work As They Should
I have this music player script that when it plays the next song from the music folder it makes my Pause and stop buttons not work quite right. wondering if anyone can take a look and see why?
UPDATE: I updated the script The main problem is solved now. Now the Stop and Pause buttons are functioning the way they should. What a pain in the you know what, all day to do something that should have taken 5 minutes. Gee thankx :/
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEngine.UI;
public class AltMusicPlayer : MonoBehaviour {
public Text MusicListText;// Reference to my UI Display Text for Songs
private string display = "";//NEW Delete if does not work!!
public enum SeekDirection { Forward, Backward }
public AudioSource source;
bool playing = true;
public List<AudioClip> clips = new List<AudioClip>();
[SerializeField] [HideInInspector] private int currentIndex = 0;
private FileInfo[] soundFiles;
private List<string> validExtensions = new List<string> { ".ogg", ".wav" }; // Don't forget the "." i.e. "ogg" won't work - cause Path.GetExtension(filePath) will return .ext, not just ext.
private string absolutePath = "./Audio/Music"; // relative path to where the app is running - change this to "./music" in your case
void Start()
{
//being able to test in unity
if (Application.isEditor)
absolutePath = "Assets/Audio/Music";
if (source == null)
source = gameObject.AddComponent<AudioSource> ();
ReloadSounds ();
}
void Update(){
if(!source.isPlaying && playing)
{
Seek(SeekDirection.Forward);
PlayCurrent();
}
}
//My New UI Buttons Added
public void PlayPrevious (){
Seek(SeekDirection.Backward);
PlayCurrent();
}
public void PlayCurrentClip () {
PlayCurrent();
playing = true;
}
public void PlayNext () {
Seek(SeekDirection.Forward);
PlayCurrent();
}
public void ReloadAudio () {
ReloadSounds();
}
public void StopAudio () {
source.Stop ();
playing = false;
}
public void PauseAudio () {
source.Pause ();
playing = false;
}
void Shuffle()
{
//Shuffle or Randomize Songs in Array List
//ShuffleMusic();
}
//End My New UI Buttons Added
void Seek(SeekDirection d)
{
if (d == SeekDirection.Forward)
currentIndex = (currentIndex + 1) % clips.Count;
else {
currentIndex--;
if (currentIndex < 0) currentIndex = clips.Count - 1;
}
}
void PlayCurrent()
{
source.clip = clips[currentIndex];
source.Play();
Debug.Log (source.clip);
MusicListText.text = clips[currentIndex].name;
}
void ReloadSounds()
{
clips.Clear();
// get all valid files
var info = new DirectoryInfo(absolutePath);
soundFiles = info.GetFiles()
.Where(f => IsValidFileType(f.Name))
.ToArray();
// and load them
foreach (var s in soundFiles)
StartCoroutine(LoadFile(s.FullName));
}
bool IsValidFileType(string fileName)
{
return validExtensions.Contains(Path.GetExtension(fileName));
// Alternatively, you could go fileName.SubString(fileName.LastIndexOf('.') + 1); that way you don't need the '.' when you add your extensions
}
IEnumerator LoadFile(string path)
{
WWW www = new WWW("file://" + path);
print("loading " + path);
AudioClip clip = www.GetAudioClip(false);
while(!clip.isReadyToPlay)
yield return www;
print("done loading");
clip.name = Path.GetFileName(path);
clips.Add(clip);
//Count Array List Length
//source.clip = clips[currentIndex];
Debug.Log (clip);
//int List = clips.Count;
//Debug.Log (List);
}
//NEW
void AddText()
{
display = currentIndex + " : " + clips[currentIndex].name;
MusicListText.text = display;
}
//END NEW
//Quit Button
public void GoQuit(){
StartCoroutine(LoadQuit("MainScreen"));
}
IEnumerator LoadQuit(string levelMain){
yield return new WaitForSeconds(0.5f); // wait time
Application.LoadLevel(levelMain);
}
}
Answer by callen · Dec 10, 2015 at 07:21 PM
I can't tell where these functions are all being called (I'm guessing a UI front-end hooks into it), but you should be able to have the player continue to the next song by adding this method to the script:
void Update(){
if(!source.isPlaying)
{
Seek(SeekDirection.Forward);
PlayCurrent();
}
}
@callen, Oh for crying out loud, lol that was all it needed, jeepers I had posted this blasted script a number of times and no one fielded this one... you got it, it works.
Only wird thing with it now is that the stop button does not completely stop the music? just kind of stops it momentarily and then it starts again?
Oh yeah, I didn't consider that! I dont actually see the code in here that is stopping the music, so I'm guessing that could have been done with a UI event directly calling the source.Stop() method.
There are a few ways to fix it, one would be tracking an internal 'playing' state yourself. To do this you'd need a bool playing variable, and to add your own void Stop$$anonymous$$usic() method (which you have to hook up to the stop button in ui!). In the Stop$$anonymous$$usic method, set playing=false and call source.Stop(); in the PlayCurrent method, set playing=true; finally in the Update() loop change the condition to "if(!source.isPlaying && playing)"
Another (possibly easier) way to fix it, without writing any more code, is to make these changes: Stop button - ins$$anonymous$$d of calling AudioSource.Stop(), call AudioSource.enabled=false Play button - keep calling your PlayCurrent method, but ALSO add a callback to set AudioSource.enabled=true
Hope that makes sense!
@callen, $$anonymous$$akes a little sense. I tried using the UI buttons to call Audio stop but I think with the update function it just makes it interrupt momentarily. I also tried adding the bool for source = false; but that just gave me weird results?
Answer by KnightRiderGuy · Dec 10, 2015 at 09:29 PM
Just for the heck of it I'll add the slightly modified script in @callen so you can see the changes. It's working better but still a little goofy. Oh just in case I didn't mention it the button are on a UI canvas. ;)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine.UI;
public class AltMusicPlayer : MonoBehaviour
{
public Text MusicListText;// Reference to my UI Display Text for Songs
private string display = "";//NEW Delete if does not work!!
public enum SeekDirection { Forward, Backward }
public AudioSource source;
bool playing = true;
public List<AudioClip> clips = new List<AudioClip>();
[SerializeField] [HideInInspector] private int currentIndex = 0;
private FileInfo[] soundFiles;
private List<string> validExtensions = new List<string> { ".ogg", ".wav" }; // Don't forget the "." i.e. "ogg" won't work - cause Path.GetExtension(filePath) will return .ext, not just ext.
private string absolutePath = "./Audio/Music"; // relative path to where the app is running - change this to "./music" in your case
void Start()
{
//being able to test in unity
if (Application.isEditor)
absolutePath = "Assets/Audio/Music";
if (source == null)
source = gameObject.AddComponent<AudioSource> ();
ReloadSounds ();
}
void Update(){
if(!source.isPlaying && playing)
{
Seek(SeekDirection.Forward);
PlayCurrent();
}
}
//My New UI Buttons Added
public void PlayPrevious (){
Seek(SeekDirection.Backward);
PlayCurrent();
}
public void PlayCurrentClip () {
PlayCurrent();
playing = true;
}
public void PlayNext () {
Seek(SeekDirection.Forward);
PlayCurrent();
}
public void ReloadAudio () {
ReloadSounds();
}
public void StopAudio () {
playing = false;
}
void Shuffle()
{
//Shuffle or Randomize Songs in Array List
//ShuffleMusic();
}
//End My New UI Buttons Added
void Seek(SeekDirection d)
{
if (d == SeekDirection.Forward)
currentIndex = (currentIndex + 1) % clips.Count;
else {
currentIndex--;
if (currentIndex < 0) currentIndex = clips.Count - 1;
}
}
void PlayCurrent()
{
source.clip = clips[currentIndex];
source.Play();
Debug.Log (source.clip);
MusicListText.text = clips[currentIndex].name;
}
void ReloadSounds()
{
clips.Clear();
// get all valid files
var info = new DirectoryInfo(absolutePath);
soundFiles = info.GetFiles()
.Where(f => IsValidFileType(f.Name))
.ToArray();
// and load them
foreach (var s in soundFiles)
StartCoroutine(LoadFile(s.FullName));
}
bool IsValidFileType(string fileName)
{
return validExtensions.Contains(Path.GetExtension(fileName));
// Alternatively, you could go fileName.SubString(fileName.LastIndexOf('.') + 1); that way you don't need the '.' when you add your extensions
}
IEnumerator LoadFile(string path)
{
WWW www = new WWW("file://" + path);
print("loading " + path);
AudioClip clip = www.GetAudioClip(false);
while(!clip.isReadyToPlay)
yield return www;
print("done loading");
clip.name = Path.GetFileName(path);
clips.Add(clip);
//Count Array List Length
//source.clip = clips[currentIndex];
Debug.Log (clip);
//int List = clips.Count;
//Debug.Log (List);
}
//NEW
void AddText()
{
display = currentIndex + " : " + clips[currentIndex].name;
MusicListText.text = display;
}
//END NEW
//Quit Button
public void GoQuit(){
StartCoroutine(LoadQuit("MainScreen"));
}
IEnumerator LoadQuit(string levelMain){
yield return new WaitForSeconds(0.5f); // wait time
Application.LoadLevel(levelMain);
}
}
Follow this Question
Related Questions
How can I play audio clips depending on the players movement 0 Answers
Trigger audio loop on beat with PlayScheduled 1 Answer
Can not play a disabled audio source 2 Answers
How to play music/audio 2 Answers