Skip to content

Commit fe20d8b

Browse files
authored
Library updates and additional install experience robustness. (#96)
1 parent e2e702d commit fe20d8b

File tree

2 files changed

+105
-76
lines changed

2 files changed

+105
-76
lines changed

build-ffmpeg

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -788,35 +788,27 @@ if ${NONFREE_AND_GPL}; then
788788

789789
if build "x264" "latest"; then
790790

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

794794
execute make -j ${MJOBS}
795795
execute make install
796796
execute make install-lib-static
797797

798-
build_done "x264" "latest"
798+
build_done "x264" "${CURRENT_PACKAGE_VERSION}"
799799
fi
800800

801801
CONFIGURE_OPTIONS+=("--enable-libx264")
802802
fi
803803

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

806807
if build "x265" "latest"; then
807808

808-
if isAppleSilicon; then
809-
810-
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
811-
else
812-
813-
clone "https://bitbucket.org/multicoreware/x265_git.git" "x265-latest"
814-
fi
809+
clone "https://bitbucket.org/multicoreware/x265_git.git" "x265-${CURRENT_PACKAGE_VERSION}"
815810

816811
cd build/linux || exit
817-
execute cmake -G "Unix Makefiles" ../../source
818-
# execute env CMAKE_INSTALL_PREFIX="${WORKSPACE}" bash ./multilib.sh
819-
820812
rm -rf 8bit 10bit 12bit 2>/dev/null
821813
mkdir -p 8bit 10bit 12bit
822814

@@ -858,32 +850,33 @@ EOF
858850
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
859851
fi
860852

861-
build_done "x265" "latest"
853+
build_done "x265" "${CURRENT_PACKAGE_VERSION}"
862854
fi
863855

864856
CONFIGURE_OPTIONS+=("--enable-libx265")
865857
fi
866858

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

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

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

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

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

883-
build_done "libvpx" "1.13.0"
884-
fi
872+
execute ./configure --prefix="${WORKSPACE}" --disable-unit-tests --disable-shared --disable-examples --as=yasm --enable-vp9-highbitdepth
873+
execute make -j ${MJOBS}
874+
execute make install
875+
876+
build_done "libvpx" "1.13.0"
877+
fi
885878

886-
CONFIGURE_OPTIONS+=("--enable-libvpx")
879+
CONFIGURE_OPTIONS+=("--enable-libvpx")
887880
fi
888881

889882
if ${NONFREE_AND_GPL}; then
@@ -1073,13 +1066,13 @@ if ! isLinux; then
10731066

10741067
if build "opencore" "0.1.6"; then
10751068

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

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

1082-
build_done "opencore" "0.1.6"
1075+
build_done "opencore" "${CURRENT_PACKAGE_VERSION}"
10831076
fi
10841077
fi
10851078

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

10901083
if build "lame" "3.100"; then
10911084

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

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

1098-
build_done "lame" "3.100"
1091+
build_done "lame" "${CURRENT_PACKAGE_VERSION}"
10991092
fi
11001093
fi
11011094

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

11041097
if build "opus" "1.4"; then
11051098

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

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

1112-
build_done "opus" "1.4"
1105+
build_done "opus" "${CURRENT_PACKAGE_VERSION}"
11131106
fi
11141107

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

11171110
if build "speex" "1.2.1"; then
11181111

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

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

1125-
build_done "speex" "1.2.1"
1118+
build_done "speex" "${CURRENT_PACKAGE_VERSION}"
11261119
fi
11271120

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

11321125
if build "libogg" "1.3.5"; then
11331126

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

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

1140-
build_done "libogg" "1.3.5"
1133+
build_done "libogg" "${CURRENT_PACKAGE_VERSION}"
11411134
fi
11421135

11431136
if build "libvorbis" "1.3.7"; then
11441137

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

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

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

1156-
build_done "libvorbis" "1.3.7"
1149+
build_done "libvorbis" "${CURRENT_PACKAGE_VERSION}"
11571150
fi
11581151
fi
11591152

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

11641157
if build "libtheora" "1.1.1"; then
11651158

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

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

1196-
build_done "libtheora" "1.1.1"
1189+
build_done "libtheora" "${CURRENT_PACKAGE_VERSION}"
11971190
fi
11981191
fi
11991192

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

12021195
if ${NONFREE_AND_GPL}; then
12031196

1204-
if build "fdk_aac" "2.0.2"; then
1197+
if build "fdk_aac" "2.0.3"; then
12051198

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

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

1212-
build_done "fdk_aac" "2.0.2"
1205+
build_done "fdk_aac" "${CURRENT_PACKAGE_VERSION}"
12131206
fi
12141207

12151208
CONFIGURE_OPTIONS+=("--enable-libfdk-aac")

install.js

Lines changed: 68 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const dotenv = require("dotenv");
99
const get = require("simple-get");
1010
const tar = require("tar");
1111

12+
const DOWNLOAD_RETRY_ATTEMPTS = 2;
13+
1214
function targetFfmpegRelease() {
1315

1416
return "v" + process.env.npm_package_version;
@@ -111,63 +113,97 @@ async function getDownloadFileName() {
111113
}
112114
}
113115

114-
async function downloadFfmpeg(downloadUrl, ffmpegDownloadPath) {
116+
async function downloadFfmpeg(downloadUrl, ffmpegDownloadPath, retries = DOWNLOAD_RETRY_ATTEMPTS) {
115117

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

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

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

124-
get({
125-
url: downloadUrl,
126-
}, (err, res) => {
124+
const file = fs.createWriteStream(tempFile);
127125

128-
if(err || res.statusCode !== 200) {
126+
const attemptDownload = () => {
129127

130-
return reject(err);
131-
}
128+
// Download the file.
129+
get(downloadUrl, (err, res) => {
132130

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

136-
res.on("data", (chunk) => {
133+
console.log("Download failed. Retrying.");
137134

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

143-
file.on("finish", () => {
138+
file.close();
139+
fs.unlinkSync(tempFile);
144140

145-
console.log(" - Download Complete");
146-
file.close();
147-
});
141+
return downloadFfmpeg(downloadUrl, ffmpegDownloadPath, retries - 1)
142+
.then(resolve)
143+
.catch(reject);
144+
}
145+
146+
return reject(err || new Error("Failed to download after " + (DOWNLOAD_RETRY_ATTEMPTS + 1).toString() + " attempts."));
147+
}
148+
149+
// We ensure totalBytes is never zero so we avoid divide-by-zero errors.
150+
const totalBytes = parseInt(res.headers["content-length"], 10) || 1;
151+
let downloadedBytes = 0;
152+
153+
// Inform users of our progress.
154+
res.on("data", (chunk) => {
155+
156+
downloadedBytes += chunk.length;
157+
process.stdout.write("\r" + Math.round((downloadedBytes / totalBytes) * 100).toString() + "%.");
158+
});
148159

149-
file.on("close", () => {
160+
// Download complete and the file is now closed, rename it.
161+
file.on("close", () => {
150162

151-
fs.renameSync(tempFile, ffmpegDownloadPath);
152-
resolve();
153-
})
163+
fs.renameSync(tempFile, ffmpegDownloadPath);
164+
resolve();
165+
});
154166

155-
file.on("error", (error) => {
167+
// Error handling.
168+
file.on("error", (error) => {
156169

157-
console.log(error);
158-
reject(error)
170+
console.log(error);
171+
reject(error);
172+
});
173+
174+
// All data written - we've completed the download.
175+
file.on("finish", () => console.log(" - download complete."));
176+
177+
res.pipe(file);
178+
}).on("error", (error) => {
179+
180+
console.log("Request error: ", error);
181+
182+
// Clean up the incomplete download before proceeding.
183+
if(retries > 0) {
184+
185+
console.log("Retrying download.");
186+
fs.unlinkSync(tempFile); // Clean up on error
187+
188+
return downloadFfmpeg(downloadUrl, ffmpegDownloadPath, retries - 1)
189+
.then(resolve)
190+
.catch(reject);
191+
}
192+
193+
reject(new Error("Failed after " + (DOWNLOAD_RETRY_ATTEMPTS + 1).toString() + " attempts."));
159194
});
195+
};
160196

161-
res.pipe(file);
162-
})
163-
})
197+
attemptDownload();
198+
});
164199
}
165200

166201
function binaryOk(ffmpegTempPath) {
167202

168203
try {
169204

170205
child_process.execSync(ffmpegTempPath + " -buildconf");
206+
171207
return true;
172208
} catch (e) {
173209

@@ -273,7 +309,7 @@ async function install() {
273309
// Bootstrap the installation process.
274310
async function bootstrap() {
275311

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

278314
try {
279315

0 commit comments

Comments
 (0)