You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
2.7 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div>
  3. <div id="waveform" />
  4. <v-row no-gutters align="center" class="mb-3 mt-1">
  5. <v-col md="8">
  6. <v-slider
  7. v-model="zoom"
  8. min="0"
  9. max="500"
  10. step="10"
  11. :append-icon="mdiMagnifyPlusOutline"
  12. :prepend-icon="mdiMagnifyMinusOutline"
  13. hide-details
  14. @click:append="zoomIn"
  15. @click:prepend="zoomOut"
  16. @change="onChangeZoom"
  17. />
  18. </v-col>
  19. <v-col md="2">
  20. <v-slider
  21. v-model="volume"
  22. min="0"
  23. max="1"
  24. step="0.1"
  25. :append-icon="mdiVolumeHigh"
  26. hide-details
  27. @change="onChangeVolume"
  28. />
  29. </v-col>
  30. <v-col md="2">
  31. <v-select
  32. v-model="speed"
  33. :items="speeds"
  34. label="Speed"
  35. dense
  36. outlined
  37. hide-details
  38. @change="onChangeSpeed"
  39. />
  40. </v-col>
  41. </v-row>
  42. <v-btn color="primary" class="text-capitalize" @click="play">
  43. <v-icon v-if="!isPlaying" left>
  44. {{ mdiPlayCircleOutline }}
  45. </v-icon>
  46. <v-icon v-else left>
  47. {{ mdiPauseCircleOutline }}
  48. </v-icon>
  49. <span v-if="!isPlaying">Play</span>
  50. <span v-else>Pause</span>
  51. </v-btn>
  52. </div>
  53. </template>
  54. <script>
  55. import Vue from 'vue'
  56. import WaveSurfer from 'wavesurfer.js'
  57. import {
  58. mdiPlayCircleOutline,
  59. mdiPauseCircleOutline,
  60. mdiVolumeHigh,
  61. mdiMagnifyPlusOutline,
  62. mdiMagnifyMinusOutline
  63. } from '@mdi/js'
  64. export default Vue.extend({
  65. props: {
  66. source: {
  67. type: String,
  68. default: '',
  69. required: true
  70. }
  71. },
  72. data() {
  73. return {
  74. wavesurfer: null,
  75. isPlaying: false,
  76. zoom: 0,
  77. volume: 0.6,
  78. speed: 1,
  79. speeds: [0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
  80. mdiPlayCircleOutline,
  81. mdiPauseCircleOutline,
  82. mdiVolumeHigh,
  83. mdiMagnifyPlusOutline,
  84. mdiMagnifyMinusOutline
  85. }
  86. },
  87. watch: {
  88. source() {
  89. this.load()
  90. this.isPlaying = false
  91. }
  92. },
  93. mounted() {
  94. this.wavesurfer = WaveSurfer.create({
  95. container: '#waveform',
  96. backend: 'MediaElement'
  97. })
  98. this.load()
  99. },
  100. methods: {
  101. load() {
  102. this.wavesurfer.load(this.source)
  103. },
  104. play() {
  105. this.isPlaying = !this.isPlaying
  106. this.wavesurfer.playPause()
  107. },
  108. zoomOut() {
  109. this.zoom = this.zoom - 10 || 0
  110. this.onChangeZoom(this.zoom)
  111. },
  112. zoomIn() {
  113. this.zoom = this.zoom + 10 || 500
  114. this.onChangeZoom(this.zoom)
  115. },
  116. onChangeVolume(value) {
  117. this.wavesurfer.setVolume(value)
  118. },
  119. onChangeZoom(value) {
  120. this.wavesurfer.zoom(value)
  121. },
  122. onChangeSpeed(value) {
  123. this.wavesurfer.setPlaybackRate(value)
  124. }
  125. }
  126. })
  127. </script>