通用评论

index.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import React from "react";
  2. import { Slider, Icon } from "antd";
  3. import dayjs from "dayjs";
  4. import durationPlugin from "dayjs/plugin/duration";
  5. import utcPlugin from "dayjs/plugin/utc";
  6. import "./index.less";
  7. import iconLoading from "../../assert/loading.gif";
  8. dayjs.extend(durationPlugin);
  9. dayjs.extend(utcPlugin);
  10. class AudioPlayer extends React.Component {
  11. constructor(props) {
  12. super(props);
  13. this.state = {
  14. duration: 0,
  15. currentDuration: 0,
  16. isPlaying: false,
  17. isLoading: false
  18. };
  19. }
  20. componentDidMount() {
  21. if (this.player) {
  22. const { src } = this.props;
  23. this.player.oncanplay = event =>
  24. this.setState({ duration: event.target.duration });
  25. this.player.onended = () =>
  26. this.setState({ isPlaying: false, currentDuration: 0 });
  27. this.player.onpause = () =>
  28. this.setState({ isPlaying: false, isLoading: false });
  29. this.player.onplay = () =>
  30. this.setState({ isPlaying: false, isLoading: true });
  31. this.player.onplaying = () =>
  32. this.setState({ isPlaying: true, isLoading: false });
  33. this.player.ontimeupdate = event =>
  34. this.setState({ currentDuration: event.target.currentTime });
  35. this.player.src = src;
  36. }
  37. }
  38. componentDidUpdate(prevProps) {
  39. if (this.props.src !== prevProps.src) {
  40. this.player.oncanplay = event =>
  41. this.setState({ duration: event.target.duration });
  42. this.player.onended = () =>
  43. this.setState({ isPlaying: false, currentDuration: 0 });
  44. this.player.onpause = () =>
  45. this.setState({ isPlaying: false, isLoading: false });
  46. this.player.onplay = () =>
  47. this.setState({ isPlaying: false, isLoading: true });
  48. this.player.onplaying = () =>
  49. this.setState({ isPlaying: true, isLoading: false });
  50. this.player.ontimeupdate = event =>
  51. this.setState({ currentDuration: event.target.currentTime });
  52. this.player.src = this.props.src;
  53. }
  54. }
  55. clickPlayOrPause(isPlaying) {
  56. if (!this.player) {
  57. return;
  58. }
  59. if (isPlaying) {
  60. this.player.pause();
  61. } else {
  62. // 如果是播放,先暂停其他的播放
  63. const playerList = document.getElementsByTagName("audio");
  64. if (playerList) {
  65. Array.from(playerList).forEach(player => {
  66. if (!player.paused) {
  67. player.pause();
  68. }
  69. });
  70. }
  71. this.player.play();
  72. }
  73. }
  74. getPlayIcon() {
  75. const { isPlaying, isLoading } = this.state;
  76. let playIconElem;
  77. if (isLoading) {
  78. playIconElem = (
  79. <img className="icon-loading" src={iconLoading} alt="iconLoading" />
  80. );
  81. } else if (isPlaying) {
  82. playIconElem = <Icon className="pause" type="pause" />;
  83. } else {
  84. playIconElem = <i className="schedule schedule-icon_image_audio" />;
  85. }
  86. return playIconElem;
  87. }
  88. render() {
  89. const { currentDuration, isPlaying, duration } = this.state;
  90. return (
  91. <div className="comment-item-speak-audio-container">
  92. {/* eslint-disable-next-line jsx-a11y/media-has-caption */}
  93. <audio
  94. ref={ref => {
  95. this.player = ref;
  96. }}
  97. style={{ display: "none" }}
  98. />
  99. <span
  100. className="icon"
  101. onClick={() => {
  102. this.clickPlayOrPause(isPlaying);
  103. }}
  104. >
  105. {this.getPlayIcon()}
  106. </span>
  107. <Slider
  108. step={0.001}
  109. className="slider"
  110. tooltipVisible={false}
  111. value={currentDuration}
  112. max={duration}
  113. onChange={value => {
  114. if (this.player) {
  115. this.player.currentTime = value;
  116. }
  117. }}
  118. />
  119. <span className="time">
  120. {dayjs
  121. .utc(dayjs.duration(currentDuration, "seconds").asMilliseconds())
  122. .format("mm:ss")}
  123. /
  124. {dayjs
  125. .utc(dayjs.duration(duration, "seconds").asMilliseconds())
  126. .format("mm:ss")}
  127. </span>
  128. </div>
  129. );
  130. }
  131. }
  132. export default AudioPlayer;