Skip to content

Commit

Permalink
Library updates and additional install experience robustness. (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
hjdhjd authored Oct 14, 2024
1 parent e2e702d commit fe20d8b
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 76 deletions.
81 changes: 37 additions & 44 deletions build-ffmpeg
Original file line number Diff line number Diff line change
Expand Up @@ -788,35 +788,27 @@ if ${NONFREE_AND_GPL}; then

if build "x264" "latest"; then

clone "https://code.videolan.org/videolan/x264.git" "x264-latest"
clone "https://code.videolan.org/videolan/x264.git" "x264-${CURRENT_PACKAGE_VERSION}"
execute ./configure --prefix="${WORKSPACE}" --enable-static --enable-pic

execute make -j ${MJOBS}
execute make install
execute make install-lib-static

build_done "x264" "latest"
build_done "x264" "${CURRENT_PACKAGE_VERSION}"
fi

CONFIGURE_OPTIONS+=("--enable-libx264")
fi

if ${NONFREE_AND_GPL} && (isAppleSilicon || [[ ! "${TARGET_ARCH}" == "arm"* ]]) ; then
# 32-bit ARM platforms like Raspberry Pi don't build x265 cleanly.
if ${NONFREE_AND_GPL} && [[ ! "${TARGET_ARCH}" == "armv7l" ]] ; then

if build "x265" "latest"; then

if isAppleSilicon; then

download "https://bitbucket.org/multicoreware/x265_git/get/931178347b3f73e40798fd5180209654536bbaa5.tar.gz" "x265-3.5.tar.gz" # This is actually 3.4 if looking at x265Versio
else

clone "https://bitbucket.org/multicoreware/x265_git.git" "x265-latest"
fi
clone "https://bitbucket.org/multicoreware/x265_git.git" "x265-${CURRENT_PACKAGE_VERSION}"

cd build/linux || exit
execute cmake -G "Unix Makefiles" ../../source
# execute env CMAKE_INSTALL_PREFIX="${WORKSPACE}" bash ./multilib.sh

rm -rf 8bit 10bit 12bit 2>/dev/null
mkdir -p 8bit 10bit 12bit

Expand Down Expand Up @@ -858,32 +850,33 @@ EOF
sed -i.backup 's/-lgcc_s/-lgcc_eh/g' "${WORKSPACE}/lib/pkgconfig/x265.pc" # The -i.backup is intended and required on macOS: https://stackoverflow.com/questions/5694228/sed-in-place-flag-that-works-both-on-mac-bsd-and-linux
fi

build_done "x265" "latest"
build_done "x265" "${CURRENT_PACKAGE_VERSION}"
fi

CONFIGURE_OPTIONS+=("--enable-libx265")
fi

if [[ ! "${TARGET_ARCH}" == "arm"* ]]; then
if build "libvpx" "1.13.0"; then

download "https://github.com/webmproject/libvpx/archive/refs/tags/v1.13.0.tar.gz" "libvpx-1.13.0.tar.gz"
if build "libvpx" "1.13.0"; then

if [[ "${TARGET_OS}" == "darwin" ]]; then
download "https://github.com/webmproject/libvpx/archive/refs/tags/v1.13.0.tar.gz" "libvpx-1.13.0.tar.gz"

echo "Applying Darwin patch"
sed "s/,--version-script//g" build/make/Makefile > build/make/Makefile.patched
sed "s/-Wl,--no-undefined -Wl,-soname/-Wl,-undefined,error -Wl,-install_name/g" build/make/Makefile.patched > build/make/Makefile
fi
if [[ "${TARGET_OS}" == "darwin" ]]; then

execute ./configure --prefix="${WORKSPACE}" --disable-unit-tests --disable-shared --disable-examples --as=yasm --enable-vp9-highbitdepth
execute make -j ${MJOBS}
execute make install
echo "Applying Darwin patch"
sed "s/,--version-script//g" build/make/Makefile > build/make/Makefile.patched
sed "s/-Wl,--no-undefined -Wl,-soname/-Wl,-undefined,error -Wl,-install_name/g" build/make/Makefile.patched > build/make/Makefile
fi

build_done "libvpx" "1.13.0"
fi
execute ./configure --prefix="${WORKSPACE}" --disable-unit-tests --disable-shared --disable-examples --as=yasm --enable-vp9-highbitdepth
execute make -j ${MJOBS}
execute make install

build_done "libvpx" "1.13.0"
fi

CONFIGURE_OPTIONS+=("--enable-libvpx")
CONFIGURE_OPTIONS+=("--enable-libvpx")
fi

if ${NONFREE_AND_GPL}; then
Expand Down Expand Up @@ -1073,13 +1066,13 @@ if ! isLinux; then

if build "opencore" "0.1.6"; then

download "https://downloads.sourceforge.net/project/opencore-amr/opencore-amr/opencore-amr-0.1.6.tar.gz" "opencore-amr-0.1.6.tar.gz"
download "https://downloads.sourceforge.net/project/opencore-amr/opencore-amr/opencore-amr-${CURRENT_PACKAGE_VERSION}.tar.gz"

execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
execute make -j ${MJOBS}
execute make install

build_done "opencore" "0.1.6"
build_done "opencore" "${CURRENT_PACKAGE_VERSION}"
fi
fi

Expand All @@ -1089,40 +1082,40 @@ if ! isLinux; then

if build "lame" "3.100"; then

download "https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz" "lame-3.100.tar.gz"
download "https://downloads.sourceforge.net/project/lame/lame/3.100/lame-${CURRENT_PACKAGE_VERSION}.tar.gz"

execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
execute make -j ${MJOBS}
execute make install

build_done "lame" "3.100"
build_done "lame" "${CURRENT_PACKAGE_VERSION}"
fi
fi

CONFIGURE_OPTIONS+=("--enable-libmp3lame")

if build "opus" "1.4"; then

download "https://downloads.xiph.org/releases/opus/opus-1.4.tar.gz"
download "https://downloads.xiph.org/releases/opus/opus-${CURRENT_PACKAGE_VERSION}.tar.gz"

execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
execute make -j ${MJOBS}
execute make install

build_done "opus" "1.4"
build_done "opus" "${CURRENT_PACKAGE_VERSION}"
fi

CONFIGURE_OPTIONS+=("--enable-libopus")

if build "speex" "1.2.1"; then

download "https://ftp.osuosl.org/pub/xiph/releases/speex/speex-1.2.1.tar.gz"
download "https://ftp.osuosl.org/pub/xiph/releases/speex/speex-${CURRENT_PACKAGE_VERSION}.tar.gz"

execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
execute make -j ${MJOBS}
execute make install

build_done "speex" "1.2.1"
build_done "speex" "${CURRENT_PACKAGE_VERSION}"
fi

CONFIGURE_OPTIONS+=("--enable-libspeex")
Expand All @@ -1131,18 +1124,18 @@ if ! isLinux; then

if build "libogg" "1.3.5"; then

download "https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-1.3.5.tar.xz"
download "https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-${CURRENT_PACKAGE_VERSION}.tar.xz"

execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
execute make -j ${MJOBS}
execute make install

build_done "libogg" "1.3.5"
build_done "libogg" "${CURRENT_PACKAGE_VERSION}"
fi

if build "libvorbis" "1.3.7"; then

download "https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-1.3.7.tar.gz"
download "https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-${CURRENT_PACKAGE_VERSION}.tar.gz"

if [[ "${TARGET_OS}" == "darwin" ]]; then

Expand All @@ -1153,7 +1146,7 @@ if ! isLinux; then
execute make -j ${MJOBS}
execute make install

build_done "libvorbis" "1.3.7"
build_done "libvorbis" "${CURRENT_PACKAGE_VERSION}"
fi
fi

Expand All @@ -1163,7 +1156,7 @@ if ! isLinux; then

if build "libtheora" "1.1.1"; then

download "https://ftp.osuosl.org/pub/xiph/releases/theora/libtheora-1.1.1.tar.gz"
download "https://ftp.osuosl.org/pub/xiph/releases/theora/libtheora-${CURRENT_PACKAGE_VERSION}.tar.gz"

sed "s/-fforce-addr//g" configure > configure.patched
chmod +x configure.patched
Expand Down Expand Up @@ -1193,23 +1186,23 @@ if ! isLinux; then
execute make -j ${MJOBS}
execute make install

build_done "libtheora" "1.1.1"
build_done "libtheora" "${CURRENT_PACKAGE_VERSION}"
fi
fi

CONFIGURE_OPTIONS+=("--enable-libtheora")

if ${NONFREE_AND_GPL}; then

if build "fdk_aac" "2.0.2"; then
if build "fdk_aac" "2.0.3"; then

download "https://downloads.sourceforge.net/project/opencore-amr/fdk-aac/fdk-aac-2.0.2.tar.gz" "fdk-aac-2.0.2.tar.gz"
download "https://downloads.sourceforge.net/project/opencore-amr/fdk-aac/fdk-aac-${CURRENT_PACKAGE_VERSION}.tar.gz" "fdk-aac-${CURRENT_PACKAGE_VERSION}.tar.gz"

execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static --enable-pic
execute make -j ${MJOBS}
execute make install

build_done "fdk_aac" "2.0.2"
build_done "fdk_aac" "${CURRENT_PACKAGE_VERSION}"
fi

CONFIGURE_OPTIONS+=("--enable-libfdk-aac")
Expand Down
100 changes: 68 additions & 32 deletions install.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const dotenv = require("dotenv");
const get = require("simple-get");
const tar = require("tar");

const DOWNLOAD_RETRY_ATTEMPTS = 2;

function targetFfmpegRelease() {

return "v" + process.env.npm_package_version;
Expand Down Expand Up @@ -111,63 +113,97 @@ async function getDownloadFileName() {
}
}

async function downloadFfmpeg(downloadUrl, ffmpegDownloadPath) {
async function downloadFfmpeg(downloadUrl, ffmpegDownloadPath, retries = DOWNLOAD_RETRY_ATTEMPTS) {

// Open a write stream to the download location.
const tempFile = path.resolve(ffmpegCache(), ".download");
const file = fs.createWriteStream(tempFile);

console.log("Downloading FFmpeg from: %s", downloadUrl);
console.log("Downloading FFmpeg from: " + downloadUrl);

return new Promise((resolve, reject) => {

get({
url: downloadUrl,
}, (err, res) => {
const file = fs.createWriteStream(tempFile);

if(err || res.statusCode !== 200) {
const attemptDownload = () => {

return reject(err);
}
// Download the file.
get(downloadUrl, (err, res) => {

const totalBytes = parseInt(res.headers["content-length"], 10);
let downloadedBytes = 0;
if(err || (res.statusCode !== 200)) {

res.on("data", (chunk) => {
console.log("Download failed. Retrying.");

downloadedBytes = downloadedBytes + chunk.length;
const percent = Math.round((downloadedBytes / totalBytes) * 100) + "%";
process.stdout.write("\r" + percent);
});
// Clean up the incomplete download before proceeding.
if(retries > 0) {

file.on("finish", () => {
file.close();
fs.unlinkSync(tempFile);

console.log(" - Download Complete");
file.close();
});
return downloadFfmpeg(downloadUrl, ffmpegDownloadPath, retries - 1)
.then(resolve)
.catch(reject);
}

return reject(err || new Error("Failed to download after " + (DOWNLOAD_RETRY_ATTEMPTS + 1).toString() + " attempts."));
}

// We ensure totalBytes is never zero so we avoid divide-by-zero errors.
const totalBytes = parseInt(res.headers["content-length"], 10) || 1;
let downloadedBytes = 0;

// Inform users of our progress.
res.on("data", (chunk) => {

downloadedBytes += chunk.length;
process.stdout.write("\r" + Math.round((downloadedBytes / totalBytes) * 100).toString() + "%.");
});

file.on("close", () => {
// Download complete and the file is now closed, rename it.
file.on("close", () => {

fs.renameSync(tempFile, ffmpegDownloadPath);
resolve();
})
fs.renameSync(tempFile, ffmpegDownloadPath);
resolve();
});

file.on("error", (error) => {
// Error handling.
file.on("error", (error) => {

console.log(error);
reject(error)
console.log(error);
reject(error);
});

// All data written - we've completed the download.
file.on("finish", () => console.log(" - download complete."));

res.pipe(file);
}).on("error", (error) => {

console.log("Request error: ", error);

// Clean up the incomplete download before proceeding.
if(retries > 0) {

console.log("Retrying download.");
fs.unlinkSync(tempFile); // Clean up on error

return downloadFfmpeg(downloadUrl, ffmpegDownloadPath, retries - 1)
.then(resolve)
.catch(reject);
}

reject(new Error("Failed after " + (DOWNLOAD_RETRY_ATTEMPTS + 1).toString() + " attempts."));
});
};

res.pipe(file);
})
})
attemptDownload();
});
}

function binaryOk(ffmpegTempPath) {

try {

child_process.execSync(ffmpegTempPath + " -buildconf");

return true;
} catch (e) {

Expand Down Expand Up @@ -273,7 +309,7 @@ async function install() {
// Bootstrap the installation process.
async function bootstrap() {

console.log("Building for version: %s.", targetFfmpegRelease());
console.log("Retrieving FFmpeg from ffmpeg-for-homebridge release: %s.", targetFfmpegRelease());

try {

Expand Down

0 comments on commit fe20d8b

Please sign in to comment.