Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add a project launcher #67 #75

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
21ca955
Add launcher.py
nikhiljangra264 Dec 20, 2024
fa3f7a6
Refactor launcher.py:
nikhiljangra264 Dec 22, 2024
f034b6c
Remove unnessasary requirements from requirements.txt
nikhiljangra264 Dec 22, 2024
83ff05f
Refactor Dependency handling in launcher.py
nikhiljangra264 Dec 22, 2024
5aae3eb
Add runtime config file.
nikhiljangra264 Dec 22, 2024
5d4c2f8
Fix `launcher.py` and `AudioProcessor.cpp` for Windows
nikhiljangra264 Dec 22, 2024
8c2722a
Fix macOS architecture detection and library path issues in test suite
nikhiljangra264 Dec 22, 2024
1bedd21
MINOR: formatted `AudioProcessor.cpp`
nikhiljangra264 Dec 22, 2024
0a01bf3
Refactor `launcher.py`
nikhiljangra264 Dec 23, 2024
9592859
Refactor `WebApplication class` in `launcher.py`: remove unused attri…
nikhiljangra264 Dec 23, 2024
4886dfd
Refactor `launcher.py`: Rename to stick to convention and Minor changes.
nikhiljangra264 Dec 24, 2024
210ad4a
Add logging statement in `launcher.py` to indicate MSYS2 PATH addition
nikhiljangra264 Dec 24, 2024
3cb403f
Add port parameter to `WebApplication.run` method in `launcher.py`.
nikhiljangra264 Dec 24, 2024
2a982c6
Rename `MEDIAPROCESSOR_PATH` to `PROCESSING_ENGINE_PATH` in `launcher…
nikhiljangra264 Dec 24, 2024
a25b39e
Update installer URL from nightly to stable release for msys2 in `lau…
nikhiljangra264 Dec 24, 2024
81ed83c
Refactor launcher.py: Rename `get_venv_binaries_directory` to `get_ve…
nikhiljangra264 Dec 29, 2024
6935987
Tooling: Refactor info messages and doxy comment in `launcher.py`
nikhiljangra264 Jan 2, 2025
dc7c850
Core: Remove local path ref from libdf.dylib install name
omeryusufyagci Jan 8, 2025
4777f69
Tooling: Add logging for displaying log statements to launcher.py
nikhiljangra264 Jan 18, 2025
0f9adc9
Tooling: Minor code formatting
nikhiljangra264 Jan 18, 2025
23342d7
Tooling: Add logging to Web app and FIXMEs for launcher.py
omeryusufyagci Jan 19, 2025
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ __pycache__/
# C extensions
*.so

# runtime config
runtime_config.json

# Distribution / packaging
.Python
build/
Expand Down
26 changes: 24 additions & 2 deletions MediaProcessor/cmake/test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ endif()

# Setup test media directory
set(TEST_MEDIA_DIR "${CMAKE_SOURCE_DIR}/tests/TestMedia" CACHE PATH "Path to test media files")
file(TO_CMAKE_PATH "${TEST_MEDIA_DIR}" TEST_MEDIA_DIR)

FetchContent_Declare(
fmt
Expand All @@ -22,8 +23,29 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(fmt)

# Common libraries for all test targets
set(COMMON_LIBRARIES gtest_main ${CMAKE_SOURCE_DIR}/lib/libdf.so ${SNDFILE_LIBRARIES} fmt::fmt)
if(APPLE)
include(CheckCXXCompilerFlag)

# This fixes arch detection on macOS
check_cxx_compiler_flag("-arch arm64" COMPILER_SUPPORTS_ARM64)

if(COMPILER_SUPPORTS_ARM64 AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
set(DF_LIBRARY ${CMAKE_SOURCE_DIR}/lib/libdf.dylib)
else()
message(FATAL_ERROR "Unsupported macOS architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
# set(DF_LIBRARY ${CMAKE_SOURCE_DIR}/lib/libdf.dylib)
endif()
elseif(WIN32)
set(DF_LIBRARY ${CMAKE_SOURCE_DIR}/lib/libdf.dll.a) # for linktime
set(DF_DLL_PATH ${CMAKE_SOURCE_DIR}/lib/df.dll) # for runtime

elseif(UNIX)
set(DF_LIBRARY ${CMAKE_SOURCE_DIR}/lib/libdf.so)
else()
message(FATAL_ERROR "Unsupported platform")
endif()

set(COMMON_LIBRARIES gtest_main ${DF_LIBRARY} ${SNDFILE_LIBRARIES} fmt::fmt)

# Macro for adding a test executable
macro(add_test_executable name)
Expand Down
10 changes: 6 additions & 4 deletions MediaProcessor/src/AudioProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,17 @@ bool AudioProcessor::invokeDeepFilterFFI(fs::path chunkPath, DFState* df_state,
std::vector<float>& inputBuffer,
std::vector<float>& outputBuffer) {
SF_INFO sfInfoIn;
SNDFILE* inputFile = sf_open(chunkPath.c_str(), SFM_READ, &sfInfoIn);
// First Convert to string
// On windows c_str converts to utf_16 but sf_open requires utf_8
SNDFILE* inputFile = sf_open(chunkPath.string().c_str(), SFM_READ, &sfInfoIn);
if (!inputFile) {
std::cerr << "Error: Could not open input WAV file: " << chunkPath << std::endl;
return false;
}

// Prepare output file
fs::path processedChunkPath = m_processedChunksPath / chunkPath.filename();
SNDFILE* outputFile = sf_open(processedChunkPath.c_str(), SFM_WRITE, &sfInfoIn);
SNDFILE* outputFile = sf_open(processedChunkPath.string().c_str(), SFM_WRITE, &sfInfoIn);
if (!outputFile) {
std::cerr << "Error: Could not open output WAV file: " << processedChunkPath << std::endl;
sf_close(inputFile);
Expand Down Expand Up @@ -213,8 +215,8 @@ bool AudioProcessor::filterChunks() {
for (int i = 0; i < m_numChunks; ++i) {
results.emplace_back(pool.enqueue([&, i]() {
// Per-thread DFState instance
DFState* df_state =
df_create(deepFilterTarballPath.c_str(), m_filterAttenuationLimit, nullptr);
DFState* df_state = df_create(deepFilterTarballPath.string().c_str(),
m_filterAttenuationLimit, nullptr);
if (!df_state) {
std::cerr << "Error: Failed to insantiate DFState in thread." << std::endl;
return false;
Expand Down
2 changes: 1 addition & 1 deletion MediaProcessor/src/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Engine::Engine(const std::filesystem::path& mediaPath)

bool Engine::processMedia() {
ConfigManager& configManager = ConfigManager::getInstance();
if (!configManager.loadConfig("config.json")) {
if (!configManager.loadConfig("runtime_config.json")) {
std::cerr << "Error: Could not load configuration." << std::endl;
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion MediaProcessor/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ int main(int argc, char* argv[]) {
* It supports both audio and video files, adapting the workflow based on the file type.
*
* Workflow:
* 1. Load configuration from "config.json".
* 1. Load configuration from "runtime_config.json".
* 2. Determine if the input file is audio or video.
* 3. For audio files:
* - Directly process audio to isolate vocals.
Expand Down
1 change: 1 addition & 0 deletions MediaProcessor/tests/AudioProcessorTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class AudioProcessorTester : public ::testing::Test {
}

void SetUp() override {
testMediaPath.make_preferred();
fs::path currentPath = fs::current_path();

testVideoPath = testMediaPath / "test_video.mkv";
Expand Down
4 changes: 2 additions & 2 deletions MediaProcessor/tests/TestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ bool CompareFiles::compareFilesByteByByte(const fs::path& filePath1, const fs::p
bool CompareFiles::compareAudioFiles(const fs::path& filePath1, const fs::path& filePath2,
double tolerance, size_t chunkSize) {
SF_INFO sfInfo1, sfInfo2;
SNDFILE* sndFile1 = sf_open(filePath1.c_str(), SFM_READ, &sfInfo1);
SNDFILE* sndFile1 = sf_open(filePath1.string().c_str(), SFM_READ, &sfInfo1);
if (!sndFile1) {
throw std::runtime_error("Failed to open file 1: " + filePath1.string());
}

SNDFILE* sndFile2 = sf_open(filePath2.c_str(), SFM_READ, &sfInfo2);
SNDFILE* sndFile2 = sf_open(filePath2.string().c_str(), SFM_READ, &sfInfo2);
if (!sndFile2) {
sf_close(sndFile1);
throw std::runtime_error("Failed to open file 2: " + filePath2.string());
Expand Down
2 changes: 1 addition & 1 deletion MediaProcessor/tests/TestUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class TestConfigFile {
(m_rootPath / "res/DeepFilterNet3_ll_onnx/tmp/export/enc.onnx")},
{"deep_filter_decoder_path",
(m_rootPath / "res/DeepFilterNet3_ll_onnx/tmp/export/df_dec.onnx")},
{"ffmpeg_path", "/usr/bin/ffmpeg"},
{"ffmpeg_path", "ffmpeg"},
{"downloads_path", "downloads"},
{"uploads_path", "uploads"},
{"use_thread_cap", false},
Expand Down
16 changes: 4 additions & 12 deletions MediaProcessor/tests/VideoProcessorTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class VideoProcessorTester : public ::testing::Test {
}

void SetUp() override {
testMediaPath.make_preferred();
testVideoPath = testMediaPath / "test_video.mkv";
testAudioPath = testMediaPath / "test_audio_processed.wav";

Expand All @@ -36,18 +37,6 @@ class VideoProcessorTester : public ::testing::Test {

testOutputDir = fs::current_path() / "test_output";
fs::create_directories(testOutputDir);

nlohmann::json jsonObject = {
{"ffmpeg_path", "/usr/bin/ffmpeg"},
{"deep_filter_path", "MediaProcessor/res/deep-filter-0.5.6-x86_64-unknown-linux-musl"},
{"downloads_path", "downloads"},
{"uploads_path", "uploads"},
{"use_thread_cap", true},
{"max_threads_if_capped", 4}};
testConfigFile.generateConfigFile("testConfig.json", jsonObject);

ASSERT_TRUE(configManager.loadConfig(testConfigFile.getFilePath()))
<< "Failed to load test configuration file.";
}

void TearDown() override {
Expand All @@ -62,6 +51,9 @@ TEST_F(VideoProcessorTester, MergeMedia_MergesAudioAndVideoCorrectly) {
* is already being checked within the audio tester.
* Eventually we need check for sensible metrics here.
*/
ConfigManager& configManager = ConfigManager::getInstance();
ASSERT_TRUE(configManager.loadConfig(testConfigFile.getFilePath()))
<< "Unable to Load TestConfigFile";

fs::path testOutputVideoPath = testOutputDir / "test_output_video.mp4";
VideoProcessor videoProcessor(testVideoPath, testAudioPath, testOutputVideoPath);
Expand Down
9 changes: 7 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import re
import subprocess
from sys import exit
from urllib.parse import urlparse

import yt_dlp
Expand All @@ -27,8 +28,12 @@
app = Flask(__name__)

# Load config and set paths
with open("config.json") as config_file:
config = json.load(config_file)
try:
with open("runtime_config.json") as config_file:
config = json.load(config_file)
except FileNotFoundError:
print("Please run launcher.py.")
exit(1)

# Define base paths using absolute references
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
Expand Down
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"deep_filter_tarball_path": "MediaProcessor/res/DeepFilterNet3_ll_onnx.tar.gz",
"deep_filter_encoder_path": "MediaProcessor/res/DeepFilterNet3_ll_onnx/tmp/export/enc.onnx",
"deep_filter_decoder_path": "MediaProcessor/res/DeepFilterNet3_ll_onnx/tmp/export/df_dec.onnx",
"ffmpeg_path": "/usr/bin/ffmpeg",
"ffmpeg_path": "ffmpeg",
"downloads_path": "downloads",
"uploads_path": "uploads",
"use_thread_cap": false,
Expand Down
Loading
Loading