1 /// <summary> 2 /// ************************************************* 3 /// 类名:MP3帮助类 4 /// 修改日期:2016/06/25 5 /// 作者:董兆生 6 /// 联系方式:QQ490412323 7 /// ************************************************* 8 /// </summary> 9 public class AudioPlay :IDisposable 10 { 11 /// <summary> 12 /// 播放状态 13 /// </summary> 14 private PlayState _palystate = PlayState.Closed; 15 public PlayState PlayState 16 { 17 set 18 { 19 if (value == _palystate) return; 20 OnPropertyChanged(value); 21 _palystate = value; 22 } 23 get { return _palystate; } 24 } 25 /// <summary> 26 /// 操作错误事件 27 /// </summary> 28 public event Errordelegate EventAudioplayerror; 29 /// <summary> 30 /// 播放完毕事件 31 /// </summary> 32 public event PlayEnd EventAudioPlayEnd; 33 /// <summary> 34 /// 播放状态发生变化事件 35 /// </summary> 36 public event DelegatePlayStateChange PlayStatePropertyChanged; 37 /// <summary> 38 /// 播放时间变化事件 39 /// </summary> 40 public event DelegatePlayNowTime EventPlayTimeChange; 41 /// <summary> 42 /// 时间长度毫秒 43 /// </summary> 44 public readonly StringBuilder PlayLenght = new StringBuilder(255); 45 /// <summary> 46 /// 播放音量 47 /// </summary> 48 private int _playvlome = 1000; 49 public int PlayVolume{get { return _playvlome; }} 50 /// <summary> 51 /// 当前播放时间 52 /// </summary> 53 public int NowPlayTime 54 { 55 get { return int.Parse(_nowplaytime.ToString()); } 56 } 57 private readonly StringBuilder _nowplaytime = new StringBuilder(255); 58 59 private AudioModel _nowPlayData; 60 /// <summary> 61 /// 当前播放歌曲 62 /// </summary> 63 public AudioModel NowPlayData { get { return _nowPlayData; } } 64 /// <summary> 65 /// 播放列表 66 /// </summary> 67 public List<AudioModel> PlayList = new List<AudioModel>(); 68 69 private int _playindex; 70 /// <summary> 71 /// 当前播放歌曲在列表中的序号 72 /// </summary> 73 public int PlayIndex { get { return _playindex; } } 74 /// <summary> 75 /// 是否单曲循环播放 76 /// </summary> 77 public bool IsSingleLoop { set; get; } 78 /// <summary> 79 /// 是否列表循环播放 80 /// </summary> 81 public bool IsListLoop { set; get; } 82 /// <summary> 83 /// 随机循环播放 84 /// </summary> 85 public bool IsRandLoop { set; get; } 86 87 private Random _random; 88 89 public AudioPlay(AudioModel playdata) 90 { 91 _nowPlayData = (AudioModel)playdata.Clone(); 92 PlayList .Add(_nowPlayData); 93 _playindex = 0; 94 95 96 var playTimer = new Timer 97 { 98 Enabled = true, 99 Interval = 1000 100 }; 101 102 playTimer.Tick += playTimer_Tick; 103 } 104 105 public AudioPlay(List<AudioModel> playList) 106 { 107 PlayList = new List<AudioModel>(playList); 108 _nowPlayData = PlayList[0]; 109 _playindex = 0; 110 111 112 var playTimer = new Timer 113 { 114 Enabled = true, 115 Interval = 1000 116 }; 117 playTimer.Tick += playTimer_Tick; 118 } 119 120 public bool NextPlay() 121 { 122 if (PlayList==null) return false; 123 124 if (_playindex + 1 >= PlayList.Count) return false; 125 126 Closed(); 127 128 _nowPlayData = PlayList[_playindex + 1]; 129 130 Open(); 131 132 SetVolume(PlayVolume); 133 134 Play(); 135 136 _playindex = _playindex + 1; 137 138 return true; 139 } 140 141 public bool PreviousPlay() 142 { 143 if (PlayList==null) return false; 144 145 if (_playindex - 1 <0 ) return false; 146 147 Closed(); 148 149 _nowPlayData = PlayList[_playindex - 1]; 150 151 Open(); 152 153 SetVolume(PlayVolume); 154 155 Play(); 156 157 _playindex = _playindex - 1; 158 159 return true; 160 } 161 162 public bool JumpPlay(int index) 163 { 164 if (PlayList == null) return false; 165 166 if (index < 0 && index > PlayList.Count - 1) return false; 167 168 Closed(); 169 170 _nowPlayData = PlayList[index]; 171 172 Open(); 173 174 SetVolume(PlayVolume); 175 176 Play(); 177 178 _playindex = index; 179 180 return true; 181 } 182 183 private void playTimer_Tick(object sender, EventArgs e) 184 { 185 if (PlayState != PlayState.Playing) return; 186 187 DoOrder(string.Format("status {0} position", _nowPlayData.AliasMovie), _nowplaytime, _nowplaytime.Capacity); 188 189 var returntimeThread = new Thread(ThreadReturnTime) {IsBackground = true}; 190 191 returntimeThread.Start(_nowplaytime); 192 193 if (!_nowplaytime.Equals(PlayLenght)) return; 194 195 Closed(); 196 197 _palystate = PlayState.Closed; 198 199 if (EventAudioPlayEnd !=null) EventAudioPlayEnd(); 200 201 if (IsRandLoop) 202 { 203 204 _random = new Random((int)DateTime.Now.Ticks); 205 206 _playindex = _random.Next(0, PlayList.Count); 207 208 _nowPlayData = PlayList[_playindex]; 209 210 JumpPlay(_playindex); 211 212 return; 213 } 214 215 if (IsListLoop) 216 { 217 218 if (_playindex + 1 >= PlayList.Count) 219 { 220 _playindex = 0; 221 } 222 else 223 { 224 _playindex = _playindex + 1; 225 } 226 227 _nowPlayData = PlayList[_playindex]; 228 229 JumpPlay(_playindex); 230 231 return; 232 } 233 234 if (!IsSingleLoop) return; 235 236 JumpPlay(_playindex); 237 } 238 239 private void ThreadReturnTime(object time) 240 { 241 if(_palystate!=PlayState.Playing) return; 242 243 if (EventPlayTimeChange != null) EventPlayTimeChange(int.Parse(time.ToString())); 244 } 245 246 247 /// <summary> 248 /// 执行指令 249 /// </summary> 250 /// <param name="order">指令</param> 251 /// <param name="returnString">需要返回的数据</param> 252 /// <param name="returnsize">返回数据大小</param> 253 /// <returns></returns> 254 private bool DoOrder(string order, StringBuilder returnString,int returnsize) 255 { 256 var error = WinApiHepler.mciSendString(order, returnString, returnsize, new IntPtr()); 257 258 if(IsDisplsed)return false; 259 260 if (error == 0) return true; 261 262 Errorlog(error); 263 264 return false; 265 } 266 267 /// <summary> 268 /// 事件格式化 269 /// </summary> 270 /// <param name="millisecond">毫秒</param> 271 /// <returns>hh:mm:ss</returns> 272 public static string TimeFormat(int millisecond) 273 { 274 var time = new TimeSpan(0, 0, 0, 0, millisecond); 275 276 return string.Format("{0}:{1}:{2}", time.Hours, time.Minutes, time.Seconds); 277 } 278 /// <summary> 279 /// 获得当前状态 280 /// </summary> 281 /// <returns></returns> 282 public PlayState GetPlyaState() 283 { 284 var state = new StringBuilder(50); 285 286 return DoOrder(string.Format("status {0} mode", _nowPlayData.AliasMovie), state, state.Capacity) != true ? PlayState.Error : (PlayState)Enum.Parse(typeof(PlayState), state.ToString()); 287 } 288 /// <summary> 289 /// 打开音乐文件 290 /// </summary> 291 public void Open() 292 { 293 PlayState = DoOrder(string.Format("open {0} alias {1}", _nowPlayData.ShortPath, _nowPlayData.AliasMovie), null, 0) != true ? PlayState.Error : PlayState.Opne; 294 295 if (_palystate != PlayState.Opne) return; 296 297 DoOrder(string.Format("status {0} length", _nowPlayData.AliasMovie), PlayLenght, PlayLenght.Capacity); 298 299 } 300 /// <summary> 301 /// 播放音乐 302 /// </summary> 303 /// <param name="starttime">开始时间</param> 304 /// <param name="endtime">结束时间</param> 305 public void Play(int starttime,int endtime) 306 { 307 PlayState = DoOrder(string.Format("play {0} from {1} to {2} notify", _nowPlayData.AliasMovie, starttime, endtime), null, 0) != true ? PlayState.Error : PlayState.Playing; 308 } 309 /// <summary> 310 /// 播放音乐 311 /// </summary> 312 public void Play() 313 { 314 PlayState = DoOrder(string.Format("play {0} notify", _nowPlayData.AliasMovie), null, 0) != true ? PlayState.Error : PlayState.Playing; 315 } 316 /// <summary> 317 /// 暂停 318 /// </summary> 319 public void Pause() 320 { 321 PlayState = DoOrder(string.Format("pause {0}", _nowPlayData.AliasMovie), null, 0) != true ? PlayState.Error : PlayState.Paused; 322 } 323 /// <summary> 324 /// 停止 325 /// </summary> 326 public void Stop() 327 { 328 PlayState = DoOrder(string.Format("stop {0}", _nowPlayData.AliasMovie), null, 0) != true ? PlayState.Error : PlayState.Stopped; 329 } 330 /// <summary> 331 /// 关闭音乐 332 /// </summary> 333 public void Closed() 334 { 335 PlayState = DoOrder(string.Format("close {0}", _nowPlayData.AliasMovie), null, 0) != true ? PlayState.Error : PlayState.Closed; 336 } 337 /// <summary> 338 /// 设置音量 339 /// </summary> 340 /// <param name="volume">0-1000</param> 341 /// <returns></returns> 342 public bool SetVolume(int volume) 343 { 344 if (!DoOrder(string.Format("setaudio {0} volume to {1}", _nowPlayData.AliasMovie, volume), null, 0)) 345 return false; 346 _playvlome = volume; 347 return true; 348 } 349 350 private void Errorlog(int error) 351 { 352 var errorText = new StringBuilder(50); 353 354 WinApiHepler.mciGetErrorString(error, errorText, errorText.Capacity); 355 356 if (EventAudioplayerror == null) return; 357 358 EventAudioplayerror(errorText.ToString()); 359 } 360 361 private void OnPropertyChanged(PlayState state) 362 { 363 if (PlayStatePropertyChanged != null) 364 { 365 PlayStatePropertyChanged(state); 366 } 367 } 368 369 protected bool IsDisplsed { get; set; } 370 371 ~AudioPlay() 372 { 373 Dispose(); 374 } 375 376 /// <summary> 377 /// 释放 378 /// </summary> 379 public void Dispose() 380 { 381 Dispose(IsDisplsed); 382 } 383 public virtual void Dispose(bool isDisplsed) 384 { 385 if (isDisplsed) 386 return; 387 388 EventAudioplayerror = null; 389 390 EventAudioPlayEnd = null; 391 392 EventPlayTimeChange = null; 393 394 DoOrder(string.Format("close {0}", _nowPlayData.AliasMovie), null, 0); 395 } 396 397 } 398 public delegate void Errordelegate(string error); 399 400 public delegate void PlayEnd(); 401 402 public delegate void DelegateHockMesg(Message msg); 403 404 public delegate void DelegatePlayStateChange(PlayState state); 405 406 public delegate void DelegatePlayNowTime(int time); 407 408 public class WindosMessageInform :UserControl 409 { 410 int[] HockMsg { set; get; } 411 412 public event DelegateHockMesg EventHockmesg; 413 414 public WindosMessageInform(int[] hockmsg) 415 { 416 HockMsg = hockmsg; 417 } 418 419 protected override void WndProc(ref Message m) 420 { 421 if (HockMsg.ToList().Contains(m.Msg)) 422 { 423 if (EventHockmesg != null) EventHockmesg(m); 424 } 425 base.WndProc(ref m); 426 } 427 } 428 429 public class AudioModel : ICloneable 430 { 431 public AudioModel() 432 { 433 434 } 435 436 public AudioModel(string file,string alias,object data) 437 { 438 PlayFile = file; 439 440 AliasMovie = alias; 441 442 SourceData = data; 443 444 FileName = System.IO.Path.GetFileNameWithoutExtension(file); 445 446 var shortpath = new StringBuilder(255); 447 448 WinApiHepler.GetShortPathName(PlayFile, shortpath, shortpath.Capacity); 449 450 ShortPath = shortpath.ToString(); 451 } 452 public string FileName { set; get; } 453 454 public string PlayFile { set; get; } 455 456 public string ShortPath { set; get; } 457 458 public string AliasMovie { set; get; } 459 460 public object SourceData { set; get; } 461 462 public object Clone() 463 { 464 var clonedata = SerializationHelper.GetSerialization(this); 465 466 return SerializationHelper.ScriptDeserialize<AudioModel>(clonedata); 467 } 468 } 469 470 public enum PlayState 471 { 472 Opne, 473 Playing, 474 Paused, 475 Stopped, 476 Closed, 477 None, 478 Error 479 }AudioPlayHelper
基于winAPI winmm.dll
mciSendString 编写的帮助类功能比较齐全(起码比我现在网上搜的齐全@-@)已经实现的功能 播放 暂停 停止 关闭就不多说了基本功能没啥好说的。
事件:播放完毕通知,时间变化通知,状态变化通知,错误通知
功能:上一首, 下一首 ,指定顺序播放
播放后状态:单曲循环,列表循环,随机播放
里面用到的BearChildren为我个人编写的工具功能如名字一样熊孩子...意思:让这个框架跟熊孩子一样什么都能做 目前还在完善中
目前框架主要是以单机桌面开发编写的一套工具,内容为图像处理,Io,数据等,我希望能有更多的人来帮助我来完善这个框架在日常工作中让开发变的更加方便快捷,
QQ群为:572582327 欢迎大家一起加入讨论丰富自己的技术 无论你是大神还是新手都欢迎你们。
代码下载链接:自带播放器demo
https://git.coding.net/BearChildren/AudioPlayHelper.git