Search code examples
javascripttypescripthtml5-audiohttp-live-streaminghls.js

Create MediaStream from Hls.js


I have a HLS stream that I am attaching to an audio element using the Hls.js library. I want to then take that stream and feed it into Wave.js. I want to use the fromStream method to construct the audio waveform visualiser and not fromElement so that I can set the optional connectDestination argument to false.

For creating the media stream that is fed into the Wave.fromStream() constructor, I am following this example that shows how captureStream() can be used to mirror the playback of an audio or video element. My implementation of capturing the stream is as follows.

  let audio = this.audioPlayer.nativeElement;
  let stream;
  if (audio.captureStream) {
    stream = audio.captureStream();
  } else if (audio.mozCaptureStream) {
    stream = audio.mozCaptureStream();
  } else {
    console.error('Stream capture is not supported');
    stream = null;
  }

Stream is then passed into Wave.fromStream().

Unfortunately, when Wave.fromStream() is executed, I get the following error.

core.js:6498 ERROR DOMException: Failed to execute 'createMediaStreamSource' on 'AudioContext': MediaStream has no audio track

This means that the media stream passed into Wave.fromStream, has no audio tracks associated with it. And when I look at my audio element, even with the Hls stream attached to it, logging Audio.audioTracks returns undefined, even though there is a stream of audio playing and being controlled by that audio element. So there is no issue with creating the media stream from the audio element, it is just how Hls.js is attaching the stream to the audio element.

Is there another way to create a media stream object from a Hls stream created by Hls.js?


Solution

  • I have found a solution to the problem which was to create my own customised version of the @foobar404/wave npm package and modify it to accept an input argument which is a pre existing audio context and the final node in the context. this means that I can connect the waveform to the final node in the audio context without then connecting the waveform to the audio context destination or source which is where my errors were coming from.

    See: https://www.npmjs.com/package/wave-external-audio-context