Create a Command Line Tool in Xcode on macOS¶
This topic describes the steps needed to configure an Objective-C Command Line Tool in Xcode.
The code snippets used in this article are from the simple_converter macOS sample.
Create the Xcode project¶
Open Xcode, select
Create New Project, pickmacOSas a platform, pickCommand Line Toolfor ApplicationSet Product Name to
simple-converter, selectObjective-Cfor language.Rename
main.mtomain.mm.Download the 64 bit version of AVBlocks Core (macOS) that matches your Mac. Run
uname -mto check:x86_64means Intel,arm64means Apple Silicon. The file you need will have a name similar to the following, except for the version number which may be different:Architecture
File
Intel (x86_64)
avblocks-v3.4.0-demo.1-darwin.zipApple Silicon (arm64)
avblocks-v3.4.0-demo.1-darwin-arm64.zipYou can also download it with
curlfrom the Xcode project directory:AVBLOCKS_BASE_URL="https://github.com/avblocks/avblocks-core/releases/download" AVBLOCKS_VERSION="v3.4.0-demo.1" # "darwin" for Intel (x86_64), "darwin-arm64" for Apple Silicon (arm64) AVBLOCKS_PLATFORM="darwin" curl -L \ -o "avblocks-${AVBLOCKS_VERSION}-${AVBLOCKS_PLATFORM}.zip" \ "${AVBLOCKS_BASE_URL}/${AVBLOCKS_VERSION}/avblocks-${AVBLOCKS_VERSION}-${AVBLOCKS_PLATFORM}.zip"
Extract the ZIP archive in a location of your choice, then copy the
includeandlibdirectories to theavblockssubdirectory of the Xcode project directory. The Xcode project directory is the directory that contains thesimple-converter.xcodeprojproject file. AVBlocks Plus also needs the header fileavb++.h. Download it from the avblocks-plus repository and save it in theavblocks/include/primo/avblocksdirectory. The AVBlocks Plus samples usestd::println, whichshim23.hprovides for C++20 builds. Download shim23.h and save it in ashimdirectory next to the directory that containsmain.mm.If you downloaded the archive to the Xcode project directory with
curl, you can extract it directly into theavblockssubdirectory:mkdir -p ./avblocks unzip -q "avblocks-${AVBLOCKS_VERSION}-${AVBLOCKS_PLATFORM}.zip" -d ./avblocks
You should end up with a directory structure similar to the following:
simple-converter ├── avblocks │ ├── include │ └── lib ├── simple-converter │ └── main.mm └── simple-converter.xcodeproj
In Xcode, select the
simple-converterproject in Xcode, and then the ‘Build Settings’ tab:Under Apple Clang - Language - C++, set the C++ Language Dialect to
C++20[-std=c++20]Under Search Paths | Header Search Paths, add the
$(PROJECT_DIR)/avblocks/includedirectory to the listUnder linking - General | Runpath Search Paths, add
@executable_pathto the listSet the Build Products Path to
$(PROJECT_DIR)/build
In Xcode, select the ‘simple-converter’ target, and then the ‘Build Phases’ tab:
Expand the ‘Link Binary with Libraries’ section
Add the
libAVBlocks.dylibfrom the$(PROJECT_DIR)/avblocks/lib/arm64directory on Apple Silicon, or$(PROJECT_DIR)/avblocks/lib/x64on Intel.
Replace the contents of
main.mmwith this code:#include <primo/avblocks/avb++.h> #include <cstdio> #include <print> #include "../shim/shim23.h" using namespace primo::codecs; using namespace primo::avblocks::modern; int main() { TLibrary library; const char* inputFile = "Wildlife_h264_aac.mp4"; const char* outputFile = "Wildlife_h265_aac.mp4"; // transcoder will fail if output exists (by design) std::remove(outputFile); try { // Probe the input file and create the input socket from the probe auto input = TMediaSocket(TMediaInfo().file(inputFile).open()); // Demo mode is allowed when using the demo version of the library. TTranscoder() .allowDemoMode(true) .addInput(input) // The output starts as a copy of the input .addOutput( input.clone() .file(outputFile) .videoInfoRef(0, [](TVideoStreamInfo& video) { // Change the output video stream to H.265/HEVC // Input is H.264/AVC at 700 kbps // With H.265/HEVC we can use lower bitrate, e.g. 500 kbps video.streamType(StreamType::H265) .streamSubType(StreamSubType::HEVC_Annex_B) .bitrate(500'000); }) ) .transcode(); std::println("Output: {}", outputFile); return 0; } catch (const TAVBlocksException& ex) { std::println(stderr, "AVBlocks error: {}", ex.what()); return 1; } }
Restart Xcode!!! Otherwise it will not pick the new Build Products Path
Build the project ( ⌘B )
Copy the file
libAVBlocks.dylibfromavblocks/lib/arm64(Apple Silicon) oravblocks/lib/x64(Intel) tobuild/Debug.
Run the application¶
Download the
Wildlife_h264_aac.mp4sample file and save it in the project directory:curl -L \ -o Wildlife_h264_aac.mp4 \ https://archive.org/download/WildlifeSampleVideo/Wildlife.mp4
Run the application in Xcode. Wait for the Transcoder to finish - it will take a few minutes. The converted file
Wildlife_h265_aac.mp4will be in thebuild/Debugdirectory.
Troubleshooting¶
You may get
dyld: Library not loaded: @executable_path/libAVBlocks.dylibor a similar message. To fix that, copy the filelibAVBlocks.dylibfromavblocks/libtobuild/Debug.TTranscoder::openmay fail if there is already a fileWildlife_h265_aac.mp4in thebuild/Debugdirectory. DeleteWildlife_h265_aac.mp4to solve that.