自定义audio(react)

H5的audio默认的样式可以满足我们录音播放停止等功能,提供的部分固定样式可以修改,如下:
在这里插入图片描述

audio::-webkit-media-controls-panel
audio::-webkit-media-controls-mute-button
audio::-webkit-media-controls-play-button
audio::-webkit-media-controls-timeline-container
audio::-webkit-media-controls-current-time-display
audio::-webkit-media-controls-time-remaining-display
audio::-webkit-media-controls-timeline
audio::-webkit-media-controls-volume-slider-container
audio::-webkit-media-controls-volume-slider
audio::-webkit-media-controls-seek-back-button
audio::-webkit-media-controls-seek-forward-button
audio::-webkit-media-controls-fullscreen-button
audio::-webkit-media-controls-rewind-button
audio::-webkit-media-controls-return-to-realtime-button
audio::-webkit-media-controls-toggle-closed-captions-button

在最新版的谷歌浏览器中,增加了播放速度。
在这里插入图片描述
在之前,我可以通过设置隐藏下载按钮,audio最右边的三个点就可以隐藏,现在需要把播放速度也隐藏了才可以。
我百度了很久,也没有找到播放速度的隐藏方式。

有些时候想要效果H5的audio不能满足,所以就需要自定义audio。
我要实现的效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

期初:因为感觉,播放和时间可以用H5的audio,我的想法是隐藏除了播放按钮和时间显示以外的其他按钮,自己在自定义图标定位上去。
做了很多尝试,通过提供的样式api,可以隐藏进度条,喇叭,但是最右侧的三个点隐藏不了,并且,虽然按钮隐藏了,喇叭音量的滑动效果依然存在。最红还是决定自定义一个audio。
代码如下:
Audio.js

import React, {
    
     Component } from "react";
import {
    
    
    CaretRightOutlined,
    PauseOutlined
} from '@ant-design/icons';
import upload from '@/assets/images/upload.png';
import deleteIcon from '@/assets/images/delete.png';
import axios from 'axios';
import styles from './index.less';


class Audio extends Component {
    
    
    constructor(props) {
    
    
        super(props);
        this.state = {
    
    
            rateList: [1.0, 1.25, 1.5, 2.0],
            playRate: 1.0,
            isPlay: false,
            isMuted: false,
            volume: 100,
            allTime: 0,
            currentTime: 0,
            isDelete: true,
        };
    }

    componentDidMount() {
    
     }

    formatSecond(time) {
    
    
        const second = Math.floor(time % 60);
        let minite = Math.floor(time / 60);
        return `${
      
      minite}:${
      
      second >= 10 ? second : `0${ 
        second}`}`;
    }

    // 该视频已准备好开始播放
    onCanPlay = () => {
    
    
        const {
    
     id } = this.props;
        const audio = document.getElementById(`audio${
      
      id}`);
        this.setState({
    
    
            allTime: audio.duration,
        });
    };

    playAudio = () => {
    
    
        const {
    
     id } = this.props;
        const audio = document.getElementById(`audio${
      
      id}`);
        audio.play();
        this.setState({
    
    
            isPlay: true,
        });
    };

    pauseAudio = () => {
    
    
        const {
    
     id } = this.props;
        const audio = document.getElementById(`audio${
      
      id}`);
        audio.pause();
        this.setState({
    
    
            isPlay: false,
        });
    };

    onMuteAudio = () => {
    
    
        const {
    
     id } = this.props;
        const audio = document.getElementById(`audio${
      
      id}`);
        this.setState({
    
    
            isMuted: !audio.muted,
        });
        audio.muted = !audio.muted;
    };

    changeTime = (e) => {
    
    
        const {
    
     value } = e.target;
        const {
    
     id } = this.props;
        const audio = document.getElementById(`audio${
      
      id}`);
        this.setState({
    
    
            currentTime: value,
        });
        audio.currentTime = value;
        if (value === audio.duration) {
    
    
            this.setState({
    
    
                isPlay: false,
            });
        }
    };

    // 当前播放位置改变时执行
    onTimeUpdate = () => {
    
    
        const {
    
     id } = this.props;
        const audio = document.getElementById(`audio${
      
      id}`);

        this.setState({
    
    
            currentTime: audio.currentTime,
        });
        if (audio.currentTime === audio.duration) {
    
    
            this.setState({
    
    
                isPlay: false,
            });
        }
    };

    changeVolume = (e) => {
    
    
        const {
    
     value } = e.target;
        const {
    
     id } = this.props;
        const audio = document.getElementById(`audio${
      
      id}`);
        audio.volume = value / 100;

        this.setState({
    
    
            volume: value,
            isMuted: !value,
        });
    };

    // 倍速播放
    changePlayRate = (num) => {
    
    
        this.audioDom.playbackRate = num;
        this.setState({
    
    
            playRate: num,
        });
    };

    // 点击下载
    handleUpload = () => {
    
    
        const {
    
     record } = this.props;  //录音信息

        axios({
    
    
            method: 'get',
            url: '视频路径',
            responseType: 'blob',
            headers: {
    
     'content-type': 'audio/mpeg' }
        }).then((res) => {
    
    
            let blobType = 'application/force-download' // 设置blob请求头
            let blob = new Blob([res.data], {
    
     type: res.data.type }) // 创建blob 设置blob文件类型 data 设置为后端返回的文件(例如mp3,jpeg) type:这里设置后端返回的类型 为 mp3
            let downa = document.createElement('a') // 创建A标签
            let href = window.URL.createObjectURL(blob) // 创建下载的链接
            downa.href = href // 下载地址
            downa.download = record.name || '音频' // 下载文件名
            document.body.appendChild(downa)
            downa.click() // 模拟点击A标签
            document.body.removeChild(downa) // 下载完成移除元素
            window.URL.revokeObjectURL(href) // 释放blob对象
        }).catch(function (error) {
    
    
            console.log(error)
        })
    };

    deleteAudio = () => {
    
    
        const {
    
     id } = this.props;
        const audio = document.getElementById(`audio${
      
      id}`);
        // audio.pause();
        this.setState({
    
    
            isDelete: false,
        });
        this.props.onClick();
    };

    render() {
    
    
        const {
    
     src, id, type,bg} = this.props;

        const {
    
    
            isPlay,
            isMuted,
            volume,
            allTime,
            currentTime,
            rateList,
            playRate,
            isDelete
        } = this.state;

        return (
            <div >
                <audio
                    id={
    
    `audio${
      
      id}`}
                    src={
    
    src}
                    ref={
    
    (audio) => {
    
    
                        this.audioDom = audio;
                    }}
                    preload={
    
    "auto"}
                    onCanPlay={
    
    this.onCanPlay}
                    onTimeUpdate={
    
    this.onTimeUpdate}
                >
                    <track src={
    
    src} kind="captions" />
                </audio>
                {
    
    
                    isDelete && <div className={
    
    type === 'delete' ? styles.audio_delete : styles.audio_style} style={
    
    {
    
    background: bg}}>
                        <div className={
    
    styles.audio_left}>
                            {
    
    isPlay ? (
                                <span onClick={
    
    this.pauseAudio}><PauseOutlined className={
    
    styles.audio_play}/></span>
                            ) : (
                                <span onClick={
    
    this.playAudio} > <CaretRightOutlined className={
    
    styles.audio_play}/></span>
                            )}

                            <span className={
    
    styles.audio_time}>
                                {
    
    this.formatSecond(currentTime) + "/" + this.formatSecond(allTime)}
                            </span>
                        </div>
                        {
    
    
                            type === "delete" ? <img src={
    
    deleteIcon} onClick={
    
    this.deleteAudio} className={
    
    styles.download} /> : <img src={
    
    upload} onClick={
    
    this.handleUpload} className={
    
    styles.download} />
                        }
                    </div>
                }
            </div>
        );
    }
}

export default Audio;

index.less

.audio_delete,
.audio_style {
    
    
  width: 192px;
  background: #FFECE5;
  // background: #F2F3F5;
  border-radius: 4px;
  font-weight: 400;
  text-align: center;
  cursor: pointer;
  padding: 0 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;

  .download {
    
    
    width: 16px;
    height: 16px;
  }

  .audio_left {
    
    
    display: inline-block;

    .audio_time {
    
    
      margin-left: 12px;
      color: #5E5E66;
    } 
  }
}

.audio_style {
    
    
  height: 32px;
  line-height: 32px;
  font-size: 12px;
  .audio_play{
    
    
    font-size: 14px;
  }
}

.audio_delete {
    
    
  height: 56px;
  line-height: 56px;
  font-size: 14px;
  .audio_play{
    
    
    font-size: 16px;
  }
}

Guess you like

Origin blog.csdn.net/qq_40657321/article/details/120329405