123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- // @flow
-
- import React from 'react';
-
- import AbstractAudio from '../AbstractAudio';
- import type { AudioElement } from '../AbstractAudio';
-
- /**
- * The React/Web {@link Component} which is similar to and wraps around
- * {@code HTMLAudioElement} in order to facilitate cross-platform source code.
- */
- export default class Audio extends AbstractAudio {
- /**
- * Set to <code>true</code> when the whole file is loaded.
- */
- _audioFileLoaded: boolean;
-
- /**
- * Reference to the HTML audio element, stored until the file is ready.
- */
- _ref: ?AudioElement;
-
- /**
- * Creates new <code>Audio</code> element instance with given props.
- *
- * @param {Object} props - The read-only properties with which the new
- * instance is to be initialized.
- */
- constructor(props: Object) {
- super(props);
-
- // Bind event handlers so they are only bound once for every instance.
- this._onCanPlayThrough = this._onCanPlayThrough.bind(this);
- this._setRef = this._setRef.bind(this);
- }
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {ReactElement}
- */
- render() {
- return (
- <audio
- loop = { Boolean(this.props.loop) }
- onCanPlayThrough = { this._onCanPlayThrough }
- preload = 'auto'
-
- // $FlowFixMe
- ref = { this._setRef }
- src = { this.props.src } />
- );
- }
-
- /**
- * Stops the audio HTML element.
- *
- * @returns {void}
- */
- stop() {
- if (this._ref) {
- this._ref.pause();
-
- // $FlowFixMe
- this._ref.currentTime = 0;
- }
- }
-
- /**
- * If audio element reference has been set and the file has been
- * loaded then {@link setAudioElementImpl} will be called to eventually add
- * the audio to the Redux store.
- *
- * @private
- * @returns {void}
- */
- _maybeSetAudioElementImpl() {
- if (this._ref && this._audioFileLoaded) {
- this.setAudioElementImpl(this._ref);
- }
- }
-
- _onCanPlayThrough: () => void;
-
- /**
- * Called when 'canplaythrough' event is triggered on the audio element,
- * which means that the whole file has been loaded.
- *
- * @private
- * @returns {void}
- */
- _onCanPlayThrough() {
- this._audioFileLoaded = true;
- this._maybeSetAudioElementImpl();
- }
-
- _setRef: (?AudioElement) => void;
-
- /**
- * Sets the reference to the HTML audio element.
- *
- * @param {HTMLAudioElement} audioElement - The HTML audio element instance.
- * @private
- * @returns {void}
- */
- _setRef(audioElement: ?AudioElement) {
- this._ref = audioElement;
-
- if (audioElement) {
- this._maybeSetAudioElementImpl();
- } else {
- // AbstractAudioElement is supposed to trigger "removeAudio" only if
- // it was previously added, so it's safe to just call it.
- this.setAudioElementImpl(null);
-
- // Reset the loaded flag, as the audio element is being removed from
- // the DOM tree.
- this._audioFileLoaded = false;
- }
- }
- }
|