通用评论

index.js 4.1KB

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