美文网首页
音频组件

音频组件

作者: 糖糖不加糖_ | 来源:发表于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