#!/bin/bash ############################### # VARS ############################### # shellcheck source=/.github/workflows/mock/VERSION source "/etc/VERSION" dsm_version="$productversion $buildnumber-$smallfixnumber" repo_base_url="https://raw.githubusercontent.com/AlexPresso/VideoStation-FFMPEG-Patcher" version="2.0" action="patch" branch="main" ffmpegversion="" wrappers=( "ffmpeg" "gst-launch-1.0" "gst-inspect-1.0" ) vs_base_path=/var/packages/VideoStation vs_path="$vs_base_path/target" libsynovte_path="$vs_path/lib/libsynovte.so" vs_scripts=("preuninst") cp_base_path=/var/packages/CodecPack cp_path="$cp_base_path/target" cp_bin_path="$cp_path/bin" cp_to_patch=( "ffmpeg41:ffmpeg" "ffmpeg27:ffmpeg" "ffmpeg33:ffmpeg" "gst-launch-1.0:gst-launch-1.0" "gst-inspect-1.0:gst-inspect-1.0" ) gstreamer_plugins=( "libgstdtsdec" "libgstlibav" ) gstreamer_libs=( "libavcodec-ffmpeg.so.56" "libavformat-ffmpeg.so.56" "libavutil-ffmpeg.so.54" "libbluray.so.1" "libdca.so.0" "libgme.so.0" "libgnutls-deb0.so.28" "libgsm.so.1" "libhogweed.so.4" "libmodplug.so.1" "libnettle.so.6" "libnuma.so.1" "libopenjpeg.so.5" "libopenjpeg_JPWL.so.5" "libopus.so.0" "liborc-0.4.so.0" "libp11-kit.so.0" "libpng12.so.0" "librtmp.so.1" "libschroedinger-1.0.so.0" "libshine.so.3" "libsoxr.so.0" "libspeex.so.1" "libssh-gcrypt.so.4" "libssh-gcrypt_threads.so.4" "libswresample-ffmpeg.so.1" "libtasn1.so.6" "libtheora.so.0" "libtheoradec.so.1" "libtheoraenc.so.1" "libtwolame.so.0" "libva.so.1" "libvpx.so.2" "libvpx.so.2.0" "libwavpack.so.1" "libwebp.so.5" "libx264.so.146" "libx265.so.59" "libxvidcore.so.4" "libzvbi.so.0" "libzvbi-chains.so.0" "dri/dummy_drv_video.so" "x264-10bit/libx264.so.146" "x265-10bit/libx265.so.59" ) ############################### # UTILS ############################### log() { printf "\e[0;37m[%s] \e[0m[%s] %b" "$(date '+%Y-%m-%d %H:%M:%S')" "$1" "$2$3" } info() { log "INFO" "\e[0m" "$1\n" } error() { log "ERROR" "\e[0;31m" "$1\n" } success() { log "SUCCESS" "\e[0;32m" "$1\n" } welcome_motd() { info "ffmpeg-patcher v$version" download "motd" "$repo_base_url/$branch/motd.txt" /tmp/tmp.wget log "Message of the day" "\033[1;33m" "\n\n$(cat /tmp/tmp.wget)\n\n" sleep 3 } root_check() { if [[ "$EUID" -ne 0 ]]; then error "This tool needs root access (please run 'sudo -i' before proceeding)." exit 1 fi } check_dependencies() { missingDeps=0 for dependency in "${dependencies[@]}"; do if [[ ! -d "/var/packages/$dependency" ]]; then error "Missing $dependency package, please install it and re-run the patcher." missingDeps=1 fi done if [[ $missingDeps -eq 1 ]]; then exit 1 fi } restart_packages() { if [[ -d $cp_bin_path ]]; then if [[ -d "$cp_base_path/etc/gstreamer-1.0" ]]; then info "Clearing CodecPack gstreamer cache..." rm -f "$cp_base_path/etc/gstreamer-1.0/registry.*.bin" fi info "Restarting CodecPack..." synopkg restart CodecPack fi if [[ -d "$vs_base_path/etc/gstreamer-1.0" ]]; then info "Clearing VideoStation gstreamer cache..." rm -f "$vs_base_path/etc/gstreamer-1.0/registry.*.bin" fi info "Restarting VideoStation..." synopkg restart VideoStation } clean() { info "Cleaning orphan files..." rm -f /tmp/tmp.wget rm -f /tmp/ffmpeg.log rm -f /tmp/ffmpeg*.stderr rm -f /tmp/ffmpeg*.stderr.prev rm -f /tmp/gstreamer.log rm -f /tmp/gst*.stderr rm -f /tmp/gst*.stderr.prev } download() { log "INFO" "\e[0m" "Downloading $1... " wget -q -O - "$2" > /tmp/temp.wget downloadStatus=$? if [[ $downloadStatus == 0 ]]; then mv -f /tmp/temp.wget "$3" printf "\e[0;32mDone\n" else printf "\e[0;31mError\n" error "An error occurred while downloading $2. Rolling back changes..." unpatch error "An error occurred while downloading $2, every changes were rolled back." error "Please check your internet connection / GithubStatus. If you think this is an error, please file an issue to the repository." exit 1 fi } ################################ # PATCH PROCEDURES ################################ patch() { check_dependencies info "====== Patching procedure (branch: $branch) ======" if [[ -f "$vs_path/lib/libsynovte.so.orig" ]]; then error "You're trying to patch over an already patched VideoStation, if that's really what you want to do, please unpatch before patching again." exit 1 fi for filename in "${vs_scripts[@]}"; do if [[ -f "$vs_base_path/scripts/$filename" ]]; then info "Saving current $filename script as $filename.orig" mv -n "$vs_base_path/scripts/$filename" "$vs_base_path/scripts/$filename.orig" download "$filename.sh" "$repo_base_url/$branch/scripts/$filename.sh" "$vs_base_path/scripts/$filename" info "Injecting script variables..." repo_full_url="$repo_base_url/$branch" sed -i -e "s|@repo_full_url@|$repo_full_url|" "$vs_base_path/scripts/$filename" chmod 755 "$vs_base_path/scripts/$filename" fi done for filename in "${wrappers[@]}"; do if [[ -f "$vs_path/bin/$filename" ]]; then info "Saving current $filename as $filename.orig" mv -n "$vs_path/bin/$filename" "$vs_path/bin/$filename.orig" download "$filename.sh" "$repo_base_url/$branch/wrappers/$filename.sh" "$vs_path/bin/$filename" chown root:VideoStation "$vs_path/bin/$filename" chmod 750 "$vs_path/bin/$filename" chmod u+s "$vs_path/bin/$filename" fi done if [[ -d $cp_bin_path ]]; then for file in "${cp_to_patch[@]}"; do filename="${file%%:*}" target="${file##*:}" if [[ -f "$cp_bin_path/$filename" ]]; then info "Patching CodecPack's $filename" mv -n "$cp_bin_path/$filename" "$cp_bin_path/$filename.orig" ln -s -f "$vs_path/bin/$target" "$cp_bin_path/$filename" fi done fi if [[ -f "$vs_path/bin/gst-launch-1.0" ]]; then info "Downloading gstreamer plugins..." for plugin in "${gstreamer_plugins[@]}"; do download "Gstreamer plugin: $plugin" "$repo_base_url/$branch/plugins/$plugin.so" "$vs_path/lib/gstreamer/gstreamer-1.0/$plugin.so" done mkdir -p "$vs_path/lib/gstreamer/dri" mkdir -p "$vs_path/lib/gstreamer/x264-10bit" mkdir -p "$vs_path/lib/gstreamer/x265-10bit" for lib in "${gstreamer_libs[@]}"; do download "Gstreamer library: $lib" "$repo_base_url/$branch/libs/$lib" "$vs_path/lib/gstreamer/$lib" done info "Saving current GSTOmx configuration..." mv -n "$vs_path/etc/gstomx.conf" "$vs_path/etc/gstomx.conf.orig" info "Injecting GSTOmx configuration..." cp -n "$cp_path/etc/gstomx.conf" "$vs_path/etc/gstomx.conf" fi download "patch_config.sh" "$repo_base_url/$branch/patch_config.sh" "$vs_base_path/patch_config.sh" info "Setting ffmpeg version to: ffmpeg$ffmpegversion" sed -i -e "s/@ffmpeg_version@/ffmpeg$ffmpegversion/" "$vs_base_path/patch_config.sh" info "Saving current libsynovte.so as libsynovte.so.orig" cp -n "$libsynovte_path" "$libsynovte_path.orig" chown VideoStation:VideoStation "$libsynovte_path.orig" info "Enabling eac3, dts and truehd" sed -i -e 's/eac3/3cae/' -e 's/dts/std/' -e 's/truehd/dheurt/' "$libsynovte_path" restart_packages clean success "Done patching, you can now enjoy your movies ;) (please add a star to the repo if it worked for you)" } unpatch() { info "====== Unpatch procedure ======" if [[ -f "$libsynovte_path.orig" ]]; then info "Restoring libsynovte.so" mv -T -f "$libsynovte_path.orig" "$libsynovte_path" else info "libsynovte.so was not patched, keeping actual file." fi find "$vs_path/bin" -type f -name "*.orig" | while read -r filename; do info "Restoring VideoStation's $filename" mv -T -f "$filename" "${filename::-5}" done find "$vs_base_path/scripts" -type f -name "*.orig" | while read -r filename; do info "Restoring VideoStation's $filename script" mv -T -f "$filename" "${filename::-5}" done if [[ -d $cp_bin_path ]]; then for file in "${cp_to_patch[@]}"; do filename="${file%%:*}" if [[ -f "$cp_bin_path/$filename.orig" ]]; then info "Restoring CodecPack's $filename" mv -T -f "$cp_bin_path/$filename.orig" "$cp_bin_path/$filename" fi done fi if [[ -f "$vs_path/bin/gst-launch-1.0" ]]; then for plugin in "${gstreamer_plugins[@]}"; do info "Removing gstreamer's $plugin plugin" rm -f "$vs_path/lib/gstreamer/gstreamer-1.0/$plugin.so" done for lib in "${gstreamer_libs[@]}"; do info "Removing gstreamer's $lib library" rm -f "$vs_path/lib/gstreamer/$lib" done if [[ -f "$vs_path/etc/gstomx.conf.orig" ]]; then info "Restoring GSTOmx configuration..." mv -T -f "$vs_path/etc/gstomx.conf.orig" "$vs_path/etc/gstomx.conf" else info "GSTOmx configuration was not patched, keeping actual file." fi fi info "Remove patch config." rm -f "$vs_base_path/patch_config.sh" restart_packages clean success "Unpatch complete" } ################################ # ENTRYPOINT ################################ root_check while getopts a:b:p:v: flag; do case "${flag}" in a) action=${OPTARG};; b) branch=${OPTARG};; p) repo_base_url="${OPTARG}/AlexPresso/VideoStation-FFMPEG-Patcher";; v) ffmpegversion="${OPTARG}";; *) echo "usage: $0 [-a patch|unpatch] [-b branch] [-p http://proxy] [-v ffmpegVersion]" >&2; exit 1;; esac done if [[ "$ffmpegversion" == "4" ]]; then ffmpegversion="" fi dependencies=("VideoStation" "ffmpeg$ffmpegversion") welcome_motd info "You're running DSM $dsm_version" if [[ -d /var/packages/CodecPack/target/pack ]]; then cp_path="$cp_base_path/target/pack" cp_bin_path="$cp_path/bin" info "Tuned script for DSM $dsm_version" fi case "$action" in unpatch) unpatch;; patch) patch;; esac