midiPlayer.tsx 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /**
  2. * h5播放midi
  3. */
  4. import { defineComponent, reactive } from "vue";
  5. import state, { gotoNext, onEnded, onPlay } from "/src/state";
  6. let timer: any = null;
  7. const midiData = reactive({
  8. iframeRef: null as any,
  9. playing: false,
  10. index: 0,
  11. /** 倍数播放 */
  12. rate: 1
  13. })
  14. const playNote = () => {
  15. if (!midiData.playing) return
  16. const item = state.times[midiData.index]
  17. // 播放到最有一个音符,结束
  18. if (!item){
  19. onEnded()
  20. return
  21. }
  22. midiData.index++
  23. const duration = item.endtime - item.time
  24. midiData.iframeRef?.contentWindow?.playNote(item.realKey, duration)
  25. // gotoNext(item)
  26. timer = setTimeout(() => {
  27. playNote()
  28. }, duration / midiData.rate * 1000)
  29. }
  30. /** 停止播放 */
  31. const stopPlay = () => {
  32. midiData.playing = false
  33. }
  34. /** 初始化 */
  35. export const hanldeInitMidiData = (iframeRef: HTMLIFrameElement) => {
  36. midiData.iframeRef = iframeRef
  37. }
  38. /** 切换播放 */
  39. export const handleTogglePlayMidi = (type: "play" | "paused") => {
  40. if (type === 'play'){
  41. midiData.playing = true
  42. playNote()
  43. onPlay()
  44. } else {
  45. stopPlay()
  46. }
  47. }
  48. /** 设置倍数播放 */
  49. export const hanldeSetMidiPlaybackRate = (rate: number) => {
  50. midiData.rate = rate
  51. }
  52. /** 获取播放时间 */
  53. export const getMidiCurrentTime = () => {
  54. let index = midiData.index - 1
  55. index = index < 0 ? 0 : index
  56. return state.times[index].time
  57. }
  58. /** 获取总播放时间 */
  59. export const getMidiDuration = () => {
  60. return state.times[state.times.length - 1].endtime
  61. }
  62. /** 设置播放时间 */
  63. export const setMidiCurrentTime = (index: number) => {
  64. clearTimeout(timer)
  65. midiData.index = index
  66. playNote()
  67. }
  68. export default defineComponent({
  69. name: 'midiPlayer',
  70. setup(){
  71. return () => <div style={{display: 'none'}}></div>
  72. }
  73. })