diff --git a/dev/convert.html b/dev/convert.html index 5b3f922..9f1a6dc 100644 --- a/dev/convert.html +++ b/dev/convert.html @@ -21,7 +21,7 @@ chunked: true, chunkSize: 2**20 }); - const outputFormat = new Metamuxer.OggOutputFormat(); + const outputFormat = new Metamuxer.WavOutputFormat(); const button = document.createElement('button'); button.textContent = 'Cancel'; @@ -77,10 +77,10 @@ //width: 200, //height: 100, }, - trim: { - start: 0, - end: 30 - }, + //trim: { + // start: 0, + // end: 30 + //}, computeProgress: true }); console.log(conversion); @@ -108,7 +108,7 @@ document.body.append(video); video.play(); - //download(new Blob([target.buffer]), 'converted' + outputFormat.fileExtension); + download(new Blob([target.buffer]), 'converted' + outputFormat.fileExtension); function download(blob, filename) { const url = URL.createObjectURL(blob); diff --git a/dev/mux.html b/dev/mux.html index 8acf0c2..f1e031e 100644 --- a/dev/mux.html +++ b/dev/mux.html @@ -43,6 +43,7 @@ format = new Metamuxer.OggOutputFormat(); format = new Metamuxer.Mp4OutputFormat({ fastStart: 'fragmented', minimumFragmentDuration: 2 }); format = new Metamuxer.MkvOutputFormat({ minimumClusterDuration: 2 }); + format = new Metamuxer.WavOutputFormat(); let target = new Metamuxer.BufferTarget(); /* @@ -57,6 +58,30 @@ let output = new Metamuxer.Output({ format, target }); + let sourcy = new Metamuxer.AudioBufferSource({ + codec: 'pcm-s16', + bitrate: Metamuxer.QUALITY_HIGH + }); + output.addAudioTrack(sourcy); + + await output.start(); + + for (let i = 0; i < 1000; i++) { + let buf = new AudioBuffer({ + length: 1024, + sampleRate: 48000, + numberOfChannels: 2 + }); + sourcy.add(buf); + } + + console.log("Done") + + + await output.finalize(); + + await new Promise(() => {}); + /* let videoSource = new Metamuxer.EncodedVideoChunkSource('avc'); output.addTrack(videoSource); diff --git a/src/media-source.ts b/src/media-source.ts index 55aaf58..3269d23 100644 --- a/src/media-source.ts +++ b/src/media-source.ts @@ -278,10 +278,16 @@ class VideoEncoderWrapper { } if (!this.encoderInitialized) { - if (this.ensureEncoderPromise) { + if (!this.ensureEncoderPromise) { + void this.ensureEncoder(videoSample); + } + + // No, this "if" statement is not useless. Sometimes, the above call to `ensureEncoder` might have + // synchronously completed and the encoder is already initialized. In this case, we don't need to await the + // promise anymore. This also fixes nasty async race condition bugs when multiple code paths are calling + // this method: It's important that the call that initialized the encoder go through this code first. + if (!this.encoderInitialized) { await this.ensureEncoderPromise; - } else { - await this.ensureEncoder(videoSample); } } assert(this.encoderInitialized); @@ -763,10 +769,16 @@ class AudioEncoderWrapper { } if (!this.encoderInitialized) { - if (this.ensureEncoderPromise) { + if (!this.ensureEncoderPromise) { + void this.ensureEncoder(audioSample); + } + + // No, this "if" statement is not useless. Sometimes, the above call to `ensureEncoder` might have + // synchronously completed and the encoder is already initialized. In this case, we don't need to await the + // promise anymore. This also fixes nasty async race condition bugs when multiple code paths are calling + // this method: It's important that the call that initialized the encoder go through this code first. + if (!this.encoderInitialized) { await this.ensureEncoderPromise; - } else { - await this.ensureEncoder(audioSample); } } assert(this.encoderInitialized);