C#播放语音

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zx13525079024/article/details/54378086

今天项目需求要实现语音播放功能,.NET中有很多语音播放的组件和类库,但综合比较之后,发现还是WINDOWS自带的本地winmm.dll比较好用,而且使用方便,不需要安装插件。

效果图如下

语音播放类库

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApplication1
{
    public class VoiceMCI
    {

        public VoiceMCI()
        {
        }
        //定义API函数使用的字符串变量 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        private string Name = "";
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        private string durLength = "";
        [MarshalAs(UnmanagedType.LPTStr, SizeConst = 128)]
        private string TemStr = "";
        int ilong;
        //定义播放状态枚举变量
        public enum State
        {
            mPlaying = 1,
            mPuase = 2,
            mStop = 3
        };
        //结构变量
        public struct structMCI
        {
            public bool bMut;
            public int iDur;
            public int iPos;
            public int iVol;
            public int iBal;
            public string iName;
            public State state;
        };
        public structMCI mc = new structMCI();
        //取得播放文件属性
        public string FileName
        {
            get
            {
                return mc.iName;
            }
            set
            {
                try
                {
                    TemStr = "";
                    TemStr = TemStr.PadLeft(127, Convert.ToChar(" "));
                    Name = Name.PadLeft(260, Convert.ToChar(" "));
                    mc.iName = value;
                    ilong = APIClass.GetShortPathName(mc.iName, Name, Name.Length);
                    Name = GetCurrPath(Name);
                    Name = "open " + Convert.ToChar(34) + Name + Convert.ToChar(34) + " alias media";
                    ilong = APIClass.mciSendString("close all", TemStr, TemStr.Length, 0);
                    ilong = APIClass.mciSendString(Name, TemStr, TemStr.Length, 0);
                    ilong = APIClass.mciSendString("set media time format milliseconds", TemStr, TemStr.Length, 0);
                    mc.state = State.mStop;
                }
                catch
                {
                }
            }
        }
        //播放
        public void play()
        {
            TemStr = "";
            TemStr = TemStr.PadLeft(127, Convert.ToChar(" "));
            APIClass.mciSendString("play media", TemStr, TemStr.Length, 0);
            mc.state = State.mPlaying;
        }
        //停止
        public void StopT()
        {
            TemStr = "";
            TemStr = TemStr.PadLeft(128, Convert.ToChar(" "));
            ilong = APIClass.mciSendString("close media", TemStr, 128, 0);
            ilong = APIClass.mciSendString("close all", TemStr, 128, 0);
            mc.state = State.mStop;
        }
        public void Puase()
        {
            TemStr = "";
            TemStr = TemStr.PadLeft(128, Convert.ToChar(" "));
            ilong = APIClass.mciSendString("pause media", TemStr, TemStr.Length, 0);
            mc.state = State.mPuase;
        }
        private string GetCurrPath(string name)
        {
            if (name.Length < 1) return "";
            name = name.Trim();
            name = name.Substring(0, name.Length - 1);
            return name;
        }
        //总时间
        public int Duration
        {
            get
            {
                durLength = "";
                durLength = durLength.PadLeft(128, Convert.ToChar(" "));
                APIClass.mciSendString("status media length", durLength, durLength.Length, 0);
                durLength = durLength.Trim();
                if (durLength == "") return 0;
                return (int)(Convert.ToDouble(durLength) / 1000f);
            }
        }
        //当前时间
        public int CurrentPosition
        {
            get
            {
                durLength = "";
                durLength = durLength.PadLeft(128, Convert.ToChar(" "));
                APIClass.mciSendString("status media position", durLength, durLength.Length, 0);
                mc.iPos = (int)(Convert.ToDouble(durLength) / 1000f);
                return mc.iPos;
            }
        }

        /// <summary>
        /// 是否有声卡
        /// </summary>
        /// <returns></returns>
        public bool IsExistWaveOut()
        {
            if (APIClass.waveOutGetNumDevs() != 0)
            {
                return true;//有声卡
            }
            return false;

        }
    }
    public class APIClass
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern int GetShortPathName(
         string lpszLongPath,
         string shortFile,
         int cchBuffer
      );
        [DllImport("winmm.dll", EntryPoint = "mciSendString", CharSet = CharSet.Auto)]
        public static extern int mciSendString(
           string lpstrCommand,
           string lpstrReturnString,
           int uReturnLength,
           int hwndCallback
          );

        [DllImport("winmm.dll", EntryPoint = "waveOutGetNumDevs")]
        public static extern int waveOutGetNumDevs();
    }
}



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form3 : Form
    {
        //动态生成语音并播放语音
        public Form3()
        {
            InitializeComponent();
        }

        private void Form3_Load(object sender, EventArgs e)
        {
            LoadVoice();
        }
        List<VoiceModel> list = new List<VoiceModel>();
        private void LoadVoice()
        {
            //加载声音
            list.Add(new VoiceModel() { id = 1, voicePath = Application.StartupPath + "\\1.mp3" });
            list.Add(new VoiceModel() { id = 2, voicePath = Application.StartupPath + "\\10.mp3" });
            list.Add(new VoiceModel() { id = 3, voicePath = Application.StartupPath + "\\1.mp3" });
            list.Add(new VoiceModel() { id = 4, voicePath = Application.StartupPath + "\\10.mp3" });
            list.Add(new VoiceModel() { id = 5, voicePath = Application.StartupPath + "\\1.mp3" });
            int i = 0;
            foreach (var item in list)
            {
                PictureBox pVolume = new PictureBox();
                pVolume.Cursor = Cursors.Hand;
                pVolume.Tag = item.id.ToString();
                pVolume.SizeMode = PictureBoxSizeMode.StretchImage;
                pVolume.BorderStyle = BorderStyle.FixedSingle;
                pVolume.Width = 70;
                pVolume.Height = 28;
                pVolume.Image = Image.FromFile(Application.StartupPath + "\\volue.png");
                pVolume.Left = 5 + (i * 75);
                pVolume.Top = 15;
                pVolume.Click += pVolume_Click;
                panelVolue.Controls.Add(pVolume);
                i++;
            }
        }

       
        //点击播放声音
        private void pVolume_Click(object sender, EventArgs e)
        {
            VoiceMCI cm = new VoiceMCI();
            if (!cm.IsExistWaveOut())
            {
                MessageBox.Show("本机没有播放音频设备,不能播放");
                return;
            }
            foreach (Control item in panelVolue.Controls)
            {
                if (item is PictureBox)
                {
                    ((PictureBox)item).Image = Image.FromFile(Application.StartupPath + "\\volue.png");
                }
            }
            PictureBox pb = (PictureBox)sender;
            int index = int.Parse(pb.Tag.ToString());
            string mp3 = list[index].voicePath;
            if (!string.IsNullOrWhiteSpace(mp3) && File.Exists(mp3))
            {
                pb.Image = Image.FromFile(Application.StartupPath + "\\volue.gif");
                cm.FileName = mp3;
                int a = cm.Duration;
                cm.play();
                Application.DoEvents();
                DateTime dt = DateTime.Now;
                Task.Factory.StartNew(() =>
                {
                    while (true)
                    {
                        //判断是否播放结束
                        Application.DoEvents();
                        int dur = ExecDateDiff(dt, DateTime.Now);
                        Application.DoEvents();
                        if (dur >= a)
                        {
                            pb.Image = Image.FromFile(Application.StartupPath + "\\volue.png");
                            break;
                        }
                    }
                });
            }
        }


     /// <summary>
        /// 计算时间差
        /// </summary>
        /// <param name="dateBegin"></param>
        /// <param name="dateEnd"></param>
        /// <returns>返回秒数</returns>
        public static int ExecDateDiff(DateTime dateBegin, DateTime dateEnd)
        {
            TimeSpan ts1 = new TimeSpan(dateBegin.Ticks);
            TimeSpan ts2 = new TimeSpan(dateEnd.Ticks);
            TimeSpan ts3 = ts1.Subtract(ts2).Duration();
            //你想转的格式
            return ts3.Minutes * 60 + ts3.Seconds;
        }
    }
    public class VoiceModel
    {

        public int id { get; set; }

        public String voicePath { get; set; }

    }
}

DEMO下载 http://download.csdn.net/detail/zx13525079024/9735892



猜你喜欢

转载自blog.csdn.net/zx13525079024/article/details/54378086