我有一个React组件,当我单击播放时,它会循环访问存储在数据库中的id
(从Google驱动器文件URL)组成的数组,并将id
设置为src=
<source>
标记并播放该URL中的声音。但是它没有按预期工作。但是,当我将整个URL硬编码到src
时,它就起作用了。
import React, { useState, useEffect } from 'react';
import Axios from 'axios';
export default function Sound() {
const [songs, setSongs] = useState([]);
const [playing, setPlaying] = useState(false);
const [volume, setVolume] = useState(0);
const thisAudio = document.getElementById('audio');
const link = 'http://docs.google.com/uc?export=open&id=';
useEffect(() => {
Axios.get('/sound')
.then(res => {
const resData = res.data;
setSongs(resData.songs); // [0B4gNjF-sbbvHTTV1QUg0NERXTzQ,...]
setPlaying(resData.playing); // True
setVolume(resData.volume); // 0.5
})
.catch(err => console.log(err));
}, []);
const playSound = async () => {
await document.getElementById('src').setAttribute('src', link + songs[0]);
await document.getElementById('src').setAttribute('type', 'audio/mp3');
console.log(thisAudio);
/* Log result:
<audio id="audio">
<source id="src" src="http://docs.google.com/uc?export=open&id=0B4gNjF-sbbvHTTV1QUg0NERXTzQ" type="audio/mp3"></source>
</audio>
Exactly what I want to see here.
*/
thisAudio.play();
thisAudio.volume = volume;
}
const changeVolume = () => {
console.log(document.getElementById('audio'));
/*
After click playSound, I click this and the result is the same as the above, nothing wrong (I guess)
*/
thisAudio.volume = 0.3;
}
return (
<div className='sound'>
<audio id='audio'>
<source id='src' >
</source>
{/* This one works
<source id='src' src={link + '0B4gNjF-sbbvHTTV1QUg0NERXTzQ'} type='audio/mp3' >
</source>
*/}
</audio>
<button onClick={playSound}>Play Sound</button>
<button onClick={changeVolume}>Change Volume</button>
</div>
);
}
我使用async来确保要加载的元素可以执行play()
。
我不知道为什么这种方法行不通。谢谢。
答案 0 :(得分:0)
动态修改源元素及其属性时, 元素已插入视频或音频元素中 影响。要更改正在播放的内容,只需在 直接使用media元素,可能使用canPlayType() 从可用资源中进行选择的方法。通常, 文档处理完后手动处理源元素 解析是不必要的复杂方法。
我是通过Html5 audio won't play in safari when the source is populated via JavaScript找到的。