diff --git a/.github/label-actions.yml b/.github/label-actions.yml index 20f85fd4..47540368 100644 --- a/.github/label-actions.yml +++ b/.github/label-actions.yml @@ -1,6 +1,6 @@ # Configuration for Label Actions - https://github.com/dessant/label-actions -not on Github: +not an Issue: issues: comment: | Ahoi! @@ -9,10 +9,12 @@ not on Github: Many helpful people will not see your message here and you are unlikely to get a useful response. - We use github to handle bugreports, feature requests and - planning new releases. + We use the Github Issue-Tracker only for development related + topics, like feature requests, bug reports etc. To get help, + please join our Discord-Server or ask in Github Discussions: - Please use our Discord-Server for help: [discord.gg/mainsail](https://discord.gg/mainsail) + - [discord.gg/mainsail](https://discord.gg/mainsail) + - [GitHub Discussions](https://github.com/orgs/mainsail-crew/discussions) This ticket will be automatically closed. diff --git a/CHANGELOG.md b/CHANGELOG.md index bd7575e5..7508fefd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,46 @@ # Changelog All notable changes to Crowsnest will be documented in this file. +## [4.1.5](https://github.com/mainsail-crew/crowsnest/releases/tag/v4.1.5) - 2024-02-28 +### Bug Fixes and Improvements + +- Fix ustreamer binary path for v5.52 changes ([#245](https://github.com/mainsail-crew/crowsnest/pull/245)) + +## [4.1.4](https://github.com/mainsail-crew/crowsnest/releases/tag/v4.1.4) - 2024-02-17 +### Bug Fixes and Improvements + +- Support `no_proxy` mode with camera-streamer (bookworm) ([#238](https://github.com/mainsail-crew/crowsnest/pull/238)) + +## [4.1.3](https://github.com/mainsail-crew/crowsnest/releases/tag/v4.1.3) - 2024-01-16 +### Features + +- Add dual picam detection ([#229](https://github.com/mainsail-crew/crowsnest/pull/229)) + +### Documentation + +- Fix buster hint link ([#236](https://github.com/mainsail-crew/crowsnest/pull/236)) + +### Other + +- Fix `clean_apps` for installations without all backends ([#230](https://github.com/mainsail-crew/crowsnest/pull/230)) +- Remove `buildclean` from `make update` ([#231](https://github.com/mainsail-crew/crowsnest/pull/231)) +- Update issue bot to add github discussions ([#234](https://github.com/mainsail-crew/crowsnest/pull/234)) +- Add warning for libcamera on pi5 ([#235](https://github.com/mainsail-crew/crowsnest/pull/235)) + +## [4.1.2](https://github.com/mainsail-crew/crowsnest/releases/tag/v4.1.2) - 2024-01-08 +### Bug Fixes and Improvements + +- **build.sh**: Fix wrong cs branch for cloning ([#215](https://github.com/mainsail-crew/crowsnest/pull/215)) +- Fixes error in detect_legacy ([#217](https://github.com/mainsail-crew/crowsnest/pull/217)) +- Skip do_memory_split on bookworm ([#223](https://github.com/mainsail-crew/crowsnest/pull/223)) +- Fix crash with brokenfocus and camera-streamer ([#224](https://github.com/mainsail-crew/crowsnest/pull/224)) +- Add pi5 support ([#225](https://github.com/mainsail-crew/crowsnest/pull/225)) + +### Other + +- Shallow clone camera-streamer submodules ([#226](https://github.com/mainsail-crew/crowsnest/pull/226)) +- Add note about proxies to crowsnest.conf ([#227](https://github.com/mainsail-crew/crowsnest/pull/227)) + ## [4.1.1](https://github.com/mainsail-crew/crowsnest/releases/tag/v4.1.1) - 2023-11-23 ### Documentation diff --git a/Makefile b/Makefile index 03500e59..ca26bda4 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,6 @@ help: ## Shows this help update: ## Update crowsnest (fetches and pulls repository changes) @git fetch && git pull @bash -c 'bin/build.sh --reclone' - ${MAKE} buildclean ${MAKE} build report: ## Generate report.txt diff --git a/README.md b/README.md index 18d3af21..8f4bff3d 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,10 @@ Not available: :heavy_minus_sign: | Operating System | X86 Architecture | ARM Architecture | | :-------------------------------: | :----------------: | :-----------------------------------------: | -| Raspberry Pi OS (buster) | :heavy_minus_sign: | :x: ([Hint](#hint)) | +| Raspberry Pi OS (buster) | :heavy_minus_sign: | :x: ([Hint](#hint-buster)) | | Raspberry Pi OS (bullseye) | :heavy_minus_sign: | :heavy_check_mark: | | Raspberry Pi OS (bookworm) | :heavy_minus_sign: | :heavy_check_mark: ([Hint](#hint-bookworm)) | -| MainsailOS (<0.7.1) | :heavy_minus_sign: | :x: ([Hint](#hint)) | +| MainsailOS (<0.7.1) | :heavy_minus_sign: | :x: ([Hint](#hint-buster)) | | MainsailOS (>1.0.0) | :heavy_minus_sign: | :heavy_check_mark: (rpi) | | Armbian | :question: | :heavy_check_mark: | | DietPi | :question: | :heavy_check_mark: (rpi) | @@ -90,6 +90,7 @@ See the [README.md](https://github.com/mainsail-crew/crowsnest/tree/legacy/v3) o #### Hint Bookworm Raspberry Pi OS images that are based on Debian 12 (codename 'bookworm') currently use a different branch of [camera-streamer](https://github.com/ayufan/camera-streamer)! +The Raspberry Pi 5 has only [ustreamer](https://github.com/pikvm/ustreamer) support! This is due to the missing JPEG and H264 Hardware encoders. --- diff --git a/bin/build.sh b/bin/build.sh index 08fc203f..05559ff5 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -3,9 +3,9 @@ #### crowsnest - A webcam Service for multiple Cams and Stream Services. #### #### Written by Stephan Wendel aka KwadFan -#### Copyright 2021 - 2023 +#### Copyright 2021 - 2024 #### Co-authored by Patrick Gehrsitz aka mryel00 -#### Copyright 2023 - till today +#### Copyright 2024 - till today #### https://github.com/mainsail-crew/crowsnest #### #### This File is distributed under GPLv3 @@ -111,63 +111,22 @@ is_bookworm() { fi } -is_ubuntu_arm() { - if [[ "$(is_raspberry_pi)" = "1" ]] && - grep -q "ubuntu" /etc/os-release; then +is_pi5() { + if [[ -f /proc/device-tree/model ]] && + grep -q "Raspberry Pi 5" /proc/device-tree/model; then echo "1" else echo "0" fi } -test_load_module() { - if modprobe -n "${1}" &> /dev/null; then - echo 1 +is_ubuntu_arm() { + if [[ "$(is_raspberry_pi)" = "1" ]] && + grep -q "ubuntu" /etc/os-release; then + echo "1" else - echo 0 - fi -} - -shallow_cs_dependencies_check() { - printf "\nChecking for camera-streamer dependencies ...\n" - - printf "Checking if device is a Raspberry Pi ...\n" - if [[ "$(is_raspberry_pi)" = "0" ]]; then - status_msg_build "Checking if device is a Raspberry Pi ..." "3" - printf "This device is not a Raspberry Pi therefore camera-streeamer cannot be installed ..." - return 1 - fi - status_msg_build "Checking if device is a Raspberry Pi ..." "0" - - printf "Checking if device is not running Ubuntu ...\n" - if [[ "$(is_ubuntu_arm)" = "1" ]]; then - status_msg_build "Checking if device is not running Ubuntu ..." "3" - printf "This device is running Ubuntu therefore camera-streeamer cannot be installed ..." - return 1 - fi - status_msg_build "Checking if device is not running Ubuntu ..." "0" - - printf "Checking for required kernel module ...\n" - SHALLOW_CHECK_MODULESLIST="bcm2835_codec" - if [[ "$(test_load_module "${SHALLOW_CHECK_MODULESLIST}")" = "0" ]]; then - status_msg_build "Checking for required kernel module ..." "3" - printf "Not all required kernel modules for camera-streamer can be loaded ..." - return 1 - fi - status_msg_build "Checking for required kernel module ..." "0" - - printf "Checking for required packages ...\n" - # Update the number below if you update SHALLOW_CHECK_PKGLIST - SHALLOW_CHECK_PKGLIST="^(libavformat-dev|libavutil-dev|libavcodec-dev|liblivemedia-dev|libcamera-dev|libcamera-apps-lite)$" - if [[ $(apt-cache search --names-only "${SHALLOW_CHECK_PKGLIST}" | wc -l) -lt 6 ]]; then - status_msg_build "Checking for required packages ..." "3" - printf "Not all required packages for camera-streamer can be installed ..." - return 1 + echo "0" fi - status_msg_build "Checking for required packages ..." "0" - - status_msg_build "Checking for camera-streamer dependencies ..." "0" - return 0 } ### Get avail mem @@ -180,10 +139,10 @@ get_avail_mem() { delete_apps() { for path in "${ALL_PATHS[@]}"; do if [[ ! -d "${path}" ]]; then - printf "'%s' does not exist! Delete skipped ...\n" "${path}" + printf "'%s' does not exist! Delete ... [SKIPPED]\n" "${path}" fi if [[ -d "${path}" ]]; then - printf "Deleting '%s' ... \n" "${path}" + printf "Deleting '%s' ... [DONE]\n" "${path}" rm -rf "${path}" fi done @@ -211,18 +170,11 @@ clone_ustreamer() { clone_cstreamer() { ## Special handling because only supported on Raspberry Pi [[ -n "${CROWSNEST_UNATTENDED}" ]] || CROWSNEST_UNATTENDED="0" - - ## If CROWSNEST_UNATTENDED is 1, CN_INSTALL_CS should be already set - if [[ "${CROWSNEST_UNATTENDED}" = "0" ]] && [[ -z "${CN_INSTALL_CS}" ]]; then - if shallow_cs_dependencies_check; then - CN_INSTALL_CS="1" - else - CN_INSTALL_CS="0" - fi - fi - - if [[ "${CN_INSTALL_CS}" = "0" ]]; then - printf "WARN: Cloning camera-streamer skipped! Device is not supported!" + if { [[ "$(is_raspberry_pi)" = "0" ]] || + [[ "$(is_pi5)" = "1" ]] || + [[ "$(is_ubuntu_arm)" = "1" ]]; } && + [[ "${CROWSNEST_UNATTENDED}" = "0" ]]; then + printf "Device is not supported! Cloning camera-streamer ... [SKIPPED]\n" return fi @@ -262,10 +214,14 @@ clone_apps() { ### Run 'make clean' in cloned folders clean_apps() { for app in "${ALL_PATHS[@]}"; do - printf "\nRunning 'make clean' in %s ... \n" "${app}" - pushd "${app}" &> /dev/null || exit 1 - make clean - popd &> /dev/null || exit 1 + if [[ ! -d "${app}" ]]; then + printf "'%s' does not exist! Clean ... [SKIPPED]\n" "${app}" + else + printf "\nRunning 'make clean' in %s ... \n" "${app}" + pushd "${app}" &> /dev/null || exit 1 + make clean + popd &> /dev/null || exit 1 + fi done printf "\nRunning 'make clean' ... [DONE]\n" } diff --git a/libs/camera-streamer.sh b/libs/camera-streamer.sh index 885557d6..83db8769 100755 --- a/libs/camera-streamer.sh +++ b/libs/camera-streamer.sh @@ -25,7 +25,7 @@ function run_multi() { } function run_ayucamstream() { - local cam_sec ust_bin dev pt res rtsp rtsp_pt fps cstm start_param + local cam_sec ust_bin dev pt res rtsp rtsp_pt fps cstm noprx start_param local v4l2ctl cam_sec="${1}" ust_bin="${BASE_CN_PATH}/bin/camera-streamer/camera-streamer" @@ -36,11 +36,21 @@ function run_ayucamstream() { rtsp=$(get_param "cam ${cam_sec}" enable_rtsp) rtsp_pt=$(get_param "cam ${cam_sec}" rtsp_port) cstm="$(get_param "cam ${cam_sec}" custom_flags 2> /dev/null)" + noprx="$(get_param "crowsnest" no_proxy 2> /dev/null)" ## construct start parameter # set http port # start_param=( --http-port="${pt}" ) + if [[ -n "${noprx}" ]] && [[ "${noprx}" = "true" ]]; then + # See https://github.com/mainsail-crew/crowsnest/pull/221#issuecomment-1863555700 for why + # we cannot assume the binary has support for `--http-listen`. + if ${ust_bin} --help | grep -q "http-listen"; then + start_param+=( --http-listen=0.0.0.0 ) + log_msg "INFO: Set to 'no_proxy' mode! Using 0.0.0.0!" + fi + fi + # Set device start_param+=( --camera-path="${dev}" ) diff --git a/libs/core.sh b/libs/core.sh index 0f1a904c..d37e2b73 100755 --- a/libs/core.sh +++ b/libs/core.sh @@ -82,18 +82,25 @@ function check_dep { function check_apps { local cstreamer ustreamer - ustreamer="bin/ustreamer/ustreamer" + ustreamer_base="bin/ustreamer" + ustreamer="$(find "${BASE_CN_PATH}"/"${ustreamer_base}" \ + -iname 'ustreamer.bin' 2> /dev/null | sed '1q')" cstreamer="bin/camera-streamer/camera-streamer" - if [[ -x "${BASE_CN_PATH}/${ustreamer}" ]]; then - log_msg "Dependency: '${ustreamer##*/}' found in ${ustreamer}." + if [[ -x "${ustreamer}" ]]; then + log_msg "Dependency: '${ustreamer##*/}' found in ${ustreamer_base}/${ustreamer##*/}." + UST_BIN="${ustreamer}" + # shellcheck disable=SC2034 + declare -r UST_BIN else log_msg "Dependency: '${ustreamer##*/}' not found. Exiting!" exit 1 fi ## Avoid dependency check if non rpi sbc - if [[ "$(is_raspberry_pi)" = "1" ]] && [[ "$(is_ubuntu_arm)" = "0" ]]; then + if [[ "$(is_raspberry_pi)" = "1" ]] && + [[ "$(is_ubuntu_arm)" = "0" ]] && + [[ "$(is_pi5)" = "0" ]]; then if [[ -x "${BASE_CN_PATH}/${cstreamer}" ]]; then log_msg "Dependency: '${cstreamer##*/}' found in ${cstreamer}." else diff --git a/libs/hwhandler.sh b/libs/hwhandler.sh index 63b6710d..ceb5bd72 100755 --- a/libs/hwhandler.sh +++ b/libs/hwhandler.sh @@ -65,7 +65,7 @@ detect_libcamera() { [[ -x "$(command -v libcamera-hello)" ]]; then avail="$(libcamera-hello --list-cameras | sed '/^\[.*\].*/d' | awk 'NR==1 {print $1}')" if [[ "${avail}" = "Available" ]]; then - echo "1" + get_libcamera_path | wc -l else echo "0" fi @@ -86,13 +86,16 @@ get_libcamera_path() { # Determine connected "legacy" device function detect_legacy { local avail - if [[ -f /proc/device-tree/model ]] && - grep -q "Raspberry" /proc/device-tree/model; then - avail="$(vcgencmd get_camera | awk -F '=' '{ print $3 }' | cut -d',' -f1)" - else - avail="0" + if [[ "$(is_raspberry_pi)" = "1" ]] && + command -v vcgencmd &> /dev/null; then + if vcgencmd get_camera &> /dev/null ; then + avail="$(vcgencmd get_camera \ + | awk -F '=' '{ print $3 }' \ + | cut -d',' -f1 \ + )" + fi fi - echo "${avail}" + echo "${avail:-0}" } function dev_is_legacy { @@ -128,6 +131,15 @@ is_raspberry_pi() { fi } +is_pi5() { + if [[ -f /proc/device-tree/model ]] && + grep -q "Raspberry Pi 5" /proc/device-tree/model; then + echo "1" + else + echo "0" + fi +} + is_ubuntu_arm() { if [[ "$(is_raspberry_pi)" = "1" ]] && grep -q "ubuntu" /etc/os-release; then diff --git a/libs/init_stream.sh b/libs/init_stream.sh index 4b6dce64..2884c698 100755 --- a/libs/init_stream.sh +++ b/libs/init_stream.sh @@ -27,7 +27,9 @@ function construct_streamer { check_section "${cams}" case ${mode} in [mM]ulti | camera-streamer) - if [[ "$(is_raspberry_pi)" = "1" ]] && [[ "$(is_ubuntu_arm)" = "0" ]]; then + if [[ "$(is_raspberry_pi)" = "1" ]] && + [[ "$(is_ubuntu_arm)" = "0" ]] && + [[ "$(is_pi5)" = "0" ]]; then MULTI_INSTANCES+=( "${cams}" ) else log_msg "WARN: Mode 'camera-streamer' is not supported on your device!" diff --git a/libs/logging.sh b/libs/logging.sh index 167ee392..aef72e09 100755 --- a/libs/logging.sh +++ b/libs/logging.sh @@ -88,7 +88,7 @@ function print_cfg { } function print_cams { - local total v4l + local device total v4l v4l="$(find /dev/v4l/by-id/ -iname "*index0" 2> /dev/null | wc -l)" libcamera="$(detect_libcamera)" legacy="$(detect_legacy)" @@ -100,7 +100,14 @@ function print_cams { log_msg "INFO: Found ${total} total available Device(s)" fi if [[ "${libcamera}" -ne 0 ]]; then - log_msg "Detected 'libcamera' device -> $(get_libcamera_path)" + if [[ "$(is_pi5)" = "1" ]]; then + log_msg "================================================================" + log_msg " WARN: 'libcamera' devices are currently not supported on Pi 5! " + log_msg "================================================================" + fi + for device in $(get_libcamera_path); do + log_msg "Detected 'libcamera' device -> ${device}" + done fi if [[ "${legacy}" -ne 0 ]]; then raspicam="$(v4l2-ctl --list-devices | grep -A1 -e 'mmal' | \ diff --git a/libs/ustreamer.sh b/libs/ustreamer.sh index 3f588eec..88fc1a33 100755 --- a/libs/ustreamer.sh +++ b/libs/ustreamer.sh @@ -24,14 +24,15 @@ run_mjpg() { run_ustreamer "${instance}" & done blockyfix - brokenfocus + brokenfocus "${cams}" return } run_ustreamer() { local cam_sec ust_bin dev pt res fps cstm start_param cam_sec="${1}" - ust_bin="${BASE_CN_PATH}/bin/ustreamer/ustreamer" + # shellcheck disable=SC2153 + ust_bin="${UST_BIN}" dev="$(get_param "cam ${cam_sec}" device)" pt="$(get_param "cam ${cam_sec}" port)" res="$(get_param "cam ${cam_sec}" resolution)" diff --git a/libs/v4l2_control.sh b/libs/v4l2_control.sh index d7630219..167fc3a4 100755 --- a/libs/v4l2_control.sh +++ b/libs/v4l2_control.sh @@ -116,7 +116,7 @@ function brokenfocus { function main { local cur_val conf_val device - for cam in $(configured_cams); do + for cam in ${1}; do device="$(get_param "cam ${cam}" device)" cur_val="$(get_current_value "${device}")" conf_val="$(get_conf_value "${cam}")" @@ -133,7 +133,7 @@ function brokenfocus { } ### MAIN -main +main "${1}" } diff --git a/libs/versioncontrol.sh b/libs/versioncontrol.sh index 806bf120..e477c6fd 100644 --- a/libs/versioncontrol.sh +++ b/libs/versioncontrol.sh @@ -28,7 +28,7 @@ versioncontrol() { local cur_ver avail_ver pushd "${BASE_CN_PATH}"/bin/ustreamer &> /dev/null || exit 1 avail_ver="$(git describe --tags --always)" - cur_ver="v$("${PWD}"/ustreamer -v)" + cur_ver="v$(${UST_BIN} -v)" if [[ "${cur_ver}" == "${avail_ver}" ]]; then vc_log_msg "ustreamer is up to date. (${cur_ver})" fi @@ -42,7 +42,9 @@ versioncontrol() { # Camera Streamer has no version Output yet get_ayucamstream_version() { local cur_ver avail_ver - if [[ "$(is_raspberry_pi)" = "1" ]] && [[ "$(is_ubuntu_arm)" = "0" ]]; then + if [[ "$(is_raspberry_pi)" = "1" ]] && + [[ "$(is_ubuntu_arm)" = "0" ]] && + [[ "$(is_pi5)" = "0" ]]; then pushd "${BASE_CN_PATH}"/bin/camera-streamer &> /dev/null || exit 1 avail_ver="($(git describe --tags --always))" cur_ver="$("${PWD}"/camera-streamer --version | tr -d " ")" diff --git a/resources/crowsnest.conf b/resources/crowsnest.conf index 4a1f2446..ecb841d8 100644 --- a/resources/crowsnest.conf +++ b/resources/crowsnest.conf @@ -17,6 +17,11 @@ #### Port 8082 equals /webcam3/?action=[stream/snapshot] ##### #### Port 8083 equals /webcam4/?action=[stream/snapshot] ##### #### ##### +#### Note: These ports are default for most Mainsail ##### +#### installations. To use any other port would involve ##### +#### changing the proxy configuration or using directly ##### +#### http://:/?action=[stream/snapshot] ##### +#### ##### ##################################################################### #### RTSP Stream URL: ( if enabled and supported ) ##### #### rtsp://:/stream.h264 ##### diff --git a/tools/libs/build_apps.sh b/tools/libs/build_apps.sh index bad40c77..bc4525c8 100755 --- a/tools/libs/build_apps.sh +++ b/tools/libs/build_apps.sh @@ -19,6 +19,29 @@ set -Ee # Debug # set -x +clone_ustreamer() { + ## remove bin/ustreamer if exist + if [[ -d bin/ustreamer ]]; then + rm -rf bin/ustreamer + fi + sudo -u "${BASE_USER}" \ + git clone "${CROWSNEST_USTREAMER_REPO_SHIP}" \ + -b "${CROWSNEST_USTREAMER_REPO_BRANCH}" \ + --depth=1 --single-branch bin/ustreamer +} + +clone_cstreamer() { + ## remove bin/ustreamer if exist + if [[ -d bin/camera-streamer ]]; then + rm -rf bin/camera-streamer + fi + sudo -u "${BASE_USER}" \ + git clone "${CROWSNEST_CAMERA_STREAMER_REPO_SHIP}" \ + --recurse-submodules --shallow-submodules \ + -b "${CROWSNEST_CAMERA_STREAMER_REPO_BRANCH}" \ + --depth=1 --single-branch bin/camera-streamer +} + build_apps() { export CN_INSTALL_CS sudo -E -u "${BASE_USER}" "${PWD}"/bin/build.sh --reclone diff --git a/tools/libs/core.sh b/tools/libs/core.sh index a72bb4a4..3fe80165 100755 --- a/tools/libs/core.sh +++ b/tools/libs/core.sh @@ -67,6 +67,15 @@ is_raspberry_pi() { fi } +is_pi5() { + if [[ -f /proc/device-tree/model ]] && + grep -q "Raspberry Pi 5" /proc/device-tree/model; then + echo "1" + else + echo "0" + fi +} + is_ubuntu_arm() { if [[ "$(is_raspberry_pi)" = "1" ]] && grep -q "ubuntu" /etc/os-release; then @@ -104,6 +113,14 @@ shallow_cs_dependencies_check() { fi status_msg "Checking if device is a Raspberry Pi ..." "0" + msg "Checking if device is not a Raspberry Pi 5 ...\n" + if [[ "$(is_pi5)" = "1" ]]; then + status_msg "Checking if device is not a Raspberry Pi 5 ..." "3" + msg "This device is a Raspberry Pi 5 therefore camera-streeamer cannot be installed ..." + return 1 + fi + status_msg "Checking if device is not a Raspberry Pi 5 ..." "0" + msg "Checking if device is not running Ubuntu ...\n" if [[ "$(is_ubuntu_arm)" = "1" ]]; then status_msg "Checking if device is not running Ubuntu ..." "3" diff --git a/tools/libs/set_gpumem.sh b/tools/libs/set_gpumem.sh index ab183e0f..bf20311f 100755 --- a/tools/libs/set_gpumem.sh +++ b/tools/libs/set_gpumem.sh @@ -34,7 +34,9 @@ set_gpu_mem() { else mem_split=256 fi - if [[ "$(is_raspbian)" = "1" ]] && [[ -n "$(command -v raspi-config)" ]]; then + if [[ "$(is_raspbian)" = "1" ]] && + [[ "$(is_bookworm)" = "0" ]] && + [[ -n "$(command -v raspi-config)" ]]; then if sudo raspi-config nonint do_memory_split "${mem_split}" ;then status_msg "Trying to set minimum GPU Memory to ${mem_split} MB ..." "0" else