通用评论

index.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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({
  25. duration: event.target.duration,
  26. isLoading: false,
  27. isPlaying: true
  28. });
  29. this.player.onended = () =>
  30. this.setState({
  31. isPlaying: false,
  32. currentDuration: 0,
  33. isLoading: false
  34. });
  35. this.player.onpause = () =>
  36. this.setState({ isPlaying: false, isLoading: false });
  37. // this.player.onplay = () => this.setState({ isLoading: true });
  38. this.player.ontimeupdate = event =>
  39. this.setState({ currentDuration: event.target.currentTime });
  40. this.player.src = src;
  41. }
  42. }
  43. componentDidUpdate(prevProps) {
  44. if (this.props.src !== prevProps.src) {
  45. this.player.oncanplay = event =>
  46. this.setState({
  47. duration: event.target.duration,
  48. isLoading: false,
  49. isPlaying: true
  50. });
  51. this.player.onended = () =>
  52. this.setState({
  53. isPlaying: false,
  54. currentDuration: 0,
  55. isLoading: false
  56. });
  57. this.player.onpause = () =>
  58. this.setState({ isPlaying: false, isLoading: false });
  59. // this.player.onplay = () => this.setState({ isPlaying: false });
  60. this.player.ontimeupdate = event =>
  61. this.setState({ currentDuration: event.target.currentTime });
  62. this.player.src = this.props.src;
  63. }
  64. }
  65. clickPlayOrPause(isPlaying) {
  66. if (!this.player) {
  67. return;
  68. }
  69. if (isPlaying) {
  70. this.player.pause();
  71. } else {
  72. // 如果是播放,先暂停其他的播放
  73. const playerList = document.getElementsByTagName("audio");
  74. if (playerList) {
  75. Array.from(playerList).forEach(player => {
  76. if (!player.paused) {
  77. player.pause();
  78. }
  79. });
  80. }
  81. this.player.play();
  82. this.setState({
  83. isLoading: true
  84. });
  85. }
  86. }
  87. getPlayIcon() {
  88. const { isPlaying, isLoading } = this.state;
  89. let playIconElem;
  90. if (isLoading) {
  91. playIconElem = (
  92. <img className="icon-loading" src={iconLoading} alt="iconLoading" />
  93. );
  94. } else if (isPlaying) {
  95. playIconElem = <Icon className="pause" type="pause" />;
  96. } else {
  97. playIconElem = <i className="schedule schedule-icon_image_audio" />;
  98. }
  99. return playIconElem;
  100. }
  101. render() {
  102. const { currentDuration, isPlaying, duration } = this.state;
  103. return (
  104. <div className="comment-item-speak-audio-container">
  105. {/* eslint-disable-next-line jsx-a11y/media-has-caption */}
  106. <audio
  107. ref={ref => {
  108. this.player = ref;
  109. }}
  110. style={{ display: "none" }}
  111. />
  112. <span
  113. className="icon"
  114. onClick={() => {
  115. this.clickPlayOrPause(isPlaying);
  116. }}
  117. >
  118. {this.getPlayIcon()}
  119. </span>
  120. <Slider
  121. step={0.001}
  122. className="slider"
  123. tooltipVisible={false}
  124. value={currentDuration}
  125. max={duration}
  126. onChange={value => {
  127. if (this.player) {
  128. this.player.currentTime = value;
  129. }
  130. }}
  131. />
  132. <span className="time">
  133. {dayjs
  134. .utc(dayjs.duration(currentDuration, "seconds").asMilliseconds())
  135. .format("mm:ss")}
  136. /
  137. {dayjs
  138. .utc(dayjs.duration(duration, "seconds").asMilliseconds())
  139. .format("mm:ss")}
  140. </span>
  141. </div>
  142. );
  143. }
  144. }
  145. export default AudioPlayer;