美文网首页
音频组件

音频组件

作者: 糖糖不加糖_ | 来源:发表于2019-11-24 15:42 被阅读0次

    下面为一个音频组件,样式自定义,增加倍速效果,使用antd组件改变了样式

    import React, { Component } from 'react';
    import { Drawer, Spin, Button, Slider, Select, Icon, Pagination } from 'antd';
    import styles from './style.less';
    import { connect } from 'dva';
    import { ModalState } from '../../model';
    import { PhoneRecord, Pager } from '../../data';
    import { dateFormat } from '../../../common/dateUtils';
    import { Dispatch } from 'redux';
    
    const { Option } = Select;
    
    interface PhoneRecordProps {
      phoneVisible: boolean;
      phoneLoading: boolean;
      handlePhoneRecord: () => void;
      phoneRecordData: PhoneRecord[];
      dispatch: Dispatch<any>;
      subclazzNumber: number;
      userId: number;
      phonePager: Pager;
    };
    interface PhoneRecordState {
      iconType: {};
      values: {};
      isPlay: number;
    }
    class PhoneRecordInfo extends Component<PhoneRecordProps, PhoneRecordState> {
    
      constructor (props: PhoneRecordProps) {
        super(props);
        this.state = {
          iconType: {},
          values: {},
          isPlay: -1,
        }
      }
    
      componentDidUpdate(prevProps: PhoneRecordProps, prevState: PhoneRecordState) {
        const { phoneVisible } = this.props;
        const phoneVisiblePrev = prevProps.phoneVisible;
        if (phoneVisible && phoneVisible !== phoneVisiblePrev) {
          // this.forceUpdate();
          this.handlePhoneRecordData();
        }
      }
    
      componentWillUnmount() {
        const len = Object.keys(this.refs).length;
        for(let i = 0; i < len; i++) {
          const audio = this.refs[i];
          audio.removeEventListener('timeupdate', this.updateProgress);
          audio.removeEventListener('ended', this.audioEnded);
          audio.pause();
        }
      }
    
      // 改变播放速度
      changeMultiple = (value, key) => {
        console.log('value', value)
        this.refs[key.toString()].playbackRate = value;
      }
    
      // 处理时间
      transTime = (time) => {
        // 后端返回的audio中的时间以ms计算,取整s
        let duration = parseInt(time / 1000);
        let minute = parseInt(duration / 60);
        let sec = duration % 60;
        let isM0 = ':';
        if (minute === 0) {
            minute = '00';
        } else if (minute < 10) {
            minute = '0' + minute;
        }
        if (sec < 10) {
            sec = '0' + sec;
        }
        return minute + isM0 + sec;
      }
    
      // 播放暂停音频
      playAudio = (id) => {
        const { iconType, isPlay } = this.state;
        const audio = this.refs[id.toString()];
        if (id !== isPlay) {
          const audioPre = this.refs[isPlay.toString()];
          if (audioPre) {
            audioPre.pause();
            iconType[isPlay.toString()] = 'caret-right';
          }
        }
    
        audio.addEventListener('timeupdate', () => this.updateProgress(id), false);
        audio.addEventListener('ended', () => this.audioEnded(id), false);
        if (iconType[id] === 'caret-right') {
          audio.play();
          iconType[id] = 'pause';
          this.setState({ iconType, isPlay: id });
        } else {
          audio.pause();
          iconType[id] = 'caret-right';
          this.setState({ iconType, isPlay: -1 });
        }
    
      }
    
      // 电话沟通记录数据
      handlePhoneRecordData = (pager: Pager = {current: 1, pageSize: 5}) => {
        const { dispatch, subclazzNumber, userId } = this.props;
        dispatch({
          type: 'academicRecord/getPhoneRecordList',
          payload: { subclazzNumber, userId, pager },
          callback: this.handleIconType
        });
      }
    
      // 处理图标类型
      handleIconType = (data: PhoneRecord[]) => {
        const iconType = {};
        data.forEach((item) => {
          const { id } = item;
          iconType[id] = 'caret-right';
        });
        this.setState({ iconType });
      }
    
      // 更新进度
      updateProgress = (id) => {
        const audio = this.refs[id];
        const { values } = this.state;
        const { currentTime, duration } = audio;
        let value;
        if (currentTime && duration) {
          value = Math.round((Math.floor(currentTime) / Math.floor(duration)) * 100);
        } else {
          value = 0;
        }
        // const value = Math.round((Math.floor(currentTime) / Math.floor(duration)) * 100);
        values[id] = value;
    
        this.setState({ values });
      }
    
      // 音频结束
      audioEnded = (id) => {
        const audio = this.refs[id.toString()];
        const { iconType } = this.state;
        iconType[id] = 'caret-right';
        audio.pause();
        this.setState({ iconType });
      }
    
      // handleAudio = () => {
      //   console.log('this.refs',this.refs);
      // }
    
      // 拖动时状态
      handleDrag = (value, id) => {
        console.log(value);
        // const audio = this.refs[id.toString()];
        // audio.pause();
        const { values } = this.state;
        values[id] = value;
        this.setState({ values });
      }
    
      // 拖动后进度条位置
      onAfterChange = (value, id) => {
        const { values } = this.state;
        values[id] = value;
        const audio = this.refs[id.toString()];
        audio.removeEventListener('timeupdate', this.updateProgress);
        const { duration } = audio;
        const currentTime = duration * value / 100;
        audio.currentTime = currentTime;
    
        // audio.play();
        console.log('handleDrag', this.refs[id].currentTime)
        this.setState({ values }, () => audio.addEventListener('timeupdate', () => this.updateProgress(id), false));
        // const icon = iconType[id];
        // if (icon === 'pause') {
        //   audio.play();
        // }
      }
      
      // 分页改变
      onChangePager = (current, pageSize) => {
        const pager = {
          current,
          pageSize
        };
        this.handlePhoneRecordData(pager);
        this.setState({
          values: {},
          isPlay: -1,
        })
      }
    
      // 处理每一个电话录音模块
      hanglePhoneItem = () => {
        const { phoneRecordData } = this.props;
        const { iconType, values } = this.state;
        if (phoneRecordData && phoneRecordData.length > 0) {
          return phoneRecordData.map((item) => {
            const { assistName, createTime, url, callTime, id } = item;
            return (
              <div key={id}>
                <div className={styles.phoneInfo}>
                  {dateFormat.YYYYMMDDHHmmss(createTime)}
                  <span className={styles.assistName}>{assistName}</span>
                </div>
    
                <audio style={{ display: 'none' }} ref={id.toString()} src={url} controls ></audio>
    
                <div className={styles.audioItem}>
                  <div className={styles.icon} onClick={() => this.playAudio(id)}>
                    <Icon type={iconType[id]} style={{ color: '#fff'}} />
                  </div>
                  <div className={styles.time}>
                    {this.transTime(callTime)}
                  </div>
                  <Slider
                    onAfterChange={(value) => this.onAfterChange(value, id)}
                    onChange={(value) => this.handleDrag(value, id)}
                    tooltipVisible={false}
                    value={values[id]}
                    className={styles.sliderInfo}
                  />
                  <Select defaultValue={1} onChange={(value) => this.changeMultiple(value, id)} className={styles.selectInfo}>
                    <Option value={0.8}>0.8倍速</Option>
                    <Option value={1}>1倍速</Option>
                    <Option value={1.5}>1.5倍速</Option>
                    <Option value={2}>2倍速</Option>
                  </Select>
                </div>
              </div>
            )
          })
        }
      }
    
      handlePhoneRecord = () => {
        const { handlePhoneRecord } = this.props;
        if (handlePhoneRecord) {
          handlePhoneRecord();
        }
        const { isPlay } = this.state;
        const audio = this.refs[isPlay];
        audio.pause();
        this.setState({
          values: {},
          isPlay: -1,
        })
      }
    
      render() {
        const { 
          phoneVisible,
          phoneLoading,
          phonePager
        } = this.props;
        const { current, total, pageSize } = phonePager || {};
        return (
          <Drawer
            title="电话沟通记录"
            visible={phoneVisible}
            onClose={this.handlePhoneRecord}
            width={676}
          >
            <Spin spinning={phoneLoading}>
              {this.hanglePhoneItem()}
              {
                total ? <Pagination 
                current={current}
                total={total} 
                pageSize={pageSize} 
                onChange={this.onChangePager} 
                className={styles.pager}
              /> : ''
              }
              
            </Spin>
          </Drawer>
        )
      }
    }
    const PhoneRecord: any = connect(({ loading, academicRecord }: { loading: { effects: any }; academicRecord: ModalState }) => ({
      phoneLoading: loading.effects['academicRecord/getPhoneRecordList'],
      ...academicRecord,
    }))(PhoneRecordInfo)
    export default PhoneRecord;
    

    相关文章

      网友评论

          本文标题:音频组件

          本文链接:https://www.haomeiwen.com/subject/dgmlwctx.html