增加 audio 示例

This commit is contained in:
catchonme 2019-05-06 14:08:33 +08:00
parent 8ec84f3a81
commit 780e2c4d87
5 changed files with 67 additions and 20 deletions

View File

@ -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"
}
```

View File

@ -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',

View File

@ -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",
}
]
}

View File

@ -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;

View File

@ -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>
);
}