Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

AudioOutputPreview.web.tsx 3.4KB

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