Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions packages/jellyfin-server/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
TERMUX_PKG_HOMEPAGE="https://jellyfin.org"
TERMUX_PKG_DESCRIPTION="A free media system for organizing and streaming media (server)"
TERMUX_PKG_LICENSE="GPL-2.0"
TERMUX_PKG_MAINTAINER="@termux"
TERMUX_PKG_VERSION=(
10.11.4
7.1.2.4
)
TERMUX_PKG_SRCURL=(
"https://github.com/jellyfin/jellyfin/archive/refs/tags/v${TERMUX_PKG_VERSION[0]}.tar.gz"
"https://github.com/jellyfin/jellyfin-web/archive/refs/tags/v${TERMUX_PKG_VERSION[0]}.zip"
"https://github.com/jellyfin/jellyfin-ffmpeg/archive/refs/tags/v${TERMUX_PKG_VERSION[1]%.*}-${TERMUX_PKG_VERSION[1]##*.}.tar.gz"
)
TERMUX_PKG_SHA256=(
2701e396ca79f30597c9f44704f65c5c5ef451c9709f17e30f4328a23bfd3cfe
8f183ff655942bdb7b392c731ef0a684301819bddf658e6d27dfa3c064f48a13
51377d573eff0fe6b15028b350406de2ad4696960781620ef1791c19bea41c3b
)
TERMUX_PKG_BUILD_DEPENDS="aspnetcore-targeting-pack-9.0, dotnet-targeting-pack-9.0, libcairo, pango, libjpeg-turbo, giflib, librsvg"
TERMUX_PKG_DEPENDS="libc++, aspnetcore-runtime-9.0, dotnet-host, dotnet-runtime-9.0, libskiasharp, libesqlite3, jellyfin-ffmpeg"
TERMUX_PKG_SERVICE_SCRIPT=(
"jellyfin"
"exec ${TERMUX_PREFIX}/bin/jellyfin 2>&1"
)
TERMUX_PKG_EXCLUDED_ARCHES="arm"
TERMUX_PKG_RM_AFTER_INSTALL="
opt/jellyfin/include
opt/jellyfin/lib/pkgconfig
opt/jellyfin/share
"
termux_step_post_get_source() {
pushd jellyfin-ffmpeg-"${TERMUX_PKG_VERSION[1]%.*}-${TERMUX_PKG_VERSION[1]##*.}"
# If quilt is added to termux-build-helper:
# if [[ -f "debian/patches/series" ]]; then
# quilt push -a
# fi
local _patch;
for _patch in $(<debian/patches/series); do
git apply --whitespace=nowarn "debian/patches/${_patch}"
done
popd
}

termux_step_pre_configure() {
TERMUX_DOTNET_VERSION=9.0
termux_setup_dotnet; termux_setup_nodejs

pushd jellyfin-web-"${TERMUX_PKG_VERSION[0]}"
npm install

# git warning in build log here is normal, the commit hash is not needed
npm run build:production
cp -R ./dist "$TERMUX_PKG_BUILDDIR/jellyfin-web"
popd

pushd jellyfin-ffmpeg-"${TERMUX_PKG_VERSION[1]%.*}-${TERMUX_PKG_VERSION[1]##*.}"
local _ARCH=""
local _FFMPEG_PREFIX="${TERMUX_PREFIX}/opt/jellyfin"
LDFLAGS="-Wl,-rpath=${_FFMPEG_PREFIX}/lib ${LDFLAGS}"

local _EXTRA_CONFIGURE_FLAGS=""
if [ "$TERMUX_ARCH" = "i686" ]; then
_ARCH="x86"
# Specify --disable-asm to prevent text relocations on i686,
# see https://trac.ffmpeg.org/ticket/4928
_EXTRA_CONFIGURE_FLAGS="--disable-asm"
# elif [ "$TERMUX_ARCH" = "arm" ]; then
# _ARCH="armeabi-v7a"
# _EXTRA_CONFIGURE_FLAGS="--enable-neon"
elif [ "$TERMUX_ARCH" = "x86_64" ]; then
_ARCH="x86_64"
elif [ "$TERMUX_ARCH" = "aarch64" ]; then
_ARCH="$TERMUX_ARCH"
_EXTRA_CONFIGURE_FLAGS="--enable-neon"
else
termux_error_exit "Unsupported arch: $TERMUX_ARCH"
fi

# generated using ffmpeg-configureopts.sh
# if names of variables used in this command are changed, please update variable names in ffmpeg-configureopts.sh as well
./configure --prefix="${_FFMPEG_PREFIX}" \
--arch="${_ARCH}" \
--as="$AS" \
--cc="$CC" \
--cxx="$CXX" \
--nm="$NM" \
--ar="$AR" \
--ranlib=llvm-ranlib \
--pkg-config="$PKG_CONFIG" \
--strip="$STRIP" \
--enable-cross-compile \
--extra-version="Jellyfin" \
--extra-cflags="" \
--extra-cxxflags="" \
--extra-ldflags="" \
--extra-ldexeflags="-pie" \
--extra-libs="-ldl -landroid-glob" \
--target-os=android \
--disable-static \
--enable-shared \
--enable-gpl --enable-version3 --disable-ffplay --disable-debug --disable-doc --disable-sdl2 --disable-libxcb --disable-xlib --enable-lto=auto --enable-iconv --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-libxml2 --enable-openssl --enable-lzma --enable-fontconfig --enable-libharfbuzz --enable-libvorbis --enable-opencl --enable-chromaprint --enable-libdav1d --enable-libass --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvpx --enable-libwebp --enable-libopenmpt --enable-libsrt --enable-libsvtav1 --enable-libx264 --enable-libx265 --enable-libzimg \
${_EXTRA_CONFIGURE_FLAGS} \
--disable-vulkan

make -j"$TERMUX_PKG_MAKE_PROCESSES"
make install
popd
}

termux_step_make() {
dotnet publish "$TERMUX_PKG_SRCDIR"/Jellyfin.Server --configuration Release --runtime "$DOTNET_TARGET_NAME" --output "$TERMUX_PKG_BUILDDIR"/build --no-self-contained -p:DebugType=None
dotnet build-server shutdown
}

termux_step_make_install() {
# we provide bionic builds of these in the repo
rm -f "${TERMUX_PKG_BUILDDIR}/build/"{libe_sqlite3,libSkiaSharp,libHarfBuzzSharp}.so
chmod 0700 "${TERMUX_PKG_BUILDDIR}/build"

mv "${TERMUX_PKG_BUILDDIR}/jellyfin-web" "${TERMUX_PKG_BUILDDIR}/build"
# XML cruft generated during build used to provide documentation for functions and objects
find "${TERMUX_PKG_BUILDDIR}/build" -name '*.xml' -type f -exec rm '{}' +
find "${TERMUX_PKG_BUILDDIR}/build" ! \( -name 'jellyfin' -o -type d \) -exec chmod 0600 '{}' \;
find "${TERMUX_PKG_BUILDDIR}/build" \( -name 'jellyfin' -o -type d \) -exec chmod 0700 '{}' \;
mv "${TERMUX_PKG_BUILDDIR}/build" "${TERMUX_PREFIX}/lib/jellyfin"
ln -s "${TERMUX_PREFIX}/lib/jellyfin/jellyfin" "${TERMUX_PREFIX}/bin/jellyfin"
}
# References
# - Jellyfin-FFMPEG
# https://github.com/jellyfin/jellyfin-ffmpeg/blob/jellyfin/builder/build.sh
# https://github.com/termux/termux-packages/tree/master/packages/ffmpeg
# Note: All patches for Jellyfin-FFMPEG should be based off the patched version, see termux_step_post_get_source
# One of the source urls (jellyfin-web) points to a zip to avoid overwriting jellyfin's source archive due to duplicate filename
16 changes: 16 additions & 0 deletions packages/jellyfin-server/ffmpeg-configure.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--- a/jellyfin-ffmpeg-7.1.2-4/configure
+++ b/jellyfin-ffmpeg-7.1.2-4/configure
@@ -5773,13 +5773,9 @@ case $target_os in
striptype=""
;;
android)
- disable symver
enable section_data_rel_ro
add_cflags -fPIE
add_ldexeflags -fPIE -pie
- SLIB_INSTALL_NAME='$(SLIBNAME)'
- SLIB_INSTALL_LINKS=
- SHFLAGS='-shared -Wl,-soname,$(SLIBNAME)'
;;
haiku)
prefix_default="/boot/common"
48 changes: 48 additions & 0 deletions packages/jellyfin-server/ffmpeg-configureopts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash
# generates command line options for jellyfin-ffmpeg configure script
# acceptable inputs:
# ./ffmpeg-configureopts.sh linux64 gpl
# ./ffmpeg-configureopts.sh linuxarm64 gpl
[ -z "$1" ] && set -- linuxarm64 gpl

set -e
cd -- "$(dirname -- "$0")"
FFMPEG_VERSION="$(. build.sh; printf '%s' "${TERMUX_PKG_VERSION[1]%.*}-${TERMUX_PKG_VERSION[1]##*.}")"
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"; trap - EXIT; exit' INT EXIT TERM
cd "$tmp"

git -c advice.detachedHead=false clone --quiet --depth 1 https://github.com/jellyfin/jellyfin-ffmpeg -b v${FFMPEG_VERSION}
cd jellyfin-ffmpeg/builder
<build.sh awk '{print} $0 ~ /^FF_LIBS/ {exit}' > configure.sh
sed -i 's/set -xe/set -e/' configure.sh
sed -i 's/docker/:/' configure.sh

cat <<'EOF' >>configure.sh
printf '%s\n' "./configure --prefix='\${_FFMPEG_PREFIX}'
--arch='\${_ARCH}'
--as='\$AS'
--cc='\$CC'
--cxx='\$CXX'
--nm='\$NM'
--ar='\$AR'
--ranlib=llvm-ranlib
--pkg-config='\$PKG_CONFIG'
--strip='\$STRIP'
--enable-cross-compile
--extra-version='Jellyfin'
--extra-cflags='$FF_CFLAGS'
--extra-cxxflags='$FF_CXXFLAGS'
--extra-ldflags='$FF_LDFLAGS'
--extra-ldexeflags='$FF_LDEXEFLAGS'
--extra-libs='$FF_LIBS -landroid-glob'
--target-os=android
--disable-static
--enable-shared
$FF_CONFIGURE
\${_EXTRA_CONFIGURE_FLAGS}
--disable-vulkan" | sed "s/'/\"/g;$ ! s/$/ \\\\/"
EOF
# disable unused and unneeded options
rm -rf scripts.d/*{rkrga,vulkan,rkmpp,fdk-aac,zvbi,amf,vaapi,ffnvcodec,libvpl,shaderc}*
bash ./configure.sh "$@"
18 changes: 18 additions & 0 deletions packages/jellyfin-server/ffmpeg-libavcodec-allcodecs.c.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--- a/jellyfin-ffmpeg-7.1.2-4/libavcodec/allcodecs.c
+++ b/jellyfin-ffmpeg-7.1.2-4/libavcodec/allcodecs.c
@@ -150,7 +150,6 @@ extern const FFCodec ff_h263_rkmpp_decoder;
extern const FFCodec ff_h264_decoder;
extern const FFCodec ff_h264_v4l2m2m_decoder;
extern const FFCodec ff_h264_mediacodec_decoder;
-extern const FFCodec ff_h264_mediacodec_encoder;
extern const FFCodec ff_h264_mmal_decoder;
extern const FFCodec ff_h264_qsv_decoder;
extern const FFCodec ff_h264_rkmpp_decoder;
@@ -861,6 +861,7 @@ extern const FFCodec ff_h264_videotoolbox_encoder;
extern const FFCodec ff_hevc_amf_encoder;
extern const FFCodec ff_hevc_cuvid_decoder;
extern const FFCodec ff_hevc_d3d12va_encoder;
+extern const FFCodec ff_h264_mediacodec_encoder;
extern const FFCodec ff_hevc_mediacodec_decoder;
extern const FFCodec ff_hevc_mediacodec_encoder;
extern const FFCodec ff_hevc_mf_encoder;
20 changes: 20 additions & 0 deletions packages/jellyfin-server/ffmpeg-libavutil-file_open.c.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--- a/jellyfin-ffmpeg-7.1.2-4/libavutil/file_open.c
+++ b/jellyfin-ffmpeg-7.1.2-4/libavutil/file_open.c
@@ -113,7 +113,7 @@ int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *l
FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
int fd = -1;
#if HAVE_MKSTEMP
- size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */
+ size_t len = strlen(prefix) + strlen("@TERMUX_PREFIX@/tmp/") + 7; /* room for "@TERMUX_PREFIX@/tmp/" and "XXXXXX\0" */
*filename = av_malloc(len);
#elif HAVE_TEMPNAM
void *ptr= tempnam(NULL, prefix);
@@ -139,7 +139,7 @@ int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *l
# endif
fd = open(*filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600);
#else
- snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
+ snprintf(*filename, len, "@TERMUX_PREFIX@/tmp/%sXXXXXX", prefix);
fd = mkstemp(*filename);
#if defined(_WIN32) || defined (__ANDROID__) || defined(__DJGPP__)
if (fd < 0) {
111 changes: 111 additions & 0 deletions packages/jellyfin-server/jellyfin-defaults.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
nonetchange is pretty much mandatory on Android, so we enable it by default
We also make Jellyfin try to use jellyfin-ffmpeg by default, if available

--- a/Emby.Server.Implementations/ConfigurationOptions.cs
+++ b/Emby.Server.Implementations/ConfigurationOptions.cs
@@ -21,7 +21,7 @@ namespace Emby.Server.Implementations
{ SqliteCacheSizeKey, "20000" },
{ FfmpegSkipValidationKey, bool.FalseString },
{ FfmpegImgExtractPerfTradeoffKey, bool.FalseString },
- { DetectNetworkChangeKey, bool.TrueString }
+ { DetectNetworkChangeKey, bool.FalseString }
};
}
}
--- a/Jellyfin.Server/StartupOptions.cs
+++ b/Jellyfin.Server/StartupOptions.cs
@@ -68,10 +68,10 @@ namespace Jellyfin.Server
public string? PublishedServerUrl { get; set; }

/// <summary>
- /// Gets or sets a value indicating whether the server should not detect network status change.
+ /// Gets or sets a value indicating whether the server should detect network status change.
/// </summary>
- [Option("nonetchange", Required = false, HelpText = "Indicates that the server should not detect network status change.")]
- public bool NoDetectNetworkChange { get; set; }
+ [Option("netchange", Required = false, HelpText = "Indicates that the server should detect network status change.")]
+ public bool DetectNetworkChange { get; set; }

/// <summary>
/// Gets or sets the path to an jellyfin backup archive to restore the application to.
@@ -102,9 +102,9 @@ namespace Jellyfin.Server
config.Add(FfmpegPathKey, FFmpegPath);
}

- if (NoDetectNetworkChange)
+ if (DetectNetworkChange)
{
- config.Add(DetectNetworkChangeKey, bool.FalseString);
+ config.Add(DetectNetworkChangeKey, bool.TrueString);
}

return config;
--- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -217,7 +217,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
[GeneratedRegex(@"((?<name>lib\w+)\s+(?<major>[0-9]+)\.\s*(?<minor>[0-9]+))", RegexOptions.Multiline)]
private static partial Regex LibraryRegex();

- public bool ValidateVersion()
+ public bool ValidateVersion(bool noerr = false)
{
string output;
try
@@ -226,13 +226,17 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
catch (Exception ex)
{
- _logger.LogError(ex, "Error validating encoder");
+ if (!noerr) {
+ _logger.LogError(ex, "Error validating encoder");
+ }
return false;
}

if (string.IsNullOrWhiteSpace(output))
{
- _logger.LogError("FFmpeg validation: The process returned no result");
+ if (!noerr) {
+ _logger.LogError("FFmpeg validation: The process returned no result");
+ }
return false;
}

--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -199,7 +199,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
}

- if (!ValidatePath(ffmpegPath))
+ if (ffmpegPathSetMethodText == "system $PATH" && !ValidatePath("@TERMUX_PREFIX@/opt/jellyfin/bin/ffmpeg", true)) {
+ _ffmpegPath = null;
+ }
+ if (string.IsNullOrEmpty(_ffmpegPath) && !ValidatePath(ffmpegPath))
{
_ffmpegPath = null;
_logger.LogError("FFmpeg: Path set by {FfmpegPathSetMethodText} is invalid", ffmpegPathSetMethodText);
@@ -287,17 +290,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary>
/// <param name="path">FQPN to test.</param>
+ /// <param name="noerr">If set to true, logger is not used</param>
/// <returns><c>true</c> if the version validation succeeded; otherwise, <c>false</c>.</returns>
- private bool ValidatePath(string path)
+ private bool ValidatePath(string path, bool noerr = false)
{
if (string.IsNullOrEmpty(path))
{
return false;
}

- bool rc = new EncoderValidator(_logger, path).ValidateVersion();
+ bool rc = new EncoderValidator(_logger, path).ValidateVersion(noerr);
if (!rc)
{
- _logger.LogError("FFmpeg: Failed version check: {Path}", path);
+ if (!noerr) {
+ _logger.LogError("FFmpeg: Failed version check: {Path}", path);
+ }
return false;
}

4 changes: 4 additions & 0 deletions packages/jellyfin-server/jellyfin-ffmpeg.subpackage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
TERMUX_SUBPKG_DESCRIPTION="FFmpeg for Jellyfin with custom extensions and enhancements"
TERMUX_SUBPKG_DEPENDS="libchromaprint, fontconfig, freetype, fribidi, harfbuzz, libandroid-glob, libandroid-stub, libass, libbluray, libbz2, libdav1d, libgmp, libiconv, liblzma, libmp3lame, libopenmpt, libopus, libsrt, libtheora, libvorbis, libvpx, libwebp, libx264, libx265, libxml2, libzimg, ocl-icd, openssl, svt-av1, zlib"
TERMUX_SUBPKG_DEPEND_ON_PARENT=false
TERMUX_SUBPKG_INCLUDE="opt/jellyfin"
31 changes: 31 additions & 0 deletions packages/libesqlite3/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
TERMUX_PKG_HOMEPAGE="https://github.com/ericsink/SQLitePCL.raw"
TERMUX_PKG_DESCRIPTION="SQLitePCLRaw is a Portable Class Library for low-level access to SQLite (native library)"
TERMUX_PKG_LICENSE="Apache-2.0"
TERMUX_PKG_MAINTAINER="@termux"
_COMMIT="cd2922b8867e4360f0976601414bd24a3ad613d8"
_COMMIT_DATE="20250307"
TERMUX_PKG_VERSION="3.49.1.$_COMMIT_DATE"
TERMUX_PKG_SRCURL="https://github.com/ericsink/cb/archive/${_COMMIT}.tar.gz"
TERMUX_PKG_SHA256=4893433d7ff2e12e7ac35095a80710004f496fa4ec2527a3b188fad3d8a6f7e2
TERMUX_PKG_EXCLUDED_ARCHES="arm"

termux_step_make() {
termux_setup_dotnet
local _target_cpu=""
case "$TERMUX_ARCH" in
aarch64) _target_cpu="arm64" ;;
arm) _target_cpu="armhf" ;;
x86_64) _target_cpu="x64" ;;
i686) _target_cpu="x86" ;;
*) termux_error_exit "Unsupported arch: $TERMUX_ARCH"
esac

printf "Building libe_sqlite3.so\n"
( cd "${TERMUX_PKG_SRCDIR}/bld" && dotnet run && "$CC" $CFLAGS @linux_e_sqlite3_"${_target_cpu}".gccargs -lm -ldl )
termux_dotnet_kill
cp "${TERMUX_PKG_SRCDIR}/bld/bin/e_sqlite3/linux/${_target_cpu}/libe_sqlite3.so" "$TERMUX_PKG_BUILDDIR"
}

termux_step_make_install() {
install -Dm600 -t "${TERMUX_PREFIX}/lib" "${TERMUX_PKG_BUILDDIR}/libe_sqlite3.so"
}
Loading
Loading