flutter-pi

repository·master·Indexed 24 days ago

https://github.com/ardera/flutter-pi

A lightweight Flutter Engine Embedder for Raspberry Pi that enables running Flutter applications directly from the command line without X11 or desktop environments. It supports Raspberry Pi 2, 3, 4, and Zero 2 (W), providing hardware 3D acceleration via KMS and DRI. The project includes tools like flutterpi_tool for app bundle building and supports GStreamer for video playback and ALSA for audio via the audioplayers plugin.

Tokens
4.8K
Snippets
10
Records
19
Agent score
83%

What's inside flutter-pi

  1. What is flutter-pi

    master

    flutter-pi is a lightweight Flutter Engine Embedder designed for Raspberry Pi. It allows running Flutter applications without the need for X11 or a desktop environment (like Raspbian Desktop/LXDE), meaning you can boot directly into the command line for better performance and lower overhead.

    Key Capabilities:

    • Runs without X11.
    • Supports Flutter apps using pure Dart packages.
    • Supports Flutter plugins that use native code, provided you build the platform-specific side of those plugins yourself.
  2. Using Gstreamer and Audioplayers in flutter-pi

    master

    Gstreamer Video Player

    To use the Gstreamer-based video player, rebuild flutter-pi with the necessary Gstreamer dependencies installed. Once rebuilt, you can use the standard Flutter video_player package (VideoPlayer, VideoPlayerController, etc.) without additional Dart-side configuration.

    Audioplayers

    flutter-pi supports audioplayers: ^5.0.0. Follow these requirements:

    • Instance Management: Avoid creating many temporary instances; use a single global AudioPlayer instance to prevent hitting resource limits.
    • Audio Backend: Use ALSA. pulseaudio may interfere with playback. It is recommended to remove the pulseaudio package and ensure gstreamer1.0-alsa is installed.
    • Verification: Ensure audio devices are visible via aplay -L. You can test your setup using gst-launch with playbin on an audio file.
  3. Using PulseAudio with the audioplayers plugin

    master

    The audioplayers plugin has not been tested with pulseaudio. If you choose to use it, you are responsible for configuring GStreamer to work through the PulseAudio subsystem.

    Warning: Because pulseaudio takes full control over audio devices, ALSA will no longer function correctly while pulseaudio is installed.

  4. Supported Platforms for flutter-pi

    master

    flutter-pi is designed for Linux platforms that meet the following requirements:

    Hardware Requirements:

    • Support for hardware 3D acceleration (specifically Kernel-Modesetting (KMS) and Direct Rendering Infrastructure (DRI)).
    • CPU Architecture: ARMv7, ARMv8, x86, or x86_64.

    Compatible Boards:

    • Raspberry Pi 2, 3, and 4 (including 512MB models).
    • Raspberry Pi Zero 2 (W).

    Incompatible Boards:

    • Raspberry Pi Zero (the original).
    • Raspberry Pi 1.
  5. Compile and install flutter-pi from source

    master

    To build flutter-pi on a Raspberry Pi, follow these steps:

    1. Clone the repository recursively:
      git clone --recursive https://github.com/ardera/flutter-pi
      cd flutter-pi
    2. Create a build directory and compile using cmake and make:
      mkdir build && cd build
      cmake ..
      make -j`nproc`
    3. Install the compiled binaries to your system:
      sudo make install
    git clone --recursive https://github.com/ardera/flutter-pi
    cd flutter-pi
    mkdir build && cd build
    cmake ..
    make -j`nproc`
    sudo make install
  6. Build the app.so for Release/Profile mode

    master

    To run in Release or Profile mode, you must build an AOT snapshot (app.so). This process involves building a kernel snapshot on your dev machine and then using gen_snapshot on a Linux x64 machine (or WSL).

    1. Build Kernel Snapshot (Dev Machine): Replace my_app_name and paths as necessary:
      C:\flutter\bin\cache\dart-sdk\bin\dart.exe \
        C:\flutter\bin\cache\dart-sdk\bin\snapshots\frontend_server.dart.snapshot \
        --sdk-root C:\flutter\bin\cache\artifacts\engine\common\flutter_patched_sdk_product \
        --target=flutter \
        --aot \
        --tfa \
        -Ddart.vm.product=true \
        --packages .dart_tool\package_config.json \
        --output-dill build\kernel_snapshot.dill \
        --verbose \
        --depfile build\kernel_snapshot.d \
        package:my_app_name/main.dart
    2. Build app.so (Linux x64/WSL): Use the gen_snapshot_linux_x64_release binary. If building for arm64, omit the --sim-use-hardfp flag.
      gen_snapshot_linux_x64_release \
        --deterministic \
        --snapshot_kind=app-aot-elf \
        --elf=build/flutter_assets/app.so \
        --strip \
        --sim-use-hardfp \
        build/kernel_snapshot.dill
    3. Deploy: Upload both the asset bundle and app.so to the Raspberry Pi.
    gen_snapshot_linux_x64_release \
      --deterministic \
      --snapshot_kind=app-aot-elf \
      --elf=build/flutter_assets/app.so \
      --strip \
      --sim-use-hardfp \
      build/kernel_snapshot.dill
  7. Configure Raspberry Pi for flutter-pi

    master

    To run flutter-pi, you must configure the Raspberry Pi to boot into console mode (to avoid conflicts with X11 or Wayland) and ensure the GPU is properly configured.

    1. Boot Mode: Open sudo raspi-config, navigate to System Options -> Boot / Auto Login, and select Console or Console (Autologin).
    2. Graphics Driver: On Raspberry Pi 4 with Raspbian Bullseye, enable the Fake KMS driver via Advanced Options -> GL Driver -> GL (Fake KMS).
    3. GPU Memory: Set GPU memory to at least 64 (required for omxplayer_video_player) or 16 via Performance Options -> GPU Memory.
    4. Permissions: To allow the pi user to access 3D acceleration without using sudo, run:
      usermod -a -G render pi
      Note: Using sudo to launch flutter-pi is an alternative if you prefer not to change user permissions.

    After these changes, reboot the device.

    sudo raspi-config
    # Follow menu steps for Console mode, GL (Fake KMS), and GPU Memory
    usermod -a -G render pi
  8. Requirements for the audioplayers plugin

    master

    To use the audioplayers plugin with flutter-pi, ensure your environment meets the following criteria:

    1. Flutter Plugin Version: You must use audioplayers version ^4.0.0.
    2. GStreamer: A working GStreamer installation is required, including the appropriate audio plugins (for example, gstreamer1.0-alsa).
  9. Install dependencies for flutter-pi

    master

    Before compiling, install the required system libraries, graphics drivers, and fonts using apt.

    Core Dependencies:

    sudo apt install cmake libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdrm-dev libgbm-dev ttf-mscorefonts-installer fontconfig libsystemd-dev libinput-dev libudev-dev  libxkbcommon-dev

    GStreamer Dependencies (Required if using the GStreamer video player):

    sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-alsa

    Post-Installation: After installing fonts, update the system font cache:

    sudo fc-cache
    sudo apt install cmake libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdrm-dev libgbm-dev ttf-mscorefonts-installer fontconfig libsystemd-dev libinput-dev libudev-dev  libxkbcommon-dev
    
    sudo fc-cache
  10. Build the App Bundle (Old Method, Linux or Windows)

    master

    Use this method if you are not using flutterpi_tool. Ensure your Flutter SDK is compatible with the installed engine binaries.

    1. Build: In your app directory, run:
      flutter build bundle
    2. Deploy: Transfer the ./build/flutter_assets/ directory to the Raspberry Pi.

    Example (flutter_gallery):

    git clone https://github.com/flutter/gallery.git flutter_gallery
    cd flutter_gallery
    git checkout d77920b4ced4a105ad35659fbe3958800d418fb9
    flutter build bundle
    rsync -a ./build/flutter_assets/ pi@raspberrypi:/home/pi/flutter_gallery/
    flutter build bundle
  11. Build and deploy a Flutter application for flutter-pi

    master

    This workflow allows you to develop a Flutter application on an x64 Linux host machine and deploy it to a Raspberry Pi target. It uses a dedicated Flutter SDK instance (flutter-for-pi) to avoid conflicts with your local installation.

    Workflow Overview:

    1. Setup Host Environment: Clone the specific Flutter version matching your target's engine binaries and download the engine binaries.
    2. Create App: Use the local flutter-for-pi binary to create a new project.
    3. Compile for AOT:
      • Build the Flutter bundle.
      • Use the Dart SDK to generate a kernel_snapshot.dill.
      • Use the gen_snapshot_linux_x64_release tool to compile the .dill file into a native app.so (AOT ELF).
    4. Upload: Use rsync to transfer the flutter_assets to the Raspberry Pi.
    5. Run: Use ssh to kill any existing flutter-pi processes and launch the new application in --release mode.
    export VERSION=... # set this to the version determined on the Pi, e.g. 1.22.4
    export ARM=... # set this to "arm" or "arm64"
    export TARGET=... # set this to your Raspberry Pi's hostname
    export APPNAME=hello_pi
    export TARGETUSER=pi # set this to your username on the raspberry pi
    
    mkdir -p ~/dev
    pushd ~/dev
    # one-time setup
    git clone --branch $VERSION https://github.com/flutter/flutter.git flutter-for-pi
    ~/dev/flutter-for-pi/bin/flutter precache
    git clone --depth 1 https://github.com/ardera/flutter-engine-binaries-for-arm engine-binaries
    chmod +x engine-binaries/$ARM/gen_snapshot_linux_x64_release
    
    # create the application
    flutter-for-pi/bin/flutter create $APPNAME
    
    # compile the application
    cd $APPNAME
    ../flutter-for-pi/bin/flutter packages get
    ../flutter-for-pi/bin/flutter build bundle --no-tree-shake-icons --precompiled
    ../flutter-for-pi/bin/cache/dart-sdk/bin/dart \
      ../flutter-for-pi/bin/cache/dart-sdk/bin/snapshots/frontend_server.dart.snapshot \
      --sdk-root ~/dev/flutter-for-pi/bin/cache/artifacts/engine/common/flutter_patched_sdk_product \
      --target=flutter \
      --aot --tfa -Ddart.vm.product=true \
      --packages .dart_tool/package_config.json --output-dill build/kernel_snapshot.dill --depfile build/kernel_snapshot.d \
      package:$APPNAME/main.dart
    
    ../engine-binaries/$ARM/gen_snapshot_linux_x64_release \
      --deterministic --snapshot_kind=app-aot-elf \
      --strip --sim-use-hardfp \
      --elf=build/flutter_assets/app.so build/kernel_snapshot.dill
    
    # upload the application
    rsync --recursive ~/dev/$APPNAME/build/flutter_assets/ $TARGETUSER@$TARGET:dev/$APPNAME
    
    # run the application
    ssh $TARGETUSER@$TARGET "killall" "flutter-pi"
    ssh $TARGETUSER@$TARGET "dev/flutter-pi/build/flutter-pi" "--release" "~/dev/$APPNAME"
    popd
  12. Prepare the Raspberry Pi target for flutter-pi

    master

    To use flutter-pi, you must first prepare your Raspberry Pi by installing necessary system dependencies, configuring user permissions, and building the flutter-pi binary from source.

    Prerequisites:

    • A Raspberry Pi with a touchscreen.
    • A user with sudo privileges.

    Steps:

    1. Add your user to the render group to allow access to GPU resources.
    2. Install required Mesa, DRM, GBM, and font libraries.
    3. Install the pre-compiled Flutter engine binaries for ARM.
    4. Build flutter-pi using cmake and make.

    Note: Pay attention to the ARM architecture output (arm or arm64) and the Flutter version used by the engine binaries, as these are required for the host-side compilation step.

    export APPNAME=hello_pi # change this to the name of your application
    
    # one-time setup
    sudo usermod -a -G render $USER
    sudo apt --yes install libgl1-mesa-dev libgles2-mesa-dev libegl-mesa0 libdrm-dev libgbm-dev
    sudo apt --yes install libsystemd-dev libinput-dev libudev-dev libxkbcommon-dev
    sudo apt --yes install ttf-mscorefonts-installer fontconfig
    sudo fc-cache
    if [ `uname -m` == 'armv7l' ]; then export ARM=arm; else export ARM=arm64; fi
    mkdir -p ~/dev
    pushd ~/dev
    git clone --depth 1 https://github.com/ardera/flutter-engine-binaries-for-arm engine-binaries
    sudo ./engine-binaries/install.sh
    git clone https://github.com/ardera/flutter-pi.git
    cd flutter-pi
    mkdir build && cd build
    cmake ..
    make -j`nproc`
    # per-application setup
    mkdir -p ~/dev/$APPNAME
    popd
    echo You will need to set ARM to: $ARM