# Audio 音频播放

- 来源：[E10 UI 组件库](https://www.e-cology.com.cn/ui/audio/freepass)
- 平台：PC
- 维护者：屈正巍
- Issue：http://gitlab.ecology10.cn/FRONTEND/weapp-ui/-/issues?state=all&search=[Audio]

## 代码演示

### 基础用法

直接引入组件进行使用

```jsx
import { Component } from 'react';
import { Audio, Button, constants } from '@weapp/ui'

const prefixCls = `${constants.uiPcClsPrefix}-audio`;

class AudioDemo extends Component<any, any> {

  showAudio = () => {
    Audio.showAudio('')
  }

  render() {
    return (
      <div className={prefixCls}>
        <h4>基础用法</h4>
        <Audio
          controls
          src={''}
        />
        <h4>通过Audio.showAudio方法打开</h4>
        <Button onClick={this.showAudio}>预览音频</Button>
      </div>
    );
  }
}

export default AudioDemo;
```

### 音频弹层

将播放器放于弹层中，可使用customRender自定义渲染触发器

```jsx
import { Component } from 'react'
import { Button, Audio, constants } from '@weapp/ui'

const prefixCls = `${constants.uiPcClsPrefix}-audio`;

class AudioDemo extends Component<any, any> {

  customRender = (_this: any, content: any) => {
    return <Button>自定义触发器</Button>
  }

  render() {
    return (
      <div className={prefixCls}>
        <h4>弹层模式</h4>
        <Audio
          isDialog
          controls
          src={''}
        />
        <br />
        <Audio
          isDialog
          controls
          src={''}
          customRender={this.customRender}
        />
      </div>
    );
  }
}

export default AudioDemo;
```

### videojs

引入三方媒体插件

```jsx
import { Component } from 'react'
import { Audio, constants } from '@weapp/ui'

const prefixCls = `${constants.uiPcClsPrefix}-audio`;

class AudioDemo extends Component<any, any> {

  render() {
    return (
      <div className={prefixCls}>
        <h4>注意：Audio组件同时也兼容mp4类型的src</h4>
        <h4>音频1</h4>
        <Audio
          useVideoJs
          src={''}
        />
        <h4>音频2</h4>
        <Audio
          useVideoJs
          src={``}
        />
      </div>
    );
  }
}

export default AudioDemo;
```

### videojs控制播放器

可以根据ref拿到组件内部集成的player元素，并调用相对应的api对视频内容进行控制

```jsx
import { Component, ReactText } from 'react'
import { Audio, constants, Input, Button, } from '@weapp/ui'

const prefixCls = `${constants.uiPcClsPrefix}-demo-audio`;

class AudioDemo extends Component<any, any> {
  videoRef: any;
  getVideoRef = (el: any) => this.videoRef = el

  state = {
    value: '',
  }

  onInputChange = (value: ReactText) => this.setState({ value: String(value) })
  updateSrc = () => this.videoRef.player?.src(this.state.value)
  pause = () => this.videoRef.player?.pause()
  play = () => this.videoRef.player?.play()
  reset = () => this.videoRef.player?.reset()
  requestFullscreen = () => this.videoRef.player?.requestFullscreen()

  render() {
    const { value } = this.state
    return (
      <div className={prefixCls}>
        <h4>自定义配置</h4>
        <div style={{ display: 'flex', marginBottom: '10px' }}>
          <span style={{ display: 'flex', alignItems: 'center' }}>音频链接：</span>
          <Input
            value={value}
            onChange={this.onInputChange}
            style={{ flex: 1 }}
          />
          <Button onClick={this.updateSrc} type={'primary'} style={{ display: 'flex', alignItems: 'center' }}>更新音频链接</Button>
        </div>
        <div style={{ display: 'flex', marginBottom: '10px' }}>
          <span style={{ display: 'flex', alignItems: 'center' }}>控制播放：</span>
          <Button onClick={this.play} type={'success'}>播放</Button>
          <Button onClick={this.pause} type={'danger'}>暂停</Button>
          <Button onClick={this.reset} type={'warning'}>重置</Button>
          <Button onClick={this.requestFullscreen} type={'default'}>全屏</Button>
        </div>
        <Audio
          ref={this.getVideoRef}
          useVideoJs
          controls
          src={value}
        />
      </div>
    );
  }
}

export default AudioDemo;
```

### videojs配置播放栏

可自定义控制播放栏

```jsx
import { Component } from 'react'
import { Audio, constants } from '@weapp/ui'

const prefixCls = `${constants.uiPcClsPrefix}-demo-video`;

class AudioDemo extends Component<any, any> {

  render() {
    return (
      <div className={prefixCls}>
        <h4>可自定义控制播放栏</h4>
        <Audio
          useVideoJs
          controls
          src={''}
          videoJsOptions={{
            //fluid：播放器的的大小将不再是一个固定的值，它会根据宽高比（aspectRatio）动态计算出来，以适应其容器的大小。
            fluid: true,
            //自动播放
            autoplay: false,
            //是否静音
            muted: true,
            //播放海报
            poster: '',
            //控制操作按钮的显隐
            controlBar: {
              'currentTimeDisplay': true,
              'timeDivider': true,
              'durationDisplay': true,
              'remainingTimeDisplay': false,
              //children：用于设置播放器可以包含的组件类型和顺序。
              children: [
                { name: 'playToggle' },
                { name: 'currentTimeDisplay' },
                { name: 'progressControl' },
                { name: 'durationDisplay' },
                { name: 'playbackRateMenuButton' },
                { name: 'volumePanel' },
                { name: 'FullscreenToggle' }
              ]
            },
          }}
        />
      </div>
    );
  }
}

export default AudioDemo;
```

### videojs播放失败

播放失败

```jsx
import { Component, ReactText } from 'react'
import { Audio, constants, Input, Button, } from '@weapp/ui'

const prefixCls = `${constants.uiPcClsPrefix}-demo-audio`;

class AudioDemo extends Component<any, any> {
  videoRef: any;
  getVideoRef = (el: any) => this.videoRef = el

  state = {
    value: 'err',
  }
  onAudioBeforeSetup = (player: any, err: any) => console.info('onAudioBeforeSetup', player, err)

  onAudioSetup = (player: any) => console.info('onAudioSetup', player)

  onAudioError = (player: any) => console.info('onAudioError', player)

  render() {
    const { value } = this.state
    return (
      <div className={prefixCls}>
        <h4>videojs钩子</h4>
        <Audio
          ref={this.getVideoRef}
          useVideoJs
          controls
          src={value}
          onAudioError={this.onAudioError}
          onAudioBeforeSetup={this.onAudioBeforeSetup}
          onAudioSetup={this.onAudioSetup}
        />
      </div>
    );
  }
}

export default AudioDemo;
```

## API

### 使用vidoejs说明：

```typescript
1.如果采用videojs模式，可以参考demo4中，采用ref的形式拿到Audio中的player，并调用相对应的方法对视频播放进行控制
```

### 参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| className | 自定义类名 | string | 否 |  |
| style | 自定义样式 | CSSProperties | 否 |  |
| isDialog | 是否为弹出音频 | boolean | 否 | false |
| src | 音频地址 | string | 否 |  |
| controls | 是否提供用户控制 | boolean | 否 | true |
| autoPlay | 是否马上自动开始播放 | boolean | 否 | false |
| loop | 是否循环播放 | boolean | 否 | false |
| muted | 是否默认静音 | boolean | 否 | false |
| preload | 预加载配置项 | 'auto/metadata/none' | 否 | 'auto' |
| dialogProps | dialog弹框参数 | boolean | 否 |  |
| onClose | 弹窗关闭回调 | () => void | 否 |  |
| onOpen | 弹窗打开回调 | () => void | 否 |  |
| useVideoJs | 是否采用三方的video.js | boolean | 否 |  |
| videoJsOptions | 三方的video.js配置options | VideoJsPlayerOptions | 否 |  |
| onAudioBeforeSetup | videos.js挂载前的狗子 | (player: any, err: any) => void | 否 |  |
| onAudioSetup | videos.js挂载时的钩子 | (player: any) => void | 否 |  |
| onAudioError | videos.js报错时的钩子 | (player: any) => void | 否 |  |
### Audio.showAudio

通过 function 调用方式预览音频

```typescript
//其中otherParams为需要传递的参数
function showAudio(src?: string, otherParams?: AudioProps){
  ...
}
```
