Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #pragma once
24 :
25 : #include <memory>
26 :
27 : #include "async/asyncable.h"
28 :
29 : #include "io/filestream.h"
30 :
31 : #include "engraving/rendering/layoutoptions.h"
32 : #include "engraving/style/style.h"
33 :
34 : #include "modularity/ioc.h"
35 : #include "io/ifilesystem.h"
36 : #include "global/iapplication.h"
37 : #include "media/ivideoencoderresolver.h"
38 : #include "../ivideoexportconfiguration.h"
39 : #include "project/iprojectsession.h"
40 :
41 : #include "project/inotationwriter.h"
42 : #include "project/inotationwritersregister.h"
43 :
44 : class QImage;
45 :
46 : namespace muse::draw {
47 : class Painter;
48 : }
49 :
50 : namespace mu::iex::videoexport {
51 : class VideoWriter : public project::INotationWriter, public muse::Contextable, public muse::async::Asyncable
52 : {
53 : muse::GlobalInject<IVideoExportConfiguration> configuration;
54 : muse::GlobalInject<muse::io::IFileSystem> fileSystem;
55 : muse::GlobalInject<muse::IApplication> application;
56 : muse::GlobalInject<muse::media::IVideoEncoderResolver> videoEncodeResolver;
57 : muse::GlobalInject<project::INotationWritersRegister> writers;
58 : muse::ContextInject<project::IProjectSession> projectSession = { this };
59 :
60 : public:
61 0 : VideoWriter(const muse::modularity::ContextPtr& iocCtx)
62 0 : : muse::Contextable(iocCtx) {}
63 :
64 : std::vector<UnitType> supportedUnitTypes() const override;
65 : bool supportsUnitType(UnitType unitType) const override;
66 :
67 : muse::Ret write(notation::INotationPtr notation, muse::io::IODevice& device, const Options& options = Options()) override;
68 : muse::Ret writeList(const notation::INotationPtrList& notations, muse::io::IODevice& device,
69 : const Options& options = Options()) override;
70 :
71 : muse::Progress* progress() override;
72 : void abort() override;
73 :
74 : private:
75 : struct Config
76 : {
77 : int width = 1920;
78 : int height = 1080;
79 : int fps = 24;
80 : int bitrate = 800000;
81 : float leadingSec = 3.;
82 : float trailingSec = 3.;
83 : double canvasDpi = 300.0;
84 : ViewMode viewMode = ViewMode::PageFull;
85 : muse::PointF moveToCenter;
86 : };
87 :
88 : Config makeConfig() const;
89 :
90 : void startVideoExport(muse::media::IVideoEncoderPtr encoder, notation::INotationPtr notation, const Config& cfg);
91 : void startAudioExport(notation::INotationPtr notation, const muse::io::path_t& audioPath, const Config& cfg);
92 :
93 : void doGenerate(muse::media::IVideoEncoderPtr encoder, notation::INotationPtr notation, const Config& config);
94 :
95 : bool generateLeadingFrames(muse::media::IVideoEncoderPtr encoder, notation::INotationPtr notation, muse::draw::Painter& painter,
96 : QImage& frame, const Config& config, int totalFrameCount);
97 :
98 : bool generateScoreFrames(muse::media::IVideoEncoderPtr encoder, notation::INotationPtr notation, muse::draw::Painter& painter,
99 : QImage& frame, const Config& config, float totalPlayTimeSec, int leadingFrameCount, int totalFrameCount);
100 :
101 : bool generateTrailingFrames(muse::media::IVideoEncoderPtr encoder, const Config& config);
102 :
103 : struct ScoreRestoreData
104 : {
105 : engraving::MStyle style;
106 : engraving::LayoutMode layoutMode = engraving::LayoutMode::PAGE;
107 :
108 : bool showFrames = true;
109 : bool showInstrumentNames = true;
110 : bool showInvisible = true;
111 : bool showPageborders = false;
112 : bool showUnprintable = true;
113 : bool showVBox = true;
114 : };
115 :
116 : std::optional<ScoreRestoreData> prepareScore(notation::INotationPtr notation, Config& config);
117 : void restoreScore(notation::INotationPtr notation, const ScoreRestoreData& data);
118 :
119 : muse::Progress m_progress;
120 : bool m_abort = false;
121 : bool m_isCompleted = false;
122 : muse::Ret m_writeRet;
123 :
124 : project::INotationWriterPtr m_audioWriter;
125 : std::unique_ptr<muse::io::FileStream> m_audioFile;
126 : bool m_audioCompleted = false;
127 : muse::Ret m_audioRet;
128 : };
129 : }
|