forked from p96170835/amis
增加 audio 示例
This commit is contained in:
parent
8ec84f3a81
commit
780e2c4d87
|
@ -3479,11 +3479,11 @@ CRUD 支持三种模式:`table`、`cards`、`list`,默认为 `table`。
|
|||
| autoPlay | `boolean` | false | 是否自动播放 |
|
||||
| rates | `array` | `[1.0, 2.0, 4.0]` | 加速播放 |
|
||||
|
||||
```schema:height="500" scope="body"
|
||||
```schema:height="200" scope="body"
|
||||
{
|
||||
"type": "audio",
|
||||
"autoPlay": false,
|
||||
"src": ""
|
||||
"src": "http://www.ytmp3.cn/down/32791.mp3"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ import WizardSchema from './Wizard';
|
|||
import ChartSchema from './Chart';
|
||||
import HorizontalSchema from './Horizontal';
|
||||
import VideoSchema from './Video';
|
||||
import AudioSchema from './Audio';
|
||||
import TasksSchema from './Tasks';
|
||||
import ServicesDataSchema from './Services/Data';
|
||||
import ServicesSchemaSchema from './Services/Schema';
|
||||
|
@ -448,6 +449,12 @@ const navigations = [
|
|||
path: 'chart',
|
||||
component: makeSchemaRenderer(ChartSchema)
|
||||
},
|
||||
{
|
||||
label: '音频',
|
||||
icon: 'fa fa-volume-up',
|
||||
path: 'audio',
|
||||
component: makeSchemaRenderer(AudioSchema)
|
||||
},
|
||||
{
|
||||
label: '视频',
|
||||
icon: 'fa fa-video-camera',
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
export default {
|
||||
"$schema": "http://amis.baidu.com/v2/schemas/page.json#",
|
||||
"title": "音频播放器",
|
||||
"body": [
|
||||
{
|
||||
"type": "audio",
|
||||
"autoPlay": false,
|
||||
"src": "http://www.ytmp3.cn/down/32791.mp3",
|
||||
}
|
||||
]
|
||||
}
|
|
@ -36,7 +36,9 @@
|
|||
}
|
||||
|
||||
.#{$ns}Audio--inline {
|
||||
display: inline;
|
||||
display: inline-block;
|
||||
height: $Audio-height;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.#{$ns}Audio {
|
||||
|
@ -45,6 +47,10 @@
|
|||
line-height: $Audio-lineHeight;
|
||||
border: $Audio-border;
|
||||
display: inline-block;
|
||||
&-rates-holder {
|
||||
display: inline-block;
|
||||
width: $Audio-rate-width / 2;
|
||||
}
|
||||
&-rates {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
|
|
@ -32,6 +32,7 @@ export interface AudioState {
|
|||
export class Audio extends React.Component<AudioProps, AudioState> {
|
||||
audio: any;
|
||||
progressTimeout: any;
|
||||
durationTimeout: any;
|
||||
|
||||
static defaultProps:Pick<AudioProps, 'inline' | 'autoPlay' | 'playbackRate' | 'loop' | 'rates' | 'progressInterval'> = {
|
||||
inline: true,
|
||||
|
@ -108,6 +109,7 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
|
||||
@autobind
|
||||
handleMute() {
|
||||
if (!this.props.src) return;
|
||||
const {muted, prevVolume} = this.state;
|
||||
const curVolume = !muted ? 0 : prevVolume;
|
||||
this.audio.muted = !muted;
|
||||
|
@ -119,6 +121,7 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
|
||||
@autobind
|
||||
handlePlaying() {
|
||||
if (!this.props.src) return;
|
||||
let playing = this.state.playing;
|
||||
playing ? this.audio.pause() : this.audio.play();
|
||||
this.setState({
|
||||
|
@ -128,15 +131,19 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
|
||||
@autobind
|
||||
getCurrentTime() {
|
||||
if (!this.audio || !this.state.isReady) return 0;
|
||||
if (!this.audio || !this.props.src || !this.state.isReady) return '0:00';
|
||||
const duration = this.audio.duration;
|
||||
const played = this.state.played;
|
||||
return this.formatTime(duration * (played || 0));
|
||||
}
|
||||
|
||||
@autobind
|
||||
getDuration() {
|
||||
if (!this.audio || !this.state.isReady) return 0;
|
||||
getDuration () {
|
||||
if (!this.audio || !this.props.src) return '0:00';
|
||||
if (!this.state.isReady) {
|
||||
this.onDurationCheck();
|
||||
return '0:00';
|
||||
}
|
||||
const { duration, seekable } = this.audio;
|
||||
// on iOS, live streams return Infinity for the duration
|
||||
// so instead we use the end of the seekable timerange
|
||||
|
@ -146,8 +153,19 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
return this.formatTime(duration);
|
||||
}
|
||||
|
||||
@autobind
|
||||
onDurationCheck() {
|
||||
clearTimeout(this.durationTimeout);
|
||||
const duration = this.audio && this.audio.duration;
|
||||
if (!duration) {
|
||||
this.audio.load();
|
||||
this.durationTimeout = setTimeout(this.onDurationCheck, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
onSeekChange(e:any) {
|
||||
if (!this.props.src) return;
|
||||
const played = e.target.value;
|
||||
this.setState({ played: played });
|
||||
}
|
||||
|
@ -175,6 +193,7 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
|
||||
@autobind
|
||||
setVolume(e:any) {
|
||||
if (!this.props.src) return;
|
||||
const volume = e.target.value;
|
||||
this.audio.volume = volume;
|
||||
this.setState({
|
||||
|
@ -202,6 +221,7 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
|
||||
@autobind
|
||||
toggleHandlePlaybackRate() {
|
||||
if (!this.props.src) return;
|
||||
this.setState({
|
||||
showHandlePlaybackRate: !this.state.showHandlePlaybackRate
|
||||
});
|
||||
|
@ -209,6 +229,7 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
|
||||
@autobind
|
||||
toggleHandleVolume(type:boolean) {
|
||||
if (!this.props.src) return;
|
||||
this.setState({
|
||||
showHandleVolume: type
|
||||
});
|
||||
|
@ -229,7 +250,6 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
played,
|
||||
volume,
|
||||
muted,
|
||||
isReady,
|
||||
playbackRate,
|
||||
showHandlePlaybackRate,
|
||||
showHandleVolume
|
||||
|
@ -247,22 +267,25 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
loop={loop}>
|
||||
<source src={src}/>
|
||||
</audio>
|
||||
{isReady ? (<div className={cx('Audio', className)}>
|
||||
{rates ? (<div className={cx('Audio-rates')}>
|
||||
<div className={cx('Audio-rate')}
|
||||
onClick={this.toggleHandlePlaybackRate}>
|
||||
x{playbackRate.toFixed(1)}
|
||||
</div>
|
||||
{showHandlePlaybackRate ? (<div className={cx('Audio-rateControl')}>
|
||||
<div className={cx('Audio', className)}>
|
||||
{rates && rates.length ?
|
||||
(<div className={cx('Audio-rates')}>
|
||||
<div className={cx('Audio-rate')}
|
||||
onClick={this.toggleHandlePlaybackRate}>
|
||||
x{playbackRate.toFixed(1)}
|
||||
</div>
|
||||
{showHandlePlaybackRate ?
|
||||
(<div className={cx('Audio-rateControl')}>
|
||||
{rates.map((rate, index) =>
|
||||
<span className={cx('Audio-rateControlItem')}
|
||||
key={index}
|
||||
onClick={() => this.handlePlaybackRate(rate)}>
|
||||
key={index}
|
||||
onClick={() => this.handlePlaybackRate(rate)}>
|
||||
x{rate.toFixed(1)}
|
||||
</span>
|
||||
)} </div>) : null}
|
||||
</span>
|
||||
)} </div>)
|
||||
: null}
|
||||
</div>)
|
||||
: null }
|
||||
: (<div className={cx('Audio-rates-holder')}></div>) }
|
||||
<div className={cx('Audio-play')} onClick={this.handlePlaying}>
|
||||
{playing ? pauseIcon : playIcon}
|
||||
</div>
|
||||
|
@ -291,7 +314,7 @@ export class Audio extends React.Component<AudioProps, AudioState> {
|
|||
</div></div>)
|
||||
: volume > 0 ? volumeIcon : muteIcon}
|
||||
</div>
|
||||
</div>) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue