Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
f7b65df
Add native video sync proposal
ToranadoMusic May 7, 2026
cc45a08
Add project video attachment settings
ToranadoMusic May 7, 2026
0c28053
Add native video panel shell
ToranadoMusic May 7, 2026
33b3dae
Add embedded video playback to video panel
ToranadoMusic May 8, 2026
68d54a6
Sync video panel playback to score transport
ToranadoMusic May 8, 2026
fbad270
Move video audio controls into mixer
ToranadoMusic May 8, 2026
e5d259e
Align video controls as mixer channel
ToranadoMusic May 8, 2026
a26c917
Represent video as mixer channel
ToranadoMusic May 8, 2026
eac589b
Make video panel responsive in bottom docks
ToranadoMusic May 8, 2026
ac6dfeb
Let video preview resize with panel
ToranadoMusic May 8, 2026
20ad0f7
Fix video solo and negative offset sync
ToranadoMusic May 8, 2026
4baf90e
Keep video panel controls below preview
ToranadoMusic May 8, 2026
d2a9af5
Handle video solo in playback controller
ToranadoMusic May 8, 2026
11c7208
Page settings: relax page number offset limits
cbjeukendrup May 7, 2026
dfb370f
install requests
Eism May 12, 2026
de0871b
Merge pull request #33362 from Eism/ci_learn_fix
Eism May 12, 2026
b248b44
Bump MF submodule (ce5bcfa)
krasko78 May 12, 2026
ae200c5
fixed setup dependencies
Eism May 13, 2026
b42abd4
[ci] updated check codestyle on CI
igorkorsukov May 13, 2026
4bf81c5
removed old codestyle tools
igorkorsukov May 13, 2026
f4b8872
updated framework
Eism May 13, 2026
eec876a
Merge pull request #33377 from Eism/build_deps_fix
Eism May 13, 2026
534b474
added mf tool
igorkorsukov May 13, 2026
445d0e9
bump MF submodule
igorkorsukov May 13, 2026
72908ab
Fix #33088: fix ioc issues in TimeSignaturePropertiesDialog
RomanPudashkin Apr 30, 2026
53ae59b
Fix crash in CustomizeKitDialog: loadPitchesList() depends on notation
RomanPudashkin Apr 30, 2026
379eaec
Fix #33142: fix ioc issues in SpecialCharactersDialog
RomanPudashkin May 6, 2026
a285ef4
ported media module from 4.7
Eism May 12, 2026
a532b73
ported video export update from 4.7
Eism Apr 20, 2026
52d7749
enabled video export by default
Eism Apr 20, 2026
30d5099
ported mp4 settings UI
Eism Apr 20, 2026
61b25f8
moved AutomaticUpdateSection to General page
Eism Apr 20, 2026
df68a7d
fixed compile errors
Eism Apr 20, 2026
8808817
ported aac encoder from 4.7
Eism Apr 20, 2026
8f45d9d
moved leading and trailing silence from 4.7
Eism Apr 22, 2026
d44e124
ported video section in preferences from 4.7
Eism Apr 23, 2026
e47c2f5
Fix spacing between fields in video preferences section
ajuncosa Apr 28, 2026
977f8d1
fixed #33114: added text word wrap for video title
Eism Apr 24, 2026
7fc219d
use MuseSans font for title
Eism Apr 24, 2026
dc521d7
fixed restoring playback state
Eism May 11, 2026
4d32072
added no-audio option for video export
Eism May 13, 2026
6b9571d
removed ProjectRWRegister because it is no longer needed
Eism May 13, 2026
3d2fd44
Merge pull request #33099 from Eism/video_export_port
RomanPudashkin May 14, 2026
e8df477
Merge pull request #33321 from cbjeukendrup/page-settings-relax-page-…
RomanPudashkin May 14, 2026
29c48ae
Merge branch 'musescore:main' into score-to-video
ToranadoMusic May 15, 2026
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
9 changes: 5 additions & 4 deletions .github/workflows/check_codestyle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ jobs:
uses: actions/checkout@v6
with:
submodules: recursive
- name: Fetch Muse CI scripts

- name: Test MSS coding style
run: |
cmake -P ./buildscripts/ci/checkcodestyle/ci_fetch.cmake
cmake -P ./muse/buildscripts/ci/checkcodestyle/checkcodestyle.cmake ./src/
- name: Test coding style
- name: Test MF coding style
run: |
cmake -P ./buildscripts/ci/checkcodestyle/_deps/checkcodestyle.cmake ./src/
cmake -P ./muse/buildscripts/ci/checkcodestyle/checkcodestyle.cmake ./muse/framework/
2 changes: 1 addition & 1 deletion .vscode_template/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"commands": [
{
"match": "\\.(cpp|c|h|hpp)$",
"cmd": "cmake -P ${workspaceFolder}/buildscripts/tools/codestyle/format_file.cmake '${file}'"
"cmd": "cmake -P ${workspaceFolder}/muse/tools/codestyle/format_file.cmake '${file}'"
}
]
}
Expand Down
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ set(CMAKE_MODULE_PATH
${CMAKE_CURRENT_LIST_DIR}/buildscripts
${CMAKE_CURRENT_LIST_DIR}/buildscripts/cmake
${MUSE_FRAMEWORK_SRC_PATH}/cmake
${MUSE_FRAMEWORK_PATH}/buildscripts/cmake
${CMAKE_MODULE_PATH}
)

Expand Down Expand Up @@ -97,7 +98,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 Expand Up @@ -210,6 +211,8 @@ endif(MUSE_COMPILE_USE_COMPILER_CACHE)
###########################################
# Setup external dependencies
###########################################
set(FETCHCONTENT_QUIET OFF)
set(FETCHCONTENT_BASE_DIR ${PROJECT_BINARY_DIR}/_deps)

if (MUE_COMPILE_MACOS_PRECOMPILED_DEPS_PATH)
list(PREPEND CMAKE_PREFIX_PATH ${MUE_COMPILE_MACOS_PRECOMPILED_DEPS_PATH})
Expand All @@ -225,6 +228,8 @@ if (MUE_DOWNLOAD_SOUNDFONT)
include(DownloadSoundFont)
endif(MUE_DOWNLOAD_SOUNDFONT)

set(FETCHCONTENT_BASE_DIR ${PROJECT_BINARY_DIR}/_deps)

include(SetupDependencies)

###########################################
Expand Down
1 change: 0 additions & 1 deletion buildscripts/ci/checkcodestyle/.gitignore

This file was deleted.

15 changes: 0 additions & 15 deletions buildscripts/ci/checkcodestyle/ci_fetch.cmake

This file was deleted.

2 changes: 2 additions & 0 deletions buildscripts/ci/learn/make_playlists_info_file.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,7 @@ cat $ARTIFACTS_DIR/playlist.json

echo "=== Make playlist for YouTube ==="

pip install requests

HERE="$(cd "$(dirname "$0")" && pwd)"
python3 $HERE/make_youtube_playlist_info.py ${YOUTUBE_API_KEY} ${YOUTUBE_PLAYLIST_ID} ${ARTIFACTS_DIR}/playlist.json
63 changes: 4 additions & 59 deletions buildscripts/cmake/SetupDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,64 +18,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

message(STATUS "Setup dependencies")
include(MuseDeps)

# Config
include(GetPlatformInfo)
include(GetBuildType)
# setup framework dependences
include(${MUSE_FRAMEWORK_PATH}/buildscripts/cmake/SetupDependencies.cmake)

set(LIB_OS )
if (OS_IS_WIN)
set(LIB_OS "windows")
elseif(OS_IS_LIN)
set(LIB_OS "linux")
elseif(OS_IS_FBSD)
set(LIB_OS "linux")
elseif(OS_IS_MAC)
set(LIB_OS "macos")
list(LENGTH CMAKE_OSX_ARCHITECTURES arch_count)
if(arch_count GREATER 1)
set(ARCH "universal")
endif()
endif()

set(LIB_ARCH ${ARCH})

if (BUILD_IS_RELEASE)
set(LIB_BUILD_TYPE "release")
else()
set(LIB_BUILD_TYPE "debug")
endif()

set(REMOTE_ROOT_URL https://raw.githubusercontent.com/musescore/muse_deps/main)
set(LOCAL_ROOT_PATH ${FETCHCONTENT_BASE_DIR})

function(populate name remote_suffix)
set(remote_url ${REMOTE_ROOT_URL}/${remote_suffix})
set(local_path ${LOCAL_ROOT_PATH}/${name})

if (NOT EXISTS ${local_path}/${name}.cmake)
file(MAKE_DIRECTORY ${local_path})
file(DOWNLOAD ${remote_url}/${name}.cmake ${local_path}/${name}.cmake
HTTPHEADER "Cache-Control: no-cache"
)
endif()

include(${local_path}/${name}.cmake)

# func from ${name}.cmake
cmake_language(CALL ${name}_Populate ${remote_url} ${local_path} ${LIB_OS} ${LIB_ARCH} ${LIB_BUILD_TYPE})

get_property(include_dirs GLOBAL PROPERTY ${name}_INCLUDE_DIRS)
get_property(libraries GLOBAL PROPERTY ${name}_LIBRARIES)
get_property(install_libraries GLOBAL PROPERTY ${name}_INSTALL_LIBRARIES)

set(${name}_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE)
set(${name}_LIBRARIES ${libraries} PARENT_SCOPE)
set(${name}_INSTALL_LIBRARIES ${install_libraries} PARENT_SCOPE)

endfunction()

if (MUSE_MODULE_DOCKWINDOW_KDDOCKWIDGETS_V2)
populate(kddockwidgets "kddockwidgets/2.4")
endif()
# add a list of local dependencies here
69 changes: 69 additions & 0 deletions docs/video-sync-native-proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Native Video Sync Proposal

## Goal

Add a native reference-video workflow to MuseScore Studio so users can compose against picture, keep video playback aligned with the score playhead, and control video audio through MuseScore playback controls.

## Initial Scope

The first implementation should stay intentionally narrow:

- attach one local video file to a score,
- store video path and offset metadata with the score,
- show a dockable video panel,
- sync play, pause, stop, and seek to MuseScore playback,
- provide video volume and mute controls.

Mixer-level solo and full audio-graph routing should follow after the playback and score-persistence model is accepted.

## User Workflow

1. The user chooses an Attach Video action.
2. MuseScore stores a reference to the selected video and opens a Video panel.
3. When score playback starts, the video starts at the matching score time plus offset.
4. When playback pauses or seeks, the video follows.
5. The user can nudge offset in milliseconds while working.
6. If the video is missing, MuseScore asks the user to relink it.

## Architecture Direction

### Score Metadata

Store score-level attachment data for:

- video file path,
- offset in milliseconds,
- volume,
- mute state,
- future relink identity such as file hash or original file name.

Prefer relative paths when the video is near the score file. Do not embed video data by default.

### Playback Sync

Add a video sync controller that listens to transport state and maps score playback position to video time. The controller should own drift correction rather than putting timing behavior in QML.

### UI

Add a dockable Video panel that uses the existing UI/dock registration patterns. The panel should be able to attach, detach, relink, play/pause through the global transport, and nudge offset.

### Audio

The MVP can begin with video-local mute and volume if needed. The release-quality target is a real Video source in MuseScore's audio/mixer layer so mute and solo behave like other playback channels.

## Open Questions

- Which existing score-project metadata layer is preferred for external media attachments?
- Which playback service should be the source of truth for elapsed score time?
- Is Qt Multimedia acceptable for the video decode/display layer on all supported platforms?
- Should video support be hidden behind an experimental flag while audio routing is incomplete?
- Should video audio participate in audio export, or should export be a later milestone?

## Suggested Patch Sequence

1. Add score/project metadata for an optional video attachment.
2. Add an inert internal video sync model and tests for persistence.
3. Add the Video panel UI.
4. Wire the panel to playback transport.
5. Add audio controls.
6. Add proper mixer/audio routing.
58 changes: 58 additions & 0 deletions mftool.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env bash


MF_ORIGIN_URL=https://github.com/musescore/muse_framework.git
MF_FORK_URL=""
TASK=""

while [[ "$#" -gt 0 ]]; do
case $1 in
-f|--fork) MF_FORK_URL="$2"; shift ;;
-t|--task) TASK="$2"; shift ;;
*) echo "Unknown parameter passed: $1"; exit 1 ;;
esac
shift
done

if [ -z "$MF_FORK_URL" ]; then MF_FORK_URL=$(cat mf_fork_url.local); fi
if [ -z "$MF_FORK_URL" ]; then echo "error: not set MF_FORK_URL"; exit 1; fi

if [ -z "$TASK" ]; then echo "error: not set TASK"; exit 1; fi

echo "MF_FORK_URL: $MF_FORK_URL"
echo "TASK: $TASK"


function use_fork() {
git submodule set-url muse $MF_FORK_URL
cd muse
git remote set-url origin $MF_FORK_URL
git remote remove upstream
git remote add upstream $MF_ORIGIN_URL
git remote -v
cd ..
}

function use_origin() {
git submodule set-url muse $MF_ORIGIN_URL
git submodule update --init
cd muse
git remote set-url origin $MF_ORIGIN_URL
git remote remove upstream
git remote -v
cd ..
}

case "$TASK" in
"use-fork")
use_fork
;;
"use-origin")
use_origin
;;
"sync-origin")
use_origin
git submodule update --init --remote ./muse
;;
*) echo "Unknown task: $TASK"; exit 1 ;;
esac
2 changes: 1 addition & 1 deletion muse
Submodule muse updated 316 files
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
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

find_package(Qt6 REQUIRED COMPONENTS Multimedia)

# Modules must be listed in dependency order
if (MUE_BUILD_BRAILLE_MODULE)
add_subdirectory(braille)
Expand Down
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,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::midiremote)
add_to_link_if_exists(muse::mpe)
Expand Down
7 changes: 7 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 @@ -344,6 +350,7 @@ std::shared_ptr<muse::IApplication> AppFactory::newGuiApp(const std::shared_ptr<
#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
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 MuseScoreCmdOptions : public muse::CmdOptions {
ExtensionUri,
PageNumber,
ScoreRegion,
NoAudio,
};

struct {
Expand Down
5 changes: 5 additions & 0 deletions src/app/configs/data/shortcuts.xml
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,11 @@
<seq>F12</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>toggle-video-panel</key>
<seq>Ctrl+Alt+V</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>quit</key>
<seq>Ctrl+Q</seq>
Expand Down
5 changes: 5 additions & 0 deletions src/app/configs/data/shortcuts_azerty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,11 @@
<seq>F12</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>toggle-video-panel</key>
<seq>Ctrl+Alt+V</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>quit</key>
<seq>Ctrl+Q</seq>
Expand Down
5 changes: 5 additions & 0 deletions src/app/configs/data/shortcuts_mac.xml
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,11 @@
<seq>F12</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>toggle-video-panel</key>
<seq>Ctrl+Alt+V</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>quit</key>
<seq>Ctrl+Q</seq>
Expand Down
Loading