Implements a playback handler for a {HTMLMediaElement}.

Remarks

This handles transport/loop and volume operations for audio sources (HTML media elements). See https://github.com/suterma/replayer-pwa/tree/main/doc/media-handling#readme

Devdoc

Fading is handeled internally with it's own handler.

Implements

Constructors

  • Parameters

    • media: HTMLMediaElement

      The media element to act upon

    • audioSource: ShallowRef<null | MediaElementAudioSourceNode | AudioBufferSourceNode>

      A reference to the audio node, if set. Allows finer control over the media.

    • id: string = ''

      The unique id

    • masterVolume: number = 1

      The overall volume of the output. Can be used to control the output volume in addition to fadings. (Default: 1, representing 0 dBFS)

    • playbackRate: number = DefaultPlaybackRate

      The playback rate. (Default: 1, representing normal speed)

    • pitchShift: number = DefaultPitchShift

    Returns default

Properties

_canPlay: boolean = false

Whether the media data had loaded enough to start playback.

_fader: IAudioFader
_id: string

The uniqe id

_looper: IMediaLooper
_media: HTMLMediaElement

The {HTMLMediaElement} instance to act upon

_omitNextFadeIn: boolean = false

Whether to omit the fade-in operation on the next, subsequent play operation

Remarks

This automatically gets reset at next play operation or any seek operation. It can only be set when the media is not currently playing.

_pitchShiftController: IPitchShiftController
_playbackRateController: IPlaybackRateController
hasLoadedData: boolean = false

Whether the media data has loaded (at least enough to start playback)

Remarks

This implies that metadata also has been loaded already

Devdoc

see HAVE_CURRENT_DATA at https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState#examples

hasLoadedMetadata: boolean = false

Whether the media metadata has loaded. Duration is available now.

isClickToLoadRequired: boolean = false

Flags, whether deferred loading (until a user play click event is handled) is required to further load the track media file data. The flag may be set once after the metadata was successfully loaded.

Remarks

When true, handling of a subsequent play action must first invoke a user-triggered load operation. This specific handling is currently required on (some?) iOS devices, because they only load data upon explicit user interaction.

lastEmittedCurrentTime: null | number = null

Keeper for the last emitted current time, to avoid multiple equal outputs.

onCurrentTimeChanged: SubEventImmediate<number> = ...

Emits a changed current time position, in [seconds].

Remarks

The change can stem fron ongoing playback and/or a seek or loop operation.

Param: currentTime

could be NaN or infinity, depending on the source

onDurationChanged: SubEventImmediate<number> = ...

Emits a changed duration.

Param: duration

could be NaN or infinity, depending on the source

onEnded: SubEventImmediate<void> = ...

Occurs, when the end of the track has been reached and playback has ended.

Remarks

This is not triggered when the track or a range of it is looping. Allows to select the next track in "play all" and "shuffle" mode.

onNextFadeInOmissionChanged: SubEventImmediate<boolean> = ...

Emits a changed next fade-in omission.

Param: omitted

whether the next fade-in is omitted

onPlaybackStateChanged: SubEventImmediate<PlaybackState> = ...

Emits a changed playback state.

Param: playbackState

the playback state.

onSeeked: SubEventImmediate<number> = ...

Emits an ocurred seek operation.

Param: targetTime

the target time of the seek operation

onSeekingChanged: SubEventImmediate<boolean> = ...

Emits a changed seeking state.

Remarks

Seeking is a

Param: seeking

whether the media is currently seeked (while playing or not)

Accessors

  • get canPlay(): boolean
  • Whether the media data had loaded enough to start playback.

    Returns boolean

    Remarks

    This is a shorthand for (playbackState equal to playing or ready). A value of false indicates an a currently non-playable state.

  • get currentTime(): number
  • Gets the current time position in [seconds].

    Returns number

    currentTime - could be NaN or infinity, depending on the source

    Remarks

    This is not necessarily the exact same value as was last emitted via {onCurrentTimeChanged}.

  • get duration(): number
  • Gets the media duration, in [seconds].

    Returns number

    Remarks

    Might be a non-finite number, if data is not (yet) available.

Methods

  • Writes a debug log message message for this component

    Parameters

    • message: string
    • optionalParam: undefined | string | number = undefined

    Returns void

  • Handles the current ready state of the {HTMLMediaElement}'s media, with regard to playability

    Parameters

    • readyState: number

    Returns void

    Remarks

    Decides, whether deferred loading is required.

  • Pauses playback (with a possible fade-out), then seeks to the given position

    Parameters

    • position: number
    • omitNextFadeIn: boolean = false

      When set, omits the fade-in at a subsequent playback start. Default is false.

    Returns void

  • Starts playback from the given temporal position

    Parameters

    • position: number
    • omitNextFadeIn: boolean = false

      When set, omits the fade-in at playback start. Default is false.

    Returns void

    Remarks

    This first seeks to the position, then starts playing (with a possible fade-in)

  • Repeatedly emits an update with the current time

    Returns void

    Remarks

    This is only repeated during ongoing playback.

  • Seeks forward or backward, for the given amount of seconds, if the media is loaded and the position is valid.

    Parameters

    • seconds: number

      amount of time, in [seconds], to seek

    Returns Promise<void>

    Promise - resolves when the seek operation has finished

  • Seeks to the given time position, if the media is loaded and the position is valid.

    Parameters

    • seconds: number

      the temporal position, in [seconds], to seek to

    • waitOnCanPlay: boolean = false

      optionally, whether the promise only resolves when the media can play, instead of already when the seek operation completed. Default is false, only to wait for the seek.

    Returns Promise<void>

    Promise - resolves when the seek operation completed.

    Remarks

    Immediately also advertises the new temporal position

  • Emits the durationChanged event

    Parameters

    • duration: number

      could be NaN or infinity, depending on the source

    Returns void