GithubHelp home page GithubHelp logo

anthumchris / opus-stream-decoder Goto Github PK

View Code? Open in Web Editor NEW
123.0 7.0 21.0 307 KB

Instantly decode Ogg Opus audio streams in chunks with JavaScript & WebAssembly (Wasm)

Makefile 33.94% JavaScript 49.69% HTML 16.37%
opus-decoder webassembly wasm javascript streams-api libopus opus emscripten decoding-opus-streams ogg-opus

opus-stream-decoder's Introduction

OpusStreamDecoder is an Emscripten JavaScript WebAssembly (Wasm) library for immediately decoding Ogg Opus audio streams (URLs or files) in chunks without waiting for the complete file to download, copy, or read. libopusfile is the underlying C library used for decoding. OpusStreamDecoder provides a lightweight JavaScript API for decoding Opus audio streams at near-native speeds.

Note: This repository was forked from AnthumChris/fetch-stream-audio to decouple OpusStreamDecoder as a standalone Wasm decoder. It will be integrated back into demo as a git submodule for fetch-stream-audio #4.

Usage

Pre-compiled binaries and full examples are included in the dist/ folder. The OpusStreamDecoder API was designed to be simple and the pseudocode below explains its complete usage:

If using a front-end build system, you can obtain OpusStreamDecoder via require or import syntaxes:

const { OpusStreamDecoder } = require('opus-stream-decoder');
import { OpusStreamDecoder } from 'opus-stream-decoder';

Otherwise, include the script bfore you instantiate OpusStreamDecoder.

<script src="opus-stream-decoder.js"></script>
<script>
  // instantiate with onDecode callback that fires when OggOpusFile data is decoded
  const decoder = new OpusStreamDecoder({onDecode});

  // Loop through your Opusdata callingdecode() multiple times. Pass a Uint8Array
  try {
    while(...) {
      decoder.ready.then(_ => decoder.decode(UINT8_DATA_TO_DECODE));
    }
  } catch (e) {
    decoder.ready.then(_ => decoder.free());
  }

  // free up the decoder's memory in WebAssembly (also resets decoder for reuse)
  decoder.ready.then(_ => decoder.free());

  // after free() is called, you could reuse the decoder for another file
  try { ... decoder.ready.then(_ => decoder.decode(UINT8_DATA_TO_DECODE) } ...

  /* Receives decoded Float32Array PCM audio in left/right arrays.
   * sampleRate is always 48000 and both channels would always contain data if
   * samplesDecoded > 0.  Mono Opus files would decoded identically into both
   * left/right channels and multichannel Opus files would be downmixed to 2 channels.
   */
  function onDecode({left, right, samplesDecoded, sampleRate}) {
    console.log(`Decoded ${samplesDecoded} samples`);
    // play back the left/right audio, write to a file, etc
  }
</script>

After instantiating OpusStreamDecoder, decode() should be called repeatedly until you're done reading the stream. You must start decoding from the beginning of the file. Otherwise, a valid Ogg Opus file will not be discovered by libopusfile for decoding. decoder.ready is a Promise that resolves once the underlying WebAssembly module is fetched from the network and instantiated, so ensure you always wait for it to resolve. free() should be called when done decoding, when decode() throws an error, or if you wish to "reset" the decoder and begin decoding a new file with the same instance. free() releases the allocated Wasm memory.

Performance

To achieve optimum decoding performance, OpusStreamDecoder should ideally be run in a Web Worker to keep CPU decoding computations on a sepearate browser thread. (TODO: provide web worker example.)

Additionally, onDecode will be called thousands of times while decoding Opus files. Keep your onDecode callbacks lean. The multiple calls result intentionally because of Opus' unmatched low-latency decoding advantage (read more)—audio is decoded as soon as possible . For example, a 60-second Opus file encoded with a 20ms frame/packet size would yield 3,000 onDecode calls (60 * 1000 / 20), because the underlying libopusfile C decoding function op_read_float_stereo() currently decodes one frame at a time during my tests.

Building

The dist/ folder will contain all required files, tests, and examples after building.

Download Ogg, Opus, and Opusfile C libraries:

$ git submodule update --init

TODO: consider moving this to Makefile

Install Emscripten

Emscripten is used to compile the C libraries to be compatible with WebAssembly. This repo was tested with 1.39.5.

Run the Build

$ make clean dist

The Emscripten module builds in a few seconds, but most of the work will be spent configuring the dependencies libopus, libogg, and libopusfile. You may see the warnings (not errors) below, which don't prevent the build from succeeding. It is not known whether these warnings adversly affect runtime use.

  • Don't have the functions lrint() and lrintf ()
  • Replacing these functions with a standard C cast
  • implicit conversion from 'unsigned int' to 'float'

Build Errors

Error: "autoreconf: command not found"

$ brew install automake

"./autogen.sh: No such file or directory"

$ brew install autogen

Tests & Examples

Two tests exist that will decode an Ogg Opus File with OpusStreamDecoder. Both tests output "decoded N samples." on success.

NodeJS Test

This test writes two decoded left/right PCM audio data to files in tmp/. Install NodeJS and run:

$ make test-wasm-module

HTML Browser Test

This test uses fetch() to decode a URL file stream in chunks. Serve the dist/ folder from a web server and open test-opus-stream-decoder.html in the browser. HTTP/HTTPS schemes are required for Wasm to load—opening it directly with file:// probably won't work.

You can also run SimpleHTTPServer and navigate to http://localhost:8000/test-opus-stream-decoder.html

$ cd dist
$ python -m SimpleHTTPServer 8000

Developing

Emscripten Wasm Module

See files src/*.{js,html} and use $ make and $ make clean to build into dist/

OpusChunkDecoder C interface

See C files src/opus_chunkdecoder* and use $ make native-decode-test, which allows you to compile and test almost instantly. native-decode-test is a fast workflow that ensures things work properly independently of Emscripten and Wasm before you integrate it.

You'll need to install libopusfile binaries natively on your system (on Mac use $ brew install opusfile). Then, declare environment variables with the locations of the installed libopusfile dependencies required by native-decode-test before running:

$ export OPUS_DIR=/usr/local/Cellar/opus/1.2.1
$ export OPUSFILE_DIR=/usr/local/Cellar/opusfile/0.10
$ make native-decode-test

Note: If you see error "fatal error: 'stdarg.h' file not found", try running from a new terminal window that does not have Emscripten initialized.

opus-stream-decoder's People

Contributors

anthumchris avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

opus-stream-decoder's Issues

NodeJS Test Outputs Wrong Message

"File could not be decoded" is incorrectly logged by the nodejs test in newer versions even though the test succeeds. Fails in NodeJS 10+, Succeeds in Node 8.9.1.

$ rm -rf tmp
$ make test-wasm-module 
Downloading decode test file https://fetch-stream-audio.anthum.com/audio/opus/decode-test-64kbps.opus...
tmp/decode-test-64kbps.opus   100%[===============================================>]  49.90K  --.-KB/s    in 0.1s    
Testing 64 kbps Opus file...
File could not be decoded.
OggOpusFile discovered with 16384 bytes

$ ll tmp
    170 .
    374 ..
  51101 decode-test-64kbps.opus
1191640 decoded-left.pcm
1191640 decoded-right.pcm

play it in <audio>

I am receiving stereo 48KHZ Opus encoded audio in in variable (~170 byte) size 20ms chunks extracted from UDP/RTP packets. Can your decoder play it in ? An example code would be appreciated. Regards.

"no such file" error when loaded as NPM package

I published this repo as an NPM package to https://www.npmjs.com/package/opus-stream-decoder.

An error occurs when trying to use opus-stream-decoder after the NPM package is installed.

$ npm i opus-stream-decoder
$ node -e "require('opus-stream-decoder')"
{ Error: ENOENT: no such file or directory, open 'opus-stream-decoder.wasm'
    at Object.openSync (fs.js:448:3)
    at Object.readFileSync (fs.js:348:35)
    ...

One possible solution is to build with emcc --pre-js and declare function Module['locateFile'] that would return a valid path that Emscripten would use for the readFileSync() call.

React init path seems to be broken

I'm not sure if it's intended for this to work in a React app, but I'm seeing issues with with init after overriding the locateFile function for Emscripten, so wasm is being found appropriately.
Current failures are at setting the ctor of the exported function, where global and exports are not defined.
Environment is React/Typescript/Webpack4

_

_

Live Streaming Decoding

Hi, does this have the option for live steram decoding?. I am in need of one. and this is the closest. but not sure if it works. Please let me know, and if you have sample code.
thanks

Mono

What happens if the opus stream is in mono? Which channel should I use left or right?

play raw opus packet

Hello!

How to play encoded opus data packets?

const data = [
        [88, 1, 242, 94, 114, 54, 146, 28, 217, 32, 18, 72, 135, 121, 24, 0, 129, 104, 229, 180, 250, 158, 160, 180, 176, 152, 40, 87, 126, 50, 226, 234, 30, 112, 154, 119, 32, 168, 10, 138, 124, 192],
        [88, 2, 104, 146, 166, 145, 200, 23, 85, 73, 209, 89, 45, 162, 134, 247, 148, 108, 171, 58, 71, 113, 224, 115, 101, 235, 207, 167, 143, 254, 189, 65, 248, 251, 39, 139, 7, 12, 120, 162, 136, 93, 3, 217, 45, 59, 104, 183, 141, 198, 88],
        [88, 225, 133, 148, 11, 113, 79, 203, 245, 33, 23, 1, 111, 242, 127, 166, 124, 77, 80, 206, 201, 4, 46, 120, 172, 180, 198, 175, 214, 17, 158, 107, 38, 208, 157, 86, 106, 116, 157, 134, 67, 11, 67, 72, 66, 63, 148, 57, 223, 187, 160, 221, 189, 230, 146, 206, 101, 105, 170, 212, 130, 69, 185, 2, 150, 40, 34, 137, 103, 191, 231, 179, 210, 132, 250, 175, 190, 8, 86, 238, 133, 49, 179, 160, 232, 74, 216, 48, 151, 87, 138, 236, 2, 42, 158, 8, 250, 0, 82, 18, 235, 250, 197, 1, 1, 16],
        [88, 224, 69, 167, 149, 13, 204, 234, 144, 144, 140, 254, 76, 137, 65, 254, 48, 203, 168, 66, 102, 124, 25, 19, 73, 4, 35, 133, 154, 101, 172, 9, 5, 35, 71, 31, 53, 134, 49, 79, 211, 203, 88, 143, 204, 58, 212, 142, 111, 26, 122, 216, 110, 191, 247, 29, 222, 248, 223, 109, 211, 97, 5, 80, 124, 190, 230, 85, 117, 108, 115, 228, 137, 178, 247, 25, 137, 64, 249, 155, 211, 213, 1, 117, 204, 0, 50, 88, 105, 166, 68, 190, 37, 213, 77, 207, 207, 196, 212, 52, 63, 154, 120, 136, 18, 21, 13, 36, 234, 96, 169, 137, 161, 71, 57, 108, 38, 96, 188, 88, 19, 187, 203, 253, 239, 30, 68, 87, 80, 77, 42, 54, 224, 87, 140, 126, 45, 223, 55, 106, 137, 139, 176, 226, 100, 96, 112],
        [88, 236, 166, 117, 201, 148, 178, 114, 149, 52, 65, 96, 94, 129, 37, 16, 40, 197, 207, 98, 221, 81, 178, 25, 221, 211, 28, 50, 18, 162, 38, 31, 120, 114, 16, 114, 192, 153, 80, 239, 26, 79, 146, 40, 186, 35, 38, 143, 43, 232, 123, 207, 70, 90, 11, 17, 204, 43, 81, 241, 194, 147, 104, 24, 121, 151, 21, 229, 173, 12, 30, 64, 1, 186, 203, 243, 152, 29, 67, 59, 209, 172, 141, 84, 150, 226, 117, 178, 9, 59, 35, 38, 167, 141, 132, 178, 213, 117, 65, 245, 154, 52, 100, 103, 82, 213, 172, 10, 221, 24, 111, 31, 65, 157, 133, 141, 19, 211, 234, 44, 77, 68, 88, 13, 108, 69, 109, 120, 229, 203, 139, 202, 188, 122, 61, 139, 245, 17, 65, 49, 142, 195, 10],
        [88, 237, 139, 57, 111, 18, 88, 241, 88, 247, 24, 247, 97, 218, 121, 26, 205, 63, 118, 201, 29, 184, 28, 193, 210, 1, 45, 252, 20, 55, 245, 24, 199, 84, 83, 234, 189, 138, 107, 74, 236, 207, 77, 231, 202, 0, 33, 4, 225, 225, 67, 116, 143, 217, 239, 209, 226, 90, 36, 249, 112, 105, 32, 183, 252, 119, 155, 84, 38, 212, 224, 93, 231, 133, 126, 6, 126, 255, 133, 86, 101, 157, 207, 191, 40, 216, 10, 118, 18, 101, 12, 91, 92, 28, 73, 106, 193, 160, 126, 143, 60, 18, 211, 72, 81, 166, 148, 80, 192, 134, 209, 83, 115, 85, 254, 105, 19, 59, 156, 9, 3, 88, 16, 76, 181, 160, 38, 134, 155, 15, 77, 246, 237, 65, 196, 137, 183, 200, 62, 210, 16],
        [88, 236, 243, 225, 74, 18, 11, 46, 42, 245, 198, 199, 14, 228, 166, 70, 108, 195, 97, 141, 237, 67, 9, 54, 91, 158, 43, 92, 168, 31, 121, 149, 179, 248, 80, 106, 108, 198, 252, 21, 31, 246, 175, 234, 108, 49, 215, 233, 238, 168, 252, 248, 144, 181, 36, 233, 248, 48, 212, 164, 139, 13, 24, 216, 52, 161, 49, 98, 61, 208, 111, 115, 10, 152, 46, 142, 216, 49, 159, 88, 179, 113, 142, 213, 45, 16, 136, 98, 237, 164, 107, 106, 149, 154, 116, 177, 131, 53, 224, 237, 39, 125, 45, 220, 110, 141, 121, 29, 100, 18, 230, 74, 181, 3, 14, 159, 149, 40, 205, 248, 104, 111, 169, 34, 255, 130, 160],
        [88, 235, 132, 39, 124, 255, 126, 206, 63, 215, 134, 116, 18, 23, 143, 22, 18, 205, 241, 88, 217, 27, 43, 255, 83, 1, 184, 48, 25, 84, 83, 26, 171, 248, 163, 205, 27, 162, 56, 133, 121, 4, 52, 45, 29, 190, 1, 186, 25, 92, 151, 47, 124, 217, 234, 248, 231, 222, 212, 201, 164, 167, 32, 93, 119, 164, 189, 37, 87, 105, 228, 52, 114, 70, 25, 123, 113, 207, 59, 83, 145, 128, 36, 142, 141, 68, 6, 210, 104, 25, 1, 48, 169, 62, 142, 72, 213, 56, 26, 191, 82, 25, 140, 45, 190, 164, 246, 214, 214, 182, 73, 171, 168, 182, 221, 55, 203, 192, 38, 167, 218, 42, 30, 204, 92, 74, 145, 23, 152, 12, 146, 40, 161, 63, 141, 186, 91, 65, 157],
        [88, 234, 64, 102, 12, 194, 175, 230, 190, 186, 205, 253, 1, 183, 73, 136, 82, 43, 24, 247, 0, 239, 84, 103, 66, 190, 166, 141, 94, 233, 241, 247, 41, 90, 155, 149, 8, 245, 163, 185, 30, 26, 49, 125, 249, 160, 78, 95, 47, 190, 106, 28, 171, 224, 186, 112, 161, 96, 139, 62, 95, 82, 229, 247, 177, 30, 186, 41, 224, 244, 238, 190, 217, 116, 121, 253, 17, 0, 220, 213, 202, 0, 236, 71, 104, 79, 241, 147, 227, 16, 114, 208, 131, 155, 233, 248, 230, 103, 42, 179, 144, 89, 18, 155, 171, 62, 156, 147, 84, 2, 173, 146, 239, 204, 88, 32, 49, 73, 61, 9, 43, 73, 227, 90, 122, 169, 209, 233, 216, 188, 74, 65, 54, 230, 1, 84, 242, 254, 235, 236, 96, 224],
        [88, 236, 255, 150, 112, 156, 1, 139, 0, 137, 142, 227, 3, 117, 170, 100, 188, 26, 75, 16, 43, 139, 226, 20, 242, 228, 3, 76, 184, 171, 248, 28, 19, 254, 230, 11, 193, 85, 94, 104, 172, 16, 189, 213, 146, 51, 146, 151, 119, 3, 74, 111, 116, 84, 32, 20, 222, 79, 154, 97, 168, 7, 55, 242, 159, 75, 168, 159, 249, 16, 178, 149, 60, 51, 12, 225, 190, 47, 75, 81, 254, 202, 57, 233, 12, 17, 105, 70, 69, 9, 174, 17, 219, 124, 238, 109, 85, 116, 113, 97, 21, 12, 131, 223, 210, 167, 47, 242, 190, 195, 235, 208, 78, 44, 199, 198, 146, 237, 188, 192],
        [88, 236, 92, 133, 67, 66, 59, 222, 43, 100, 83, 158, 151, 232, 102, 209, 102, 72, 52, 231, 78, 55, 12, 188, 56, 17, 179, 99, 46, 90, 153, 240, 113, 103, 53, 47, 127, 117, 209, 140, 132, 76, 213, 95, 246, 227, 42, 126, 50, 17, 156, 228, 5, 212, 135, 128, 54, 68, 151, 142, 235, 212, 135, 125, 149, 86, 181, 33, 81, 239, 154, 99, 118, 218, 135, 236, 220, 25, 142, 118, 119, 140, 241, 222, 144, 95, 150, 75, 229, 34, 201, 240, 138, 112, 14, 159, 89, 45, 170, 14, 80, 254, 108, 222, 195, 66, 77, 56, 173, 227, 99, 107, 239, 113, 253, 209, 38, 168, 158, 173, 142, 61, 206, 94, 159, 44, 41, 52, 7, 104, 32],
        [88, 234, 205, 249, 182, 249, 112, 161, 216, 222, 58, 231, 239, 157, 223, 223, 164, 6, 60, 68, 31, 173, 48, 23, 205, 235, 161, 246, 86, 89, 213, 125, 49, 67, 69, 120, 9, 229, 25, 95, 56, 50, 65, 242, 255, 205, 227, 210, 102, 138, 102, 106, 43, 28, 149, 58, 0, 90, 183, 50, 124, 31, 14, 5, 90, 114, 12, 162, 52, 23, 11, 3, 236, 51, 85, 127, 133, 244, 12, 140, 46, 184, 122, 76, 183, 71, 45, 124, 56, 179, 212, 213, 124, 217, 109, 84, 76, 0, 149, 72, 184, 202, 12, 222, 118, 138, 108, 126, 1, 6, 205, 176, 35, 230, 57, 102, 232, 74, 207, 9, 218, 42, 233, 252, 102, 194, 113, 110, 19, 25, 54, 242, 38, 24],
        [88, 237, 170, 30, 87, 40, 46, 37, 236, 10, 133, 217, 180, 203, 66, 212, 180, 240, 199, 128, 88, 171, 219, 223, 118, 169, 35, 176, 139, 192, 83, 161, 206, 14, 211, 33, 202, 10, 179, 179, 255, 35, 72, 188, 110, 230, 94, 167, 29, 64, 138, 59, 137, 209, 144, 129, 222, 214, 230, 236, 31, 185, 190, 169, 218, 134, 77, 209, 3, 113, 128, 151, 66, 131, 120, 220, 223, 163, 91, 213, 1, 249, 138, 81, 151, 61, 214, 126, 53, 86, 57, 233, 31, 213, 8, 18, 24, 183, 113, 82, 109, 155, 188, 247, 253, 77, 196, 42, 111, 179, 224, 221, 26, 166, 231, 244, 211, 167, 175, 62, 210, 199, 224],
        [88, 238, 52, 216, 85, 14, 25, 155, 71, 210, 82, 240, 231, 91, 91, 73, 230, 79, 15, 128, 209, 32, 150, 186, 91, 180, 100, 119, 33, 83, 152, 91, 120, 226, 142, 226, 117, 239, 162, 6, 187, 125, 21, 122, 133, 229, 23, 246, 74, 34, 249, 122, 65, 78, 154, 42, 127, 131, 64, 65, 108, 150, 5, 255, 209, 97, 78, 53, 254, 94, 190, 143, 99, 105, 189, 183, 124, 108, 241, 227, 76, 97, 177, 173, 31, 219, 129, 244, 19, 132, 191, 230, 2, 120, 45, 48, 111, 35, 201, 180, 167, 125, 248, 202, 108, 26, 228, 120, 9, 173, 224, 220, 160],
        [88, 238, 250, 210, 110, 204, 94, 99, 19, 18, 221, 218, 24, 28, 220, 167, 95, 85, 238, 53, 223, 161, 170, 190, 14, 232, 102, 241, 103, 110, 23, 231, 156, 132, 189, 83, 59, 207, 9, 160, 197, 180, 196, 118, 114, 99, 158, 10, 177, 139, 50, 13, 26, 55, 198, 18, 46, 158, 190, 72, 129, 54, 3, 207, 16, 16, 14, 239, 195, 253, 208, 237, 11, 188, 122, 89, 28, 42, 134, 97, 101, 167, 239, 180, 243, 4, 148, 35, 198, 46, 140, 205, 96, 11, 218, 196, 248, 61, 174, 176, 176, 86, 200, 33, 42, 208, 239, 19, 177, 95, 144, 135, 124, 45, 208, 223, 18, 24, 108, 4],
        [88, 193, 76, 73, 88, 247, 178, 208, 150, 14, 33, 15, 138, 122, 238, 50, 48, 37, 219, 194, 240, 118, 64, 59, 41, 111, 188, 86, 167, 57, 237, 126, 137, 188, 81, 70, 193, 62, 69, 153, 135, 20, 145, 46, 89, 13, 211, 140, 44, 112, 227, 123, 193, 173, 101, 246, 16, 240, 121, 105, 41, 252, 242, 188, 208],
        [88, 6, 11, 130, 75, 95, 183, 27, 195, 224, 160, 175, 213, 130, 22, 152, 102, 2, 96, 79, 227, 238, 0, 181, 73, 2, 52, 38, 52, 203, 95, 127, 252, 224, 151, 101, 8, 43, 222, 143, 218, 39, 46, 220, 113, 247, 163, 133, 136, 228, 30, 23, 207, 88, 34, 35],
        [88, 2, 153, 193, 125, 14, 69, 252, 77, 196, 217, 82, 167, 199, 190, 93, 157, 1, 150, 37, 236, 10, 212, 6, 25, 232, 146, 137, 212, 189, 203, 238, 89, 61, 91, 248, 69, 193, 60, 156, 210, 59, 39, 108, 146, 128, 233]
      ];

Add seeking functionality to the decoder

seeker

Investigate adding a feature like OpusStreamDecoder.seekTo(milliseconds) to start decoding at a specific time within the file. Currently, the decoder only supports decoding a file from the beginning.

Using libopusfile.op_pcm_seek() seems like a good idea. OpusStreamDecoder's underlying C implementation may need to dynamically allocate OpusChunkDecoder.buffer to hold the entire size of the file to decoded file. Then, bytes would be enqueued into buffer at certain positions for op_pcm_seek() to succeed.

Because of Opus' dynamic streaming nature, the total samples/duration of the file would either need to be known beforehand or calculated on the fly (see "how do I get duration..." and "why don't you store the duration..").

Guesswork would be required to decide which bytes would be required to start playing specific time. For example, take a 4mb (4,194,304 bytes) file with a duration of 4:00m (240,000 seconds). If we wanted to start playing at the 1:00m mark, which is 25% of the total duration, we could assume that the byte offset to start reading would be near 25% past the start of the file at 1,048,576 bytes (0.25 * 4194304). We would probably need to pad the beginning of that offset to ensure that the decoder has enough bytes to read packets for the pre-roll decoding, and assuming an Ogg Opus file's maximum page is 64k, that could potentially be enough. These are all initial guesses and ideas.

Streaming audio output/live

Hi there,

Apologies if this is a basic question.

I'm trying to "stream" audio from my PC. Latency isn't super important.

Despite efforts with WebRTC, and modifying the codec/quality- the sound quality is poor.

If i find a way to "stream" to a file, can your library stream the file even though it hasn't been fully "created" yet?

Or did you have another suggestion on how to achieve this?

Thanks :)

Allow reuse of decoder for subsequent files

Allow for the use case where the same decoder is used to play/decode multiple files, similar to a streaming music player like Spotify or iTunes. The decoder should be able to be "reset" and re-used for new/subsequent files, avoiding re-instantiation of the WebAssembly module and any potential side-effects.

Currently, the decode buffer would contain un-decoded Ogg bytes form the previous file if reused. An observed side note: when tested, the decoder still works (due to Opus' recoverability from loss) and recovers from re-starting the decoding of the same file, but this probably won't succeed work for files that contain different bitrates and headers.

A formal reset method would allow a new file's header page to be read and would clear any bytes from previous files.

Decoding opus stream receiving from camera stream.

I am using this opus-stream-decoder for decoding opus stream packets receiving from IP camera camera. But it is not able to decode it and giving error as follows.

Error: Could not enqueue bytes for decoding. You may also have invalid Ogg Opus file. 3 opus-stream-decoder.js:1:20337
ERROR: Cannot enqueue 237 bytes, overflows by 113. Used: 65412/65536, OggOpusFile discovered: false. Try reducing chunk or decode before enqueuing more opus-stream-decoder.js:1:14651

I am receiving opus packet on web socket and giving it to opus-stream-decoder.
I have attached the test.html I am using to this issue you check it.
test.zip
P

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.