音乐播放器的实现(三)---进度条控制、播放、暂停、上(下)一曲、播放时间和总时间显示

音乐播放器的实现(三)---进度条控制、播放、暂停、上(下)一曲、播放时间和总时间显示

传送门:(完整工程见第五章篇尾)

音乐播放器的实现(一)-- Audio Listener和Audio Source面板的介绍

音乐播放器的实现(二)---UI面板的制作

音乐播放器的实现(四)—— 歌曲列表、顺序播放、单曲循环、随机播放、自动下一曲

音乐播放器的实现(五)—— 音量的加减和静音 

设计好面板,接下来就开始进行后台代码的编写了。

在Unity3D中的Project面板单机鼠标右键, Create—>C# Script,命名为Player,然后双击打开,进行编写。

核心代码讲解:

1.在Start方法中通过按钮名给各个按钮以及进度条加上监听,实现各个按钮的点击,每当拖拽或点击进度条(进度条的value值改变),音频就会播放到相应位置。

(2021.1.25更)

有一个兄弟提出这个方式播放时有滋滋啦啦的声音(在此感谢这位小哥[抱拳])

他也给我分享了原因,经检测后证实确实有这样的Bug,所以我对代码做出了一些修改(下面代码均为修改过后的,请放心!)

void Start()
    {
         _instance = this;

        aus.Stop();                                                 //开始运行时不播放,点播放键才开始播放

        #region 注:该方式虽然可以直接达到拖动进度条就播放到进度条当前的音乐,但会产生滋滋啦啦的杂音,是因为进度条value变化,使之不断调用onValueChanged,从而让音乐的进度发生了变化,音乐前后颠倒,不断重叠
        ///
        /// 所以新建了个DragSlider脚本,挂在进度条上,来实现拖动播放的效果
        ///
        //slid.onValueChanged.AddListener(delegate
        //{
        //    //加上之后,避免拖动进度条到最后不松手时报错
        //    if (slid.value == 1)
        //        return;
        //    //给进度条添加事件监听,每当拖动进度条,歌曲从相应的位置播放
        //    aus.time = slid.value * aus.clip.length;
        //});
        #endregion

        foreach (Transform go in buttons)                           //遍历所有的操作按钮
        {
            go.GetComponent<Button>().onClick.AddListener(delegate  //根据按钮名给按钮添加事件监听
            {
                switch (go.name)
                {
                    case "lastM":       //点击“上一曲”按钮
                        LastMusic();
                        break;
                    case "pause":       //点击“暂停”按钮
                        Pause();
                        break;
                    case "play":        //点击“播放”按钮
                        Play();
                        break;
                    case "nextM":       //点击“下一曲”按钮
                        NextMusic();
                        break;
                }
            });
        }
	}

2.获取当前播放的音频的总时间,并显示在面板。

 void alltime()//歌曲总时间
    {
        //slid.value = 0;
        clipHour = (int)aus.clip.length / 3600;//时
        clipMinute = (int)(aus.clip.length - clipHour * 3600) / 60;//分
        clipSecond = (int)(aus.clip.length - clipHour * 3600 - clipMinute * 60);//秒
        //显示歌曲总时间
        allTime.text = string.Format("{0:D2}:{1:D2}:{2:D2}",
            clipHour, clipMinute, clipSecond);
    }

3.获取当前播放音频的已播放时间,并显示在面板,进度条跟着变化,表示进程。

void nowtime()//当前播放过的时间
    {
        currentHour = (int)aus.time / 3600; //时
        currentMinute = (int)(aus.time - currentHour * 3600) / 60;//分
        currentSecond = (int)(aus.time - currentHour * 3600 - currentMinute * 60);//秒
                                                                                  
        //显示当前播放过的时间
        nowTime.text = string.Format("{0:D2}:{1:D2}:{2:D2} ",
            currentHour, currentMinute, currentSecond);
        //进度条变化
        //(之后更新版)如果当前没有拖拽进度条
        if(!DragSlider.isDrag)
            slid.value = aus.time / aus.clip.length;
    }

4.显示当前正在播放的音频

void nowMusic()                     //当前的音频
    {
        AudioClip clip = aus.clip;      //当前播放的音频
        string n = aus.clip.name;       //当前播放的音频的名字
        string[] na = n.Split('-');     //以“-”为分割点,把音频名分为若干部分

        //显示当前正在播放的歌曲的名字【歌曲名(默认字体,25号)+歌手名(默认字体,18号,红色)的形式】
        musicName.text = string.Format("<size=25>{0}</size>" + "\n<size=18><color=#FF0000FF>{1}</color></size>", na[0], na[1]);

        index = Array.IndexOf(auc, clip);//当前播放的音频在aus数组中的索引
        Slider();                        //当进度条走到最后时,播放下一曲
    }

完整代码:

using UnityEngine;
using UnityEngine.EventSystems;

public class DragSlider : MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
    public static  bool isDrag;
    /// <summary>
    /// 鼠标按下
    /// </summary>
    /// <param name="eventData"></param>
    public void OnPointerDown(PointerEventData eventData)
    {
        isDrag = true;
    }
    /// <summary>
    /// 鼠标抬起
    /// </summary>
    /// <param name="eventData"></param>
    public void OnPointerUp(PointerEventData eventData)
    {
        OnMouseUp();
        isDrag = false;
    }
    void OnMouseUp()
    {
        //加上之后,避免拖动进度条到最后不松手时报错
        if (Player._instance.slid.value == 1)
        {
            //进度条拉到最后,直接播放下一曲
            Player._instance.NextMusic();
            return;
        }
        //给进度条添加事件监听,每当拖动进度条,歌曲从相应的位置播放
        Player._instance.aus.time = Player._instance.slid.value * Player._instance.aus.clip.length;
    }
}
using System;
using UnityEngine;
using UnityEngine.UI;

public class Player: MonoBehaviour {
  
    public Text musicName;          //显示歌曲的名字及歌手
    public Text nowTime;            //显示歌曲已播放的时间长度
    public Text allTime;            //显示当前歌曲的总时间长度
    public Slider slid;             //进度条
    public Transform buttons;       //按钮所在的集合体
    public AudioClip[] auc;         //存放歌曲的数组
    public AudioSource aus;         //音频播放器
    private int index;              //数组aus的索引

    private int currentHour, currentMinute, currentSecond;          //已播放的时间(时、分、秒)
    private int clipHour, clipMinute, clipSecond;                   //总时间(时、分、秒)
    
    public static Player _instance;

    void Start()
    {
        _instance = this;

        aus.Stop();                                                 //开始运行时不播放,点播放键才开始播放

        #region 注:该方式虽然可以直接达到拖动进度条就播放到进度条当前的音乐,但会产生滋滋啦啦的杂音,是因为进度条value变化,使之不断调用onValueChanged,从而让音乐的进度发生了变化,音乐前后颠倒,不断重叠
        ///
        /// 所以新建了个DragSlider脚本,挂在进度条上,来实现拖动播放的效果
        ///
        //slid.onValueChanged.AddListener(delegate
        //{
        //    //加上之后,避免拖动进度条到最后不松手时报错
        //    if (slid.value == 1)
        //        return;
        //    //给进度条添加事件监听,每当拖动进度条,歌曲从相应的位置播放
        //    aus.time = slid.value * aus.clip.length;
        //});
        #endregion
        foreach (Transform go in buttons)                           //遍历所有的操作按钮
        {
            go.GetComponent<Button>().onClick.AddListener(delegate  //根据按钮名给按钮添加事件监听
            {
                switch (go.name)
                {
                    case "lastM":       //点击“上一曲”按钮
                        LastMusic();
                        break;
                    case "pause":       //点击“暂停”按钮
                        Pause();
                        break;
                    case "play":        //点击“播放”按钮                       
                        Play();
                        break;
                    case "nextM":       //点击“下一曲”按钮
                        NextMusic();
                        break;
                }
            });
        }
	}
    void Update () {
        //当前播放过的时间
        nowtime();
        //当前正在播放的音频的总时间
        alltime();
        //当前正在播放的音乐
        nowMusic();
    }
    void nowtime()//当前播放过的时间
    {
        currentHour = (int)aus.time / 3600; //时
        currentMinute = (int)(aus.time - currentHour * 3600) / 60;//分
        currentSecond = (int)(aus.time - currentHour * 3600 - currentMinute * 60);//秒
                                                                                  
        //显示当前播放过的时间
        nowTime.text = string.Format("{0:D2}:{1:D2}:{2:D2} ",
            currentHour, currentMinute, currentSecond);
        //进度条变化
        //(之后更新版)如果当前没有拖拽进度条
        if(!DragSlider.isDrag)
            slid.value = aus.time / aus.clip.length;
    }
    void alltime()//歌曲总时间
    {
        //slid.value = 0;
        clipHour = (int)aus.clip.length / 3600;//时
        clipMinute = (int)(aus.clip.length - clipHour * 3600) / 60;//分
        clipSecond = (int)(aus.clip.length - clipHour * 3600 - clipMinute * 60);//秒
        //显示歌曲总时间
        allTime.text = string.Format("{0:D2}:{1:D2}:{2:D2}",
            clipHour, clipMinute, clipSecond);
    }
    private void LastMusic()            //上一曲
    {
        index--;                        //索引减一
        //若索引等于-1,即当前播放的音频是aus数组列表的第一首,则上一首应为aus数组列表的最后一首
        if (index==-1)
            index = auc.Length - 1;
        aus.clip = auc[index];          //音频播放器的音频为aus数组中索引对应的音频
        slid.value = 0;                 //初始化进度条
        aus.time = 0;                   //初始化音乐的播放时间(从头开始播)
        aus.Play();                     //播放音频
    }
    private void Pause()                //暂停
    {
        aus.Pause();
    }
    private void Play()                 //播放
    {
        //如果当前正在播放,则返回
        if (aus.isPlaying)
            return;
        aus.Play();
    }
    public void NextMusic()            //下一曲
    {
        index++;                        //索引加一
        //若索引等于aus音频数组的长度,即当前播放的音频是最后一首,则下一首应为aus数组列表的第一首
        if (index == auc.Length)
            index = 0;
        aus.clip = auc[index];          //音频播放器的音频为aus数组中索引对应的音频
        slid.value = 0;                 //初始化进度条
        aus.time = 0;                   //初始化音乐的播放时间(从头开始播)
        aus.Play();                     //播放音频
    } 
    void nowMusic()                     //当前的音频
    {
        AudioClip clip = aus.clip;      //当前播放的音频
        string n = aus.clip.name;       //当前播放的音频的名字
        string[] na = n.Split('-');     //以“-”为分割点,把音频名分为若干部分

        //显示当前正在播放的歌曲的名字【歌曲名(默认字体,25号)+歌手名(默认字体,18号,红色)的形式】
        musicName.text = string.Format("<size=25>{0}</size>" + "\n<size=18><color=#FF0000FF>{1}</color></size>", na[0], na[1]);

        index = Array.IndexOf(auc, clip);//当前播放的音频在aus数组中的索引
        Slider();                        //当进度条走到最后时,播放下一曲
    }
    void Slider()//当进度条走到最后时,播放下一曲
    {
        if (currentHour == clipHour && currentMinute == clipMinute && currentSecond == clipSecond)
        {
            NextMusic();//下一曲
        }
    }
}

编辑完代码后保存,在unity面板中建一个空的GameObject,把代码挂上去,然后把对应的UI拖到相应的位置,具体如下图所示:

 

最终效果如下:

代码的备注写的也比较详细,欢迎评论区留言共同探讨。 

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页