延伸我的前幾篇問題:(已解決)使用 wavesurfer.js 顯示聲音的波形圖
我想加個幾個按鈕來控制多個聲音檔的播放與暫停,包含:快速播放、正常播放、慢速播放、暫停。
我嘗試過,如果只有控制一個聲音檔的話可以,但多個聲音檔的話,目前只能控制到最後一個聲音檔。
目前程式碼大致如下(PS:在loadvoice()部分的寫法重複了很多次,請先見諒):
Javascript部分:
var btnCheck = 0;
var btnRate = 1;
document.onclick=function(){
var obj = event.srcElement;
if(obj.type == "button")
{
if(obj.id == "fastPlay"){
btnCheck = 1; //播放
btnRate = 1.3; //快速
loadvoice();
}else if(obj.id == "slowPlay"){
btnCheck = 1; //播放
btnRate = 0.7; //慢速
loadvoice();
}else if(obj.id == "btnPlay"){
btnCheck = 1; //播放
btnRate = 1; //正常
loadvoice();
}else if(obj.id == "btnPause"){
btnCheck = 2; //暫停
loadvoice();
}
}
}
function loadvoice(){
if(btnCheck == 0 && btnRate == 1){
for(i = 0 ; i < waveNum ; i++){
var wavesurfer = 'wavesurfer' + i;
wavesurfer = WaveSurfer.create({
container: '#waveform_'+i,
waveColor: 'violet',
progressColor: 'purple',
audioRate: btnRate
});
var voicepath = 'voice/'+voicename+'/'+voicename+'.pcm_'+i+'.wav';
wavesurfer.load(voicepath);
}
wavesurfer.on('ready', function () {
wavesurfer.play();
});
}else if(btnCheck == 1 && btnRate == 0.7){
for(i = 0 ; i < waveNum ; i++){
var wavesurfer = 'wavesurfer' + i;
wavesurfer = WaveSurfer.create({
container: '#waveform_'+i,
waveColor: 'violet',
progressColor: 'purple',
audioRate: btnRate
});
var voicepath = 'voice/'+voicename+'/'+voicename+'.pcm_'+i+'.wav';
wavesurfer.load(voicepath);
}
wavesurfer.on('ready', function () {
wavesurfer.play();
});
}else if(btnCheck == 1 && btnRate == 1){
for(i = 0 ; i < waveNum ; i++){
var wavesurfer = 'wavesurfer' + i;
wavesurfer = WaveSurfer.create({
container: '#waveform_'+i,
waveColor: 'violet',
progressColor: 'purple',
audioRate: btnRate
});
var voicepath = 'voice/'+voicename+'/'+voicename+'.pcm_'+i+'.wav';
wavesurfer.load(voicepath);
}
wavesurfer.on('ready', function () {
wavesurfer.play();
});
}else if(btnCheck == 1 && btnRate == 1.3){
for(i = 0 ; i < waveNum ; i++){
var wavesurfer = 'wavesurfer' + i;
wavesurfer = WaveSurfer.create({
container: '#waveform_'+i,
waveColor: 'violet',
progressColor: 'purple',
audioRate: btnRate
});
var voicepath = 'voice/'+voicename+'/'+voicename+'.pcm_'+i+'.wav';
wavesurfer.load(voicepath);
}
wavesurfer.on('ready', function () {
wavesurfer.play();
});
}else if(btnCheck == 2){
for(i = 0 ; i < waveNum ; i++){
var wavesurfer = 'wavesurfer' + i;
wavesurfer = WaveSurfer.create({
container: '#waveform_'+i,
waveColor: 'violet',
progressColor: 'purple',
audioRate: 1
});
var voicepath = 'voice/'+voicename+'/'+voicename+'.pcm_'+i+'.wav';
wavesurfer.load(voicepath);
}
}
}
HTML部分:
<?php
for($i = 0 ; $i < 24 ; $i++){
echo "
<div id='waveform_$i' class='waveform' style='background-color:rgba(255, 255, 255, 0.5)'></div><br>
<div class='btn-group' role='group'>
<button type='button' class='btn btn-secondary' id='fastPlay' name='fastPlay_$i' onclick=submit(this)>快速播放</button>
<button type='button' class='btn btn-secondary' id='btnPlay' name='btnPlay_$i' onclick=submit(this)>正常播放</button>
<button type='button' class='btn btn-secondary' id='slowPlay' name='slowPlay_$i' onclick=submit(this)>慢速播放</button>
<button type='button' class='btn btn-warning' id='btnPause' name='btnPause_$i' onclick=submit(this)>暫停</button>
</div>
";
}
?>
先猜
function loadvoice(){
if(btnCheck == 0 && btnRate == 1){
for(let i = 0 ; i < waveNum ; i++){
....
這樣
我後來實測一下
你的 code 現在應該連暫停都有問題吧
每個 button 都會 create 一個
是的><
(加了let還是一樣問題)
<html>
<script src = 'https://cdnjs.cloudflare.com/ajax/libs/wavesurfer.js/3.3.1/wavesurfer.min.js'></script>
<?php
for($i = 0 ; $i < 3 ; $i++){
echo "
<div id='waveform_$i' class='waveform' style='background-color:rgba(255, 255, 255, 0.5)'></div><br>
<div class='btn-group' role='group'>
<button type='button' class='btn btn-secondary' name='btnFastPlay' data-id = '$i'>快速播放</button>
<button type='button' class='btn btn-secondary' name='btnPlay' data-id = '$i'>正常播放</button>
<button type='button' class='btn btn-secondary' name='btnSlowPlay' data-id = '$i'>慢速播放</button>
<button type='button' class='btn btn-warning' name='btnPause' data-id = '$i'>暫停</button>
</div>
";
}
?>
<script>
let voicename = 'demo';
const voices = Array.from({ length: 3 }).map((el, i) => {
let wavesurfer = 'wavesurfer' + i;
wavesurfer = WaveSurfer.create({
container: '#waveform_'+i,
waveColor: 'violet',
progressColor: 'purple',
audioRate: 1
});
let voicepath = 'voice/'+voicename+'/'+voicename+'.pcm_'+i+'.wav';
wavesurfer.load(voicepath);
return wavesurfer;
})
document.onclick=function(){
const obj = event.srcElement;
console.log(obj)
if(obj.type == "button") {
if(obj.name == "btnFastPlay"){
voiceControl(obj, 'fast');
}else if(obj.name == "btnSlowPlay"){
voiceControl(obj, 'slow');
}else if(obj.name == "btnPlay"){
voiceControl(obj, 'play');
}else if(obj.name == "btnPause"){
voiceControl(obj, 'stop');
}
}
}
const voiceControl = (voice, action) => {
const voiceId = voice.dataset.id;
console.log(action)
switch (action) {
case 'fast': {
voices[voiceId] && voices[voiceId].setPlaybackRate(1.3);
voices[voiceId] && voices[voiceId].play();
break;
}
case 'slow': {
voices[voiceId] && voices[voiceId].setPlaybackRate(0.7);
voices[voiceId] && voices[voiceId].play();
break;
}
case 'play': {
voices[voiceId] && voices[voiceId].play();
break;
}
case 'stop': {
voices[voiceId] && voices[voiceId].pause();
break;
}
}
};
</script>
</html>
大概改了一下
總之
一開始先把 voice 初始化
並存在某個 array(demo 而已 大量可能不會這樣做
然後
你需要知道你現在要操作的是哪一個 voice
再對他進行 play 或 stop
官方也有提供setPlaybackRate
這個 function
可以讓你可以調整 rate
可能有空再補個 codepen demo
只提示你一個重點。
id名稱不能重覆。
依照你的程式碼。其按鍵的id名是會發生重覆的情況。
雖然目前看你的寫法看起來影響不大。
但還是不要太小看javascript超級大問題。
id能不重覆就不要重覆。就算你認為你不是用他來當觸發名。
另外寫法上你也得改一下。
理論上來看。你要每一個音源都有各自的控制器。
理當來說,因該是各自控制各自才對。
不過看你的寫好是按了對全部音源處理過一次。
的確覺得怪怪的。
只是我不清楚你實際要的做法。所以沒辦法跟你說對還是錯。