1 /// <summary> 2 /// ************************************************* 3 /// 類名:MP3幫助類 4 /// 修改日期:2016/06/25 5 /// 作者:董兆生 6 /// 聯繫方式:QQ490412323 7 // ...
本文為原創文章如需轉載請註明出處:
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