Skip to content

Commit 7d16e62

Browse files
FFmpeg build
1 parent 97618e7 commit 7d16e62

File tree

4 files changed

+381
-10
lines changed

4 files changed

+381
-10
lines changed

FFmpegBuild/build.sh

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/bin/sh
2+
3+
#
4+
# build-ffmpeg.sh
5+
# Aural
6+
#
7+
# Copyright © 2024 Kartik Venugopal. All rights reserved.
8+
#
9+
# This software is licensed under the MIT software license.
10+
# See the file "LICENSE" in the project root directory for license terms.
11+
#
12+
13+
#
14+
# This script builds XCFrameworks that wrap FFmpeg shared libraries (.dylib) and their
15+
# corresponding public headers. These frameworks are suitable for use by Aural Player but not for general
16+
# purpose FFmpeg use.
17+
#
18+
# Please see "README.txt" (in the same directory as this script) for detailed instructions and notes
19+
# related to the use of this script.
20+
#
21+
22+
source ./common.sh
23+
24+
# MARK: Constants -------------------------------------------------------------------------------------
25+
26+
# Architectures
27+
export architectures=("x86_64" "arm64")
28+
29+
# Deployment target for Aural Player.
30+
export deploymentTarget="11.0"
31+
32+
# Points to the latest MacOS SDK installed.
33+
export sdk="/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
34+
35+
export createFatLibs="true"
36+
37+
# MARK: Functions -------------------------------------------------------------------------------------
38+
39+
# Determine compiler / linker flags based on architecture.
40+
function setCompilerAndLinkerFlags {
41+
42+
arch=$1
43+
44+
export compiler="/usr/bin/clang"
45+
46+
# Architecture of the host machine running this build.
47+
hostArchitecture=$(uname -m)
48+
49+
if [[ "$arch" != "$hostArchitecture" ]]
50+
then
51+
archInFlags="-arch ${arch} "
52+
export crossCompileOption="--enable-cross-compile"
53+
export archOption="--arch=${arch}"
54+
fi
55+
56+
export extraCompilerFlags="${archInFlags}-mmacosx-version-min=${deploymentTarget} -isysroot ${sdk}"
57+
export extraLinkerFlags=${extraCompilerFlags}
58+
}
59+
60+
function copyHeaders {
61+
62+
mkdir "headers"
63+
64+
srcBaseDir="src/arm64"
65+
headersBaseDir="headers"
66+
67+
copyHeadersForLib $srcBaseDir $avcodecLibName $headersBaseDir "${avcodecHeaderNames[@]}"
68+
copyHeadersForLib $srcBaseDir $avformatLibName $headersBaseDir "${avformatHeaderNames[@]}"
69+
copyHeadersForLib $srcBaseDir $avutilLibName $headersBaseDir "${avutilHeaderNames[@]}"
70+
copyHeadersForLib $srcBaseDir $swresampleLibName $headersBaseDir "${swresampleHeaderNames[@]}"
71+
}
72+
73+
function createXCFrameworkForLib {
74+
75+
libName=$1
76+
lib=$2
77+
78+
xcrun xcodebuild -create-xcframework \
79+
-library "dylibs/${lib}" -headers "headers/${libName}" \
80+
-output "xcframeworks/${libName}.xcframework"
81+
}
82+
83+
runBuild
84+
createXCFrameworks
85+
cleanUp
86+
87+
echo "\nAll done !\n"

FFmpegBuild/common.sh

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
#!/bin/sh
2+
3+
# common.sh
4+
# Aural-macOS
5+
#
6+
# Created by Kartik Venugopal on 22/09/22.
7+
# Copyright © 2024 Kartik Venugopal. All rights reserved.
8+
9+
# Common variables and functions used across the ffmpeg build scripts.
10+
11+
# MARK: Constants -------------------------------------------------------------------------------------
12+
13+
# FFmpeg release version
14+
export ffmpegVersion="4.4"
15+
16+
export avcodecLibName="libavcodec"
17+
export avformatLibName="libavformat"
18+
export avutilLibName="libavutil"
19+
export swresampleLibName="libswresample"
20+
21+
# Library versions
22+
export avcodecVersion=58
23+
export avformatVersion=58
24+
export avutilVersion=56
25+
export swresampleVersion=3
26+
27+
# Aliases for the library files.
28+
export avcodecLib="${avcodecLibName}.${avcodecVersion}.dylib"
29+
export avformatLib="${avformatLibName}.${avformatVersion}.dylib"
30+
export avutilLib="${avutilLibName}.${avutilVersion}.dylib"
31+
export swresampleLib="${swresampleLibName}.${swresampleVersion}.dylib"
32+
33+
# Components to enable and build
34+
export demuxersToEnable="ape,asf,asf_o,dsf,flac,iff,matroska,mpc,mpc8,ogg,rm,tak,tta,wv"
35+
export parsersToEnable="bmp,cook,flac,gif,jpeg2000,mjpeg,mpegaudio,opus,png,sipr,tak,vorbis,webp"
36+
export decodersToEnable="ape,cook,dsd_lsbf,dsd_lsbf_planar,dsd_msbf,dsd_msbf_planar,flac,mpc7,mpc8,musepack7,musepack8,opus,ra_144,ra_288,ralf,sipr,tta,tak,vorbis,wavpack,wmav1,wmav2,wmalossless,wmapro,wmavoice"
37+
38+
# Names of public headers to include in XCFrameworks
39+
export avcodecHeaderNames=("ac3_parser.h" "adts_parser.h" "avcodec.h" "avdct.h" "avfft.h" "bsf.h" "codec.h" "codec_desc.h" "codec_id.h" "codec_par.h" "d3d11va.h" "dirac.h" "dv_profile.h" "dxva2.h" "jni.h" "mediacodec.h" "packet.h" "qsv.h" "vaapi.h" "vdpau.h" "version.h" "videotoolbox.h" "vorbis_parser.h" "xvmc.h")
40+
41+
export avformatHeaderNames=("avformat.h" "avio.h" "version.h")
42+
43+
export avutilHeaderNames=("adler32.h" "aes.h" "aes_ctr.h" "attributes.h" "audio_fifo.h" "avassert.h" "avconfig.h" "avstring.h" "avutil.h" "base64.h" "blowfish.h" "bprint.h" "bswap.h" "buffer.h" "camellia.h" "cast5.h" "channel_layout.h" "common.h" "cpu.h" "crc.h" "des.h" "dict.h" "display.h" "dovi_meta.h" "downmix_info.h" "encryption_info.h" "error.h" "eval.h" "fifo.h" "file.h" "film_grain_params.h" "frame.h" "hash.h" "hdr_dynamic_metadata.h" "hmac.h" "hwcontext.h" "hwcontext_cuda.h" "hwcontext_d3d11va.h" "hwcontext_drm.h" "hwcontext_dxva2.h" "hwcontext_mediacodec.h" "hwcontext_opencl.h" "hwcontext_qsv.h" "hwcontext_vaapi.h" "hwcontext_vdpau.h" "hwcontext_videotoolbox.h" "hwcontext_vulkan.h" "imgutils.h" "intfloat.h" "intreadwrite.h" "lfg.h" "log.h" "lzo.h" "macros.h" "mastering_display_metadata.h" "mathematics.h" "md5.h" "mem.h" "motion_vector.h" "murmur3.h" "opt.h" "parseutils.h" "pixdesc.h" "pixelutils.h" "pixfmt.h" "random_seed.h" "rational.h" "rc4.h" "replaygain.h" "ripemd.h" "samplefmt.h" "sha.h" "sha512.h" "spherical.h" "stereo3d.h" "tea.h" "threadmessage.h" "time.h" "timecode.h" "timestamp.h" "tree.h" "twofish.h" "tx.h" "version.h" "video_enc_params.h" "xtea.h")
44+
45+
export swresampleHeaderNames=("swresample.h" "version.h")
46+
47+
# The name of the FFmpeg source archive file.
48+
export srcArchiveName="ffmpeg-${ffmpegVersion}.tar.bz2"
49+
50+
# The name of the FFmpeg source directory (once the archive has been uncompressed).
51+
export srcDirName="ffmpeg-${ffmpegVersion}"
52+
53+
# MARK: Functions -------------------------------------------------------------------------------------
54+
55+
function runBuild {
56+
57+
cleanXCFrameworksDir
58+
buildFFmpeg
59+
60+
if [[ "$createFatLibs" == "true" ]]
61+
then
62+
createFatLibs
63+
fi
64+
65+
copyHeaders
66+
}
67+
68+
function cleanXCFrameworksDir {
69+
70+
if [ -d "xcframeworks" ]; then
71+
rm -rf xcframeworks
72+
fi
73+
}
74+
75+
function buildFFmpeg {
76+
77+
# Extract source code from archive.
78+
if [ ! -d ${srcDirName} ]; then
79+
tar xjf ${srcArchiveName}
80+
fi
81+
82+
# Run all builds in parallel and wait till they all finish.
83+
for arch in ${architectures[@]}; do
84+
buildFFmpegForArch $arch &
85+
done
86+
87+
wait
88+
}
89+
90+
function buildFFmpegForArch {
91+
92+
arch=$1
93+
94+
echo "\nBuilding FFmpeg for architecture '${arch}' ..."
95+
96+
# Make a copy of the source code.
97+
srcBaseDir="src/${arch}"
98+
mkdir -p ${srcBaseDir}
99+
cp -r $srcDirName/* $srcBaseDir
100+
101+
configureFFmpeg $arch $srcBaseDir
102+
makeFFmpeg
103+
104+
copyLibs $arch
105+
fixInstallNames $arch
106+
}
107+
108+
function configureFFmpeg {
109+
110+
arch=$1
111+
srcDir=$2
112+
113+
# CD to the source directory.
114+
cd ${srcDir}
115+
116+
setCompilerAndLinkerFlags $arch
117+
118+
# Configure FFmpeg
119+
./configure \
120+
--target-os=darwin \
121+
${archOption} \
122+
--cc="${compiler}" \
123+
--as="${assembler}" \
124+
--extra-cflags="${extraCompilerFlags}" \
125+
--extra-ldflags="${extraLinkerFlags}" \
126+
${crossCompileOption} \
127+
--enable-gpl \
128+
--enable-version3 \
129+
--enable-shared \
130+
--disable-static \
131+
--enable-runtime-cpudetect \
132+
--enable-hardcoded-tables \
133+
--enable-pthreads \
134+
--disable-doc \
135+
--disable-debug \
136+
--disable-network \
137+
--disable-all \
138+
--enable-avcodec \
139+
--enable-avformat \
140+
--enable-swresample \
141+
--disable-avfoundation \
142+
--disable-audiotoolbox \
143+
--disable-coreimage \
144+
--disable-zlib \
145+
--disable-everything \
146+
--disable-appkit \
147+
--disable-iconv \
148+
--disable-bzlib \
149+
--disable-sdl2 \
150+
--disable-videotoolbox \
151+
--disable-securetransport \
152+
--enable-demuxer=$demuxersToEnable \
153+
--enable-parser=$parsersToEnable \
154+
--enable-decoder=$decodersToEnable \
155+
--enable-protocol=file
156+
}
157+
158+
function makeFFmpeg {
159+
160+
# Build FFmpeg (use multithreading).
161+
tokens=$(sysctl hw.physicalcpu)
162+
numCores="$(cut -d' ' -f2 <<<$tokens)"
163+
make -j${numCores}
164+
165+
cd ../..
166+
}
167+
168+
function copyLibs {
169+
170+
arch=$1
171+
172+
# Create the directory where the libs will be installed in.
173+
libsDir="dylibs/${arch}"
174+
mkdir -p $libsDir
175+
cd $libsDir
176+
177+
srcDir="../../src/${arch}"
178+
179+
cp ${srcDir}/${avcodecLibName}/${avcodecLib} .
180+
cp ${srcDir}/${avformatLibName}/${avformatLib} .
181+
cp ${srcDir}/${avutilLibName}/${avutilLib} .
182+
cp ${srcDir}/${swresampleLibName}/${swresampleLib} .
183+
184+
cd ../..
185+
}
186+
187+
function fixInstallNames {
188+
189+
arch=$1
190+
191+
cd "dylibs/${arch}"
192+
193+
install_name_tool -id @rpath/${avcodecLib} ${avcodecLib}
194+
install_name_tool -change /usr/local/lib/${swresampleLib} @rpath/${swresampleLib} ${avcodecLib}
195+
install_name_tool -change /usr/local/lib/${avutilLib} @rpath/${avutilLib} ${avcodecLib}
196+
197+
install_name_tool -id @rpath/${avformatLib} ${avformatLib}
198+
install_name_tool -change /usr/local/lib/${avcodecLib} @rpath/${avcodecLib} ${avformatLib}
199+
install_name_tool -change /usr/local/lib/${swresampleLib} @rpath/${swresampleLib} ${avformatLib}
200+
install_name_tool -change /usr/local/lib/${avutilLib} @rpath/${avutilLib} ${avformatLib}
201+
202+
install_name_tool -id @rpath/${avutilLib} ${avutilLib}
203+
204+
install_name_tool -id @rpath/${swresampleLib} ${swresampleLib}
205+
install_name_tool -change /usr/local/lib/${avutilLib} @rpath/${avutilLib} ${swresampleLib}
206+
207+
cd ../../..
208+
}
209+
210+
function createFatLibs {
211+
212+
# Combine x86_64 and arm64 dylibs into "fat" universal dylibs.
213+
cd dylibs
214+
215+
allDylibs=($avcodecLib $avformatLib $avutilLib $swresampleLib)
216+
217+
for lib in ${allDylibs[@]}; do
218+
219+
nonFatLibFiles=""
220+
221+
for arch in ${architectures[@]}; do
222+
nonFatLibFiles="${nonFatLibFiles} ${arch}/${lib}"
223+
done
224+
225+
lipo ${nonFatLibFiles} -output ${lib} -create
226+
227+
done
228+
229+
cd ..
230+
}
231+
232+
function copyHeadersForLib {
233+
234+
srcBaseDir=$1
235+
libName=$2
236+
headersBaseDir=$3
237+
shift
238+
shift
239+
shift
240+
headerNames=("$@")
241+
srcDir="${srcBaseDir}/${libName}"
242+
243+
# Add a 2nd level folder with the same library name (otherwise headers are not resolved properly in the XCode project).
244+
# For example: "/libavcodec/libavcodec/someHeader.h"
245+
246+
headersDestDir="${headersBaseDir}/${libName}/${libName}"
247+
mkdir -p $headersDestDir
248+
249+
for file in ${headerNames[@]}; do
250+
cp "${srcDir}/${file}" "${headersDestDir}"
251+
done
252+
}
253+
254+
function createXCFrameworks {
255+
256+
mkdir "xcframeworks"
257+
258+
createXCFrameworkForLib ${avcodecLibName} ${avcodecLib}
259+
createXCFrameworkForLib ${avformatLibName} ${avformatLib}
260+
createXCFrameworkForLib ${avutilLibName} ${avutilLib}
261+
createXCFrameworkForLib ${swresampleLibName} ${swresampleLib}
262+
}
263+
264+
function cleanUp {
265+
266+
rm -rf ${srcDirName}
267+
rm -rf src
268+
rm -rf dylibs
269+
rm -rf headers
270+
}

0 commit comments

Comments
 (0)