您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

AudioOutputPreview.web.tsx 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import React, { Component } from 'react';
  2. import { WithTranslation } from 'react-i18next';
  3. import { translate } from '../../base/i18n/functions';
  4. // eslint-disable-next-line lines-around-comment
  5. // @ts-ignore
  6. import Audio from '../../base/media/components/Audio.web';
  7. import Button from '../../base/ui/components/web/Button';
  8. import { BUTTON_TYPES } from '../../base/ui/constants.any';
  9. const TEST_SOUND_PATH = 'sounds/ring.mp3';
  10. /**
  11. * The type of the React {@code Component} props of {@link AudioOutputPreview}.
  12. */
  13. interface IProps extends WithTranslation {
  14. /**
  15. * Button className.
  16. */
  17. className?: string;
  18. /**
  19. * The device id of the audio output device to use.
  20. */
  21. deviceId: string;
  22. }
  23. /**
  24. * React component for playing a test sound through a specified audio device.
  25. *
  26. * @augments Component
  27. */
  28. class AudioOutputPreview extends Component<IProps> {
  29. _audioElement: HTMLAudioElement | null;
  30. /**
  31. * Initializes a new AudioOutputPreview instance.
  32. *
  33. * @param {Object} props - The read-only React Component props with which
  34. * the new instance is to be initialized.
  35. */
  36. constructor(props: IProps) {
  37. super(props);
  38. this._audioElement = null;
  39. this._audioElementReady = this._audioElementReady.bind(this);
  40. this._onClick = this._onClick.bind(this);
  41. this._onKeyPress = this._onKeyPress.bind(this);
  42. }
  43. /**
  44. * Updates the audio element when the target output device changes and the
  45. * audio element has re-rendered.
  46. *
  47. * @inheritdoc
  48. * @returns {void}
  49. */
  50. componentDidUpdate() {
  51. this._setAudioSink();
  52. }
  53. /**
  54. * Implements React's {@link Component#render()}.
  55. *
  56. * @inheritdoc
  57. * @returns {ReactElement}
  58. */
  59. render() {
  60. return (
  61. <>
  62. <Button
  63. accessibilityLabel = { this.props.t('deviceSelection.testAudio') }
  64. className = { this.props.className }
  65. labelKey = 'deviceSelection.testAudio'
  66. onClick = { this._onClick }
  67. onKeyPress = { this._onKeyPress }
  68. type = { BUTTON_TYPES.SECONDARY } />
  69. <Audio
  70. setRef = { this._audioElementReady }
  71. src = { TEST_SOUND_PATH } />
  72. </>
  73. );
  74. }
  75. /**
  76. * Sets the instance variable for the component's audio element so it can be
  77. * accessed directly.
  78. *
  79. * @param {Object} element - The DOM element for the component's audio.
  80. * @private
  81. * @returns {void}
  82. */
  83. _audioElementReady(element: HTMLAudioElement) {
  84. this._audioElement = element;
  85. this._setAudioSink();
  86. }
  87. /**
  88. * Plays a test sound.
  89. *
  90. * @private
  91. * @returns {void}
  92. */
  93. _onClick() {
  94. this._audioElement?.play();
  95. }
  96. /**
  97. * KeyPress handler for accessibility.
  98. *
  99. * @param {Object} e - The key event to handle.
  100. *
  101. * @returns {void}
  102. */
  103. _onKeyPress(e: React.KeyboardEvent) {
  104. if (e.key === ' ' || e.key === 'Enter') {
  105. e.preventDefault();
  106. this._onClick();
  107. }
  108. }
  109. /**
  110. * Updates the target output device for playing the test sound.
  111. *
  112. * @private
  113. * @returns {void}
  114. */
  115. _setAudioSink() {
  116. this._audioElement
  117. && this.props.deviceId // @ts-ignore
  118. && this._audioElement.setSinkId(this.props.deviceId);
  119. }
  120. }
  121. export default translate(AudioOutputPreview);