
7 changed files with 1410 additions and 6 deletions
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,90 @@ |
|||||||
|
import React, {Component} from 'react'; |
||||||
|
import load from 'load-script'; |
||||||
|
|
||||||
|
window.audio_cache={}; |
||||||
|
|
||||||
|
function load_amrnb() { |
||||||
|
return new Promise((resolve,reject)=>{ |
||||||
|
if(window.AMR) |
||||||
|
resolve(); |
||||||
|
else |
||||||
|
load('amr_all.min.js', (err)=>{ |
||||||
|
if(err) |
||||||
|
reject(err); |
||||||
|
else |
||||||
|
resolve(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
export class AudioWidget extends Component { |
||||||
|
constructor(props) { |
||||||
|
super(props); |
||||||
|
this.state={ |
||||||
|
url: this.props.src, |
||||||
|
state: 'loading', |
||||||
|
data: null, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
componentDidMount() { |
||||||
|
this.load(); |
||||||
|
} |
||||||
|
|
||||||
|
load() { |
||||||
|
if(window.audio_cache[this.state.url]) { |
||||||
|
this.setState({ |
||||||
|
state: 'loaded', |
||||||
|
data: window.audio_cache[this.state.url], |
||||||
|
}); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
console.log('fetching audio',this.state.url); |
||||||
|
Promise.all([ |
||||||
|
fetch(this.state.url), |
||||||
|
load_amrnb(), |
||||||
|
]) |
||||||
|
.then((res)=>{ |
||||||
|
res[0].blob().then((blob)=>{ |
||||||
|
const reader=new FileReader(); |
||||||
|
reader.onload=(event)=>{ |
||||||
|
const raw=new window.AMR().decode(event.target.result); |
||||||
|
if(!raw) { |
||||||
|
alert('audio decoding failed'); |
||||||
|
return; |
||||||
|
} |
||||||
|
const wave=window.PCMData.encode({ |
||||||
|
sampleRate: 8000, |
||||||
|
channelCount: 1, |
||||||
|
bytesPerSample: 2, |
||||||
|
data: raw |
||||||
|
}); |
||||||
|
const binary_wave=new Uint8Array(wave.length); |
||||||
|
for(let i=0;i<wave.length;i++) |
||||||
|
binary_wave[i]=wave.charCodeAt(i); |
||||||
|
|
||||||
|
const objurl=URL.createObjectURL(new Blob([binary_wave], {type: 'audio/wav'})); |
||||||
|
window.audio_cache[this.state.url]=objurl; |
||||||
|
this.setState({ |
||||||
|
state: 'loaded', |
||||||
|
data: objurl, |
||||||
|
}); |
||||||
|
}; |
||||||
|
reader.readAsBinaryString(blob); |
||||||
|
}); |
||||||
|
this.setState({ |
||||||
|
state: 'decoding', |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
render() { |
||||||
|
if(this.state.state==='loading') |
||||||
|
return (<p><audio controls /> 正在下载……</p>); |
||||||
|
else if(this.state.state==='decoding') |
||||||
|
return (<p><audio controls /> 正在解码……</p>); |
||||||
|
else if(this.state.state==='loaded') |
||||||
|
return (<p><audio src={this.state.data} controls /></p>); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue