Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
93c77f5
enabled video export
Eism Mar 23, 2026
d1caaa6
moved video writing to separate thread
Eism Mar 2, 2026
3e5a0a4
added audio to video exporting
Eism Mar 23, 2026
75d34c1
added setting video resolution
Eism Mar 2, 2026
79b1c70
tmp: disabled audio when exporting video in cli
Eism Mar 23, 2026
0e1f115
moved availableResolutions to configuration
Eism Mar 3, 2026
34c70cd
fixed crash when exporting video from cli
Eism Mar 5, 2026
e55b756
fixed build after cherry-pick
Eism Mar 23, 2026
5ce63c7
created media module and moved the video encoder into it
Eism Mar 6, 2026
32df9ec
scripts for copying FFmpeg headers to MuseScore
Eism Mar 4, 2026
e80241c
copied FFmpeg headers
Eism Mar 4, 2026
e62223c
added dynamic loading of ffmpeg library
Eism Mar 4, 2026
29cdcd6
added ffmpeg library setting
Eism Mar 5, 2026
e889935
enabled video export module by default
Eism Mar 23, 2026
4af4044
fixed build after cherry-pick
Eism Mar 23, 2026
4d987ad
removed FFmpegFunctions
Eism Mar 23, 2026
62b230b
removed support of ffmpeg < v4
Eism Mar 23, 2026
eda3153
some code clean
Eism Mar 10, 2026
06bc78a
fixed add audio interface in VideoEncoder
Eism Mar 10, 2026
ce9c4ad
moved current videoencoder to ffmpeg/v8
Eism Mar 10, 2026
88dde7c
added ffmpeg v7
Eism Mar 11, 2026
4024a49
added libswresample
Eism Mar 12, 2026
088d252
added loading libswresample
Eism Mar 12, 2026
00fc4c6
fixed build on Windows
Eism Mar 12, 2026
5b38dab
fixed ffmpeg 7 and applied to ffmpeg 8
Eism Mar 13, 2026
b3b0ebe
fixed the sequence of directories for searching
Eism Mar 13, 2026
6c3aca5
added ffmpeg 6
Eism Mar 13, 2026
e2276ac
isolated ffmpeg include directories for different versions
Eism Mar 16, 2026
82f7d19
added ffmpeg 5
Eism Mar 16, 2026
9159ab1
added ffmpeg 4
Eism Mar 16, 2026
c1c0ce2
refactored ffmpeg video encoder initialization and encapsulated libra…
Eism Mar 16, 2026
a244a46
added missing include for ffmpeg 4
Eism Mar 16, 2026
9d55f7c
fixed the clean issue in add audio
Eism Mar 16, 2026
0ff8701
added check MUE_BUILD_IMPEXP_VIDEOEXPORT_MODULE
Eism Mar 16, 2026
af2eb31
moved ffmpeg settings to Video page
Eism Mar 23, 2026
35b1182
moved AutomaticUpdateSection to General page
Eism Mar 16, 2026
eabf85e
fixed find libraries for linux
Eism Mar 17, 2026
502815b
fixed mp4 option in export dialog
Eism Mar 23, 2026
475c321
removed redundant version and directory tracking from ffmpeg handlers
Eism Mar 17, 2026
4db1c33
refactored video encoder to use an options struct
Eism Mar 17, 2026
8bbfb9f
removed unused ffmpeg functions from lib handler
Eism Mar 17, 2026
965eb5f
added title frame for video export
Eism Mar 17, 2026
156980a
added made with for video export
Eism Mar 18, 2026
3c5a8cc
freed sws contexts in video encoders
Eism Mar 18, 2026
2bbf43a
fixed notation update after export
Eism Mar 18, 2026
a9a8ec5
added no-audio option for video export
Eism Mar 18, 2026
5857bf2
fixed frames flickering on macOS
Eism Mar 18, 2026
bc27bb2
added fdk-aac-2.0.3
Eism Mar 19, 2026
3b2f7c8
added aac writer
Eism Mar 23, 2026
cc5eea1
use aac for video export
Eism Mar 19, 2026
6f8a9f2
updated aac encoder to use IODevice (master update)
Eism Mar 23, 2026
84ae078
fixed build after conflicts resolving
Eism Mar 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ option(MUE_BUILD_IMPEXP_AUDIOEXPORT_MODULE "Build importexport audioexport modul
option(MUE_BUILD_IMPEXP_IMAGESEXPORT_MODULE "Build importexport imagesexport module" ON)
option(MUE_BUILD_IMPEXP_GUITARPRO_MODULE "Build importexport guitarpro module" ON)
option(MUE_BUILD_IMPEXP_MEI_MODULE "Build importexport mei module" ON)
option(MUE_BUILD_IMPEXP_VIDEOEXPORT_MODULE "Build importexport videoexport module" OFF)
option(MUE_BUILD_IMPEXP_VIDEOEXPORT_MODULE "Build importexport videoexport module" ON)
option(MUE_BUILD_IMPEXP_TABLEDIT_MODULE "Build importexport tabledit module" ON)
option(MUE_BUILD_IMPEXP_LYRICS_MODULE "Build importexport lyrics module" ON)

Expand Down
3 changes: 0 additions & 3 deletions ninja_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ MUSESCORE_ENABLE_CODE_COVERAGE=${MUSESCORE_UNIT_TESTS_ENABLE_CODE_COVERAGE:-"OFF
MUSESCORE_NO_RPATH=${MUSESCORE_NO_RPATH:-"OFF"}
MUSESCORE_MODULE_UPDATE=${MUSESCORE_MODULE_UPDATE:-"ON"}
MUSESCORE_BUILD_VST_MODULE=${MUSESCORE_BUILD_VST_MODULE:-"OFF"}
MUSESCORE_BUILD_IMPEXP_VIDEOEXPORT_MODULE=${MUSESCORE_BUILD_IMPEXP_VIDEOEXPORT_MODULE:-"OFF"}
MUSESCORE_BUILD_WEBSOCKET=${MUSESCORE_BUILD_WEBSOCKET:-"OFF"}
MUSESCORE_BUILD_PIPEWIRE_AUDIO_DRIVER=${MUSESCORE_BUILD_PIPEWIRE_AUDIO_DRIVER:-"OFF"}
MUSESCORE_COMPILE_USE_UNITY=${MUSESCORE_COMPILE_USE_UNITY:-"ON"}
Expand Down Expand Up @@ -92,7 +91,6 @@ function do_build() {
-DCMAKE_BUILD_NUMBER="${MUSESCORE_BUILD_NUMBER}" \
-DMUSESCORE_REVISION="${MUSESCORE_REVISION}" \
-DMUE_RUN_LRELEASE="${MUSESCORE_RUN_LRELEASE}" \
-DMUE_BUILD_IMPEXP_VIDEOEXPORT_MODULE="${MUSESCORE_BUILD_IMPEXP_VIDEOEXPORT_MODULE}" \
-DMUSE_MODULE_UPDATE="${MUSESCORE_MODULE_UPDATE}" \
-DMUE_DOWNLOAD_SOUNDFONT="${MUSESCORE_DOWNLOAD_SOUNDFONT}" \
-DMUSE_ENABLE_UNIT_TESTS="${MUSESCORE_BUILD_UNIT_TESTS}" \
Expand Down Expand Up @@ -170,7 +168,6 @@ case $TARGET in
-DCMAKE_BUILD_NUMBER="${MUSESCORE_BUILD_NUMBER}" \
-DMUSESCORE_REVISION="${MUSESCORE_REVISION}" \
-DMUE_RUN_LRELEASE="${MUSESCORE_RUN_LRELEASE}" \
-DMUE_BUILD_IMPEXP_VIDEOEXPORT_MODULE="${MUSESCORE_BUILD_IMPEXP_VIDEOEXPORT_MODULE}" \
-DMUSE_MODULE_UPDATE="${MUSESCORE_MODULE_UPDATE}" \
-DMUE_DOWNLOAD_SOUNDFONT="${MUSESCORE_DOWNLOAD_SOUNDFONT}" \
-DMUSE_ENABLE_UNIT_TESTS="${MUSESCORE_BUILD_UNIT_TESTS}" \
Expand Down
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ add_to_link_if_exists(muse::extensions)
add_to_link_if_exists(muse::interactive)
add_to_link_if_exists(muse::languages)
add_to_link_if_exists(muse::learn)
add_to_link_if_exists(muse::media)
add_to_link_if_exists(muse::midi)
add_to_link_if_exists(muse::mpe)
add_to_link_if_exists(muse::multiwindows)
Expand Down
9 changes: 9 additions & 0 deletions src/app/appfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
#include "framework/stubs/learn/learnmodule.h"
#endif

#ifdef MUSE_MODULE_MEDIA
#include "framework/media/mediamodule.h"
#else
#include "framework/stubs/media/mediastubmodule.h"
#endif

#ifdef MUSE_MODULE_MIDI
#include "framework/midi/midimodule.h"
#else
Expand Down Expand Up @@ -326,6 +332,7 @@ std::shared_ptr<muse::IApplication> AppFactory::newGuiApp(const CmdOptions& opti
#endif
app->addModule(new muse::tours::ToursModule());
app->addModule(new muse::vst::VSTModule());
app->addModule(new muse::media::MediaModule());

// modules
#ifdef MUE_BUILD_APPSHELL_MODULE
Expand Down Expand Up @@ -461,6 +468,8 @@ static void addConsoleModules(std::shared_ptr<ConsoleApp> app)
app->addModule(new muse::autobot::AutobotModule());
#endif

app->addModule(new muse::media::MediaModule());

app->addModule(new mu::context::ContextModule());

#ifdef MUE_BUILD_CONVERTER_MODULE
Expand Down
1 change: 1 addition & 0 deletions src/app/cmdoptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct CmdOptions {
ExtensionUri,
PageNumber,
ScoreRegion,
NoAudio,
};

muse::IApplication::RunMode runMode = muse::IApplication::RunMode::GuiApp;
Expand Down
5 changes: 5 additions & 0 deletions src/app/internal/commandlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ void CommandLineParser::init()
m_parser.addOption(QCommandLineOption("fps", "Frame per second [60, 30, 24]", "24"));
m_parser.addOption(QCommandLineOption("ls", "Pause before playback in seconds (3.0)", "3.0"));
m_parser.addOption(QCommandLineOption("ts", "Pause before end of video in seconds (3.0)", "3.0"));
m_parser.addOption(QCommandLineOption("no-audio", "Export video without audio"));
#endif

m_parser.addOption(QCommandLineOption("gp-linked", "create tabulature linked staves for guitar pro"));
Expand Down Expand Up @@ -445,6 +446,10 @@ void CommandLineParser::parse(int argc, char** argv)
if (m_parser.isSet("ts")) {
m_options.exportVideo.trailingSec = doubleValue("ts");
}

if (m_parser.isSet("no-audio")) {
m_options.converterTask.params[CmdOptions::ParamKey::NoAudio] = true;
}
}
#endif

Expand Down
3 changes: 2 additions & 1 deletion src/app/internal/consoleapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,8 @@ int ConsoleApp::processConverter(const CmdOptions::ConverterTask& task, const mu
ret = converter()->exportScoreElements(task.inputFile, task.outputFile, openParams);
} break;
case ConvertType::ExportScoreVideo: {
ret = converter()->exportScoreVideo(task.inputFile, task.outputFile, openParams);
bool withAudio = !task.params[CmdOptions::ParamKey::NoAudio].toBool();
ret = converter()->exportScoreVideo(task.inputFile, task.outputFile, openParams, withAudio);
} break;
case ConvertType::SourceUpdate: {
std::string scoreSource = task.params[CmdOptions::ParamKey::ScoreSource].toString().toStdString();
Expand Down
3 changes: 2 additions & 1 deletion src/converter/iconvertercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ class IConverterController : MODULE_CONTEXT_INTERFACE

virtual muse::Ret exportScoreElements(const muse::io::path_t& in, const muse::io::path_t& out, const OpenParams& openParams = {}) = 0;

virtual muse::Ret exportScoreVideo(const muse::io::path_t& in, const muse::io::path_t& out, const OpenParams& openParams = {}) = 0;
virtual muse::Ret exportScoreVideo(const muse::io::path_t& in, const muse::io::path_t& out, const OpenParams& openParams = {},
bool withAudio = true) = 0;

virtual muse::Ret updateSource(const muse::io::path_t& in, const std::string& newSource, bool forceMode = false) = 0;
};
Expand Down
26 changes: 16 additions & 10 deletions src/converter/internal/convertercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,12 +490,13 @@ muse::Ret ConverterController::convertPage(INotationWriterPtr writer, INotationP
return make_ok();
}

Ret ConverterController::convertFullNotation(INotationWriterPtr writer, INotationPtr notation, const muse::io::path_t& out) const
Ret ConverterController::convertFullNotation(INotationWriterPtr writer, INotationPtr notation, const muse::io::path_t& out,
const project::INotationWriter::Options& options) const
{
auto outBuf = Buffer::opened(IODevice::WriteOnly);

outBuf.setMeta("file_path", out.toStdString());
Ret ret = writer->write(notation, outBuf);
Ret ret = writer->write(notation, outBuf, options);
if (!ret) {
LOGE() << "failed write, err: " << ret.toString() << ", path: " << out;
return make_ret(Err::OutFileFailedWrite);
Expand Down Expand Up @@ -703,7 +704,8 @@ Ret ConverterController::exportScoreElements(const muse::io::path_t& in, const m
return BackendApi::exportScoreElements(in, out, openParams);
}

Ret ConverterController::exportScoreVideo(const muse::io::path_t& in, const muse::io::path_t& out, const OpenParams& openParams)
Ret ConverterController::exportScoreVideo(const muse::io::path_t& in, const muse::io::path_t& out, const OpenParams& openParams,
bool withAudio)
{
TRACEFUNC;

Expand All @@ -713,7 +715,7 @@ Ret ConverterController::exportScoreVideo(const muse::io::path_t& in, const muse
}

std::string suffix = io::suffix(out);
auto writer = projectRW()->writer(suffix);
auto writer = writers()->writer(suffix);
if (!writer) {
return make_ret(Err::ConvertTypeUnknown);
}
Expand All @@ -724,13 +726,17 @@ Ret ConverterController::exportScoreVideo(const muse::io::path_t& in, const muse
return make_ret(Err::InFileFailedLoad);
}

ret = writer->write(notationProject, out);
if (!ret) {
LOGE() << "failed write, err: " << ret.toString() << ", path: " << out;
return make_ret(Err::OutFileFailedWrite);
}
globalContext()->setCurrentProject(notationProject);

return make_ret(Ret::Code::Ok);
DEFER {
globalContext()->setCurrentProject(nullptr);
};

const INotationWriter::Options options {
{ INotationWriter::OptionKey::WITH_AUDIO, Val(withAudio) },
};

return convertFullNotation(writer, notationProject->masterNotation()->notation(), out, options);
}

Ret ConverterController::updateSource(const muse::io::path_t& in, const std::string& newSource, bool forceMode)
Expand Down
6 changes: 4 additions & 2 deletions src/converter/internal/convertercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ class ConverterController : public IConverterController, public muse::Contextabl

muse::Ret exportScoreElements(const muse::io::path_t& in, const muse::io::path_t& out, const OpenParams& openParams = {}) override;

muse::Ret exportScoreVideo(const muse::io::path_t& in, const muse::io::path_t& out, const OpenParams& openParams = {}) override;
muse::Ret exportScoreVideo(const muse::io::path_t& in, const muse::io::path_t& out, const OpenParams& openParams = {},
bool withAudio = true) override;

muse::Ret updateSource(const muse::io::path_t& in, const std::string& newSource, bool forceMode = false) override;

Expand Down Expand Up @@ -109,7 +110,8 @@ class ConverterController : public IConverterController, public muse::Contextabl
muse::Ret convertPageByPage(project::INotationWriterPtr writer, notation::INotationPtr notation, const muse::io::path_t& out) const;
muse::Ret convertPage(project::INotationWriterPtr writer, notation::INotationPtr notation, const size_t pageNum,
const muse::io::path_t& filePath, const muse::io::path_t& dirPath = {}) const;
muse::Ret convertFullNotation(project::INotationWriterPtr writer, notation::INotationPtr notation, const muse::io::path_t& out) const;
muse::Ret convertFullNotation(project::INotationWriterPtr writer, notation::INotationPtr notation, const muse::io::path_t& out,
const project::INotationWriter::Options& options = {}) const;

muse::Ret convertScorePartsToPdf(project::INotationWriterPtr writer, notation::IMasterNotationPtr masterNotation,
const muse::io::path_t& out) const;
Expand Down
4 changes: 4 additions & 0 deletions src/framework/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ if (MUSE_MODULE_LEARN)
add_subdirectory(learn)
endif()

if (MUSE_MODULE_MEDIA)
add_subdirectory(media)
endif()

if (MUSE_MODULE_EXTENSIONS)
add_subdirectory(extensions)
endif()
Expand Down
4 changes: 3 additions & 1 deletion src/framework/audio/common/audiotypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ enum class SoundTrackType {
MP3,
OGG,
FLAC,
WAV
WAV,
AAC
};

enum class AudioSampleFormat {
Expand Down Expand Up @@ -142,6 +143,7 @@ struct SoundTrackFormat {

case SoundTrackType::MP3:
case SoundTrackType::OGG:
case SoundTrackType::AAC:
// For lossy, bitrate must be positive
return bitRate > 0;

Expand Down
5 changes: 5 additions & 0 deletions src/framework/audio/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ if (MUSE_MODULE_AUDIO_EXPORT)
internal/export/flacencoder.h
internal/export/wavencoder.cpp
internal/export/wavencoder.h
internal/export/aacencoder.cpp
internal/export/aacencoder.h
)
if(MUE_COMPILE_USE_SYSTEM_LAME)
set(MUE_LAME_INCLUDE_DIR "" CACHE PATH "Path to directory containing lame/lame.h (optional)")
Expand Down Expand Up @@ -226,6 +228,9 @@ if (MUSE_MODULE_AUDIO_EXPORT)

include(../cmake/SetupFlac.cmake)
target_link_libraries(muse_audio_engine PRIVATE ${FLAC_TARGETS})

add_subdirectory(../thirdparty/fdk-aac fdk_aac EXCLUDE_FROM_ALL)
target_link_libraries(muse_audio_engine PRIVATE fdk_aac)
endif() # MUSE_MODULE_AUDIO_EXPORT

target_link_libraries(muse_audio_engine PRIVATE muse_audio_common)
Loading