Skip to content

Conversation

@alnitak
Copy link
Owner

@alnitak alnitak commented Mar 4, 2025

Description

Opus and Ogg libraries are currently only used by the BufferStream to receive and fill audio data with Opus format.
To fix #191, and most likely #192, we need to embed the ogg and opus libraries in the Flutter project that uses the plugin.

Previously, MacOS and Linux were using the system opus and ogg libraries if they were available in the OS.

Now the libs are prebuilt for all platforms and stored in the plugin folder. This means that even if they are not needed, the plugin still requires them to work, and the size of the app will grow slightly. To address this, a new environment variable has been introduced that can be used to prevent the prebuilt libs from being linked to the final app.

If trying to use, for example the SoLoud.setBufferStream() function, an exception will be thrown if the environment variable has been set.


How to set the environment variable:

(a new NO_OPUS_OGG_LIBS.md file with this section has been created and linked from README.md)

Linux - Android - Windows

If using VS Code, add NO_OPUS_OGG_LIBS set to an empty string in the env key to the .vscode/launch.json configuration, for example:

{
    "name": "Flutter debug",
    "type": "dart",
    "request": "launch",
    "program": "lib/buffer_stream/websocket.dart",
    "flutterMode": "debug",
    "env": {
        "NO_OPUS_OGG_LIBS": ""
    },
    "cwd": "${workspaceFolder}/example"
}

If using Android Studio, add NO_OPUS_OGG_LIBS="1" in the Run/Debug Configurations configuration under Environment Variables text field.

Alternatively, you can export the variable in the terminal and build the app, for example:

export NO_OPUS_OGG_LIBS="1" && flutter build appbundle

Note that when adding or removing the variable, you need to run flutter clean.

Warning

Side note for Android: It appears that after a flutter clean in your app folder, the plugin build files are not recompiled because they haven't changed. The only solution I've found is to run flutter pub cache clean or, for developers, remove the android/.cxx plugin folder (this might be a Flutter 3.29.0 bug, maybe I should file an issue).

MacOS - iOS

To set the environment variable on MacOS and iOS, you can add the following line to the app/ios/Podfile or app/macos/Podfile at the top of the file:

ENV['NO_OPUS_OGG_LIBS'] = '1'

Alternatively, you can export the variable in the terminal and build the app, for example:

export NO_OPUS_OGG_LIBS="1" && flutter build macos
update: after running this command, if you want to run it again without the env variable, it must be unset:
NO_OPUS_OGG_LIBS= && flutter build macos

Note that when adding or removing the variable, you need to:

  • flutter clean
  • flutter pub get
  • cd macos or cd ios
  • pod install

Note

The environment variable set in VS Code or in Android Studio will be ignored.

Web

To set the environment variable on Web, open web/compile_wasm.sh and change the line NO_OPUS_OGG_LIBS="0" to NO_OPUS_OGG_LIBS="1".
You should then run the script to build the WASM and JS files.
emscripten must be installed

The script works on Linux and probably on MacOS. Windows users should run the script in WSL or wait until a .bat script is available.

Note

The environment variable set in VS Code or in Android Studio will be ignored.

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Bug fix (non-breaking change which fixes an issue)
  • ❌ Breaking change (fix or feature that would cause existing functionality to change)
  • 🧹 Code refactor
  • ✅✅✅✅✅ Build configuration change
  • 📝 Documentation
  • 🗑️ Chore

@alnitak
Copy link
Owner Author

alnitak commented Mar 4, 2025

@filiph please, could you try this on your Mac? It should compile with or without the environment variable (with or without the libs).

@alnitak alnitak requested a review from filiph March 4, 2025 15:43
@filiph
Copy link
Collaborator

filiph commented Mar 4, 2025

Thanks @alnitak for the quick turnaround on this! I can see there's a lot of work behind this.

Here's what I did:

  • I removed the x86_64 versions of libogg and libopus. It felt weird to have them around on an arm64 system and it's definitely not a "normal" setup. I didn't want this to interfere with the test.
  • I pulled the PR (gh pr checkout 195)
  • I deep-cleaned the example/ folder with cd macos && rm -rf Podfile.lock && rm -rf Pods && pod deintegrate && cd - && flutter pub get && cd macos && pod install --repo-update && cd -
  • I tried running flutter run -d macos and also flutter run -d macos lib/buffer_stream/generate.dart. Both worked.
  • I tried building flutter build macos and it also worked, and the app worked correctly.
  • I deep-cleaned again.
  • I ran export NO_OPUS_OGG_LIBS="1" && flutter run -d macos and it worked.
  • Another deep-clean.
  • export NO_OPUS_OGG_LIBS="1" && flutter run -d macos --target "lib/buffer_stream/generate.dart" and it worked. I did not expect this to happen.
  • trying export NO_OPUS_OGG_LIBS="1" && flutter run -d macos --target "lib/buffer_stream/websocket.dart" -- and I get SoLoudOpusOggLibsNotAvailableException
    • So I was testing the wrong example. This is what I expected to happen above but I guess generate.dart doesn't actually use libopus and libogg
  • deep clean
  • export NO_OPUS_OGG_LIBS="1" && flutter build macos --target "lib/buffer_stream/websocket.dart" - correctly builds, runs, and hitting buttons does nothing (as expected, since there's an error -- though it's not reported in any way, it seems)
  • deep clean
  • flutter build macos --target "lib/buffer_stream/websocket.dart" - builds and executes, but then clicking buttons does nothing (like above) -- unexpected
  • deep clean
  • flutter run -d macos --target "lib/buffer_stream/websocket.dart"
    • builds and run
    • clicking "set chosen stream type" once again shows Unhandled Exception: SoLoudOpusOggLibsNotAvailableException: The Opus and Ogg libraries are not available. - not expected

Hope this helps.

@alnitak
Copy link
Owner Author

alnitak commented Mar 5, 2025

Hey Filip, thanks for the detailed description!

I tried and found out that the export NO_OPUS_OGG_LIBS=“1” is persistent. It will be set alongside terminal life even without the export.
So, it needs to be unset while testing.

To test it’s enough to run pod install to clean between tests:

flutter clean
flutter pub get
cd macos
pod install
cd ..

Then:

  • clean && NO_OPUS_OGG_LIBS="1" && flutter run -t lib/buffer_stream/websocket.dart

    • by pressing the button, you should see the exception
  • clean && NO_OPUS_OGG_LIBS= && flutter run -t lib/buffer_stream/websocket.dart

    • by pressing the button you should NOT see the exception

You could also test using the Podfile and instead of running from command line, run it from your IDE:

  • in the macos/Podfile uncomment the ENV['NO_OPUS_OGG_LIBS'] = ‘1’

  • clean

  • run from your IDE

  • in the macos/Podfile comment the ENV['NO_OPUS_OGG_LIBS'] = ‘1’

  • clean

  • run from your IDE

Meanwhile, on Android, I modified the build.gradle to catch when the NO_OPUS_OGG_LIBS environment variable changes and, if this is the case, force the rebuild.

So, to recap, on the other platforms, except MacOS and iOS that are using the above workflow, it’s enough to set the variable in the IDE as explained in the 1st post.

I still need to update the NO_OPUS_OGG_LIBS.md doc.

@filiph
Copy link
Collaborator

filiph commented Mar 6, 2025

Thanks for the info. After doing what you suggested:

$ NO_OPUS_OGG_LIBS= && flutter run -t lib/buffer_stream/websocket.dart

I no longer see the exception. On the other hand, when hitting "set stream" and "play" (there's a typo, btw, it says "paly"), I don't hear a sound. The UI changes but there's nothing. Is that expected?

Screenshot 2025-03-06 at 12 39 42

Same problem when I build the app with

$ export NO_OPUS_OGG_LIBS= && flutter build macos --target "lib/buffer_stream/websocket.dart"

@alnitak
Copy link
Owner Author

alnitak commented Mar 6, 2025

Hey Filip, thanks for your time.

Is that expected?

yes, the app doesn't find a websocket server. But since the plugins compiles without errors and throws an exception when using setBufferStream with format: BufferType.opus (with the paly button :) ) and the libs are not linked, I think the #191 is fixed!!

But it would awesome if you want to try! At the beginning of websocket.dart I wrote some info to use the example.

TL;DR

  • install websocked and ffmpeg: brew install ffmpeg websocketd
  • git clone https://github.com/alnitak/websocketd and run it after modifying the audioPath to set it to your local audio you want to stream.
  • run websocket.dart example of flutter_soloud (using the libs)

To know better how the buffer stream behaves, you can change the bufferingType: BufferingType.released to bufferingType: BufferingType.preserved in the setBufferStream of the websocket.dart example of flutter_soloud

From websocked server, you can set other PCM format if you want. Remember to choose the same format also in the websocket.dart example of flutter_soloud.

Screen.Recording.2025-03-06.at.14.06.31.mp4

update: you can even run the flutter_soloud example on your mobile phone connected to your local wi-fi and it should work.

@filiph
Copy link
Collaborator

filiph commented Mar 7, 2025

Hi Marco, I'm sorry, I don't think I'll have time in the next few days to do this.

@alnitak
Copy link
Owner Author

alnitak commented Mar 7, 2025

No worries, Filip! I totally understand. Since the plugin build is now fixed, you can postpone testing the BufferStream for later when you have more time.

@alnitak alnitak merged commit a4b0ead into main Mar 7, 2025
1 check passed
@alnitak alnitak deleted the opusOgg branch March 7, 2025 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: macOS build fails in latest version

3 participants