1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-09-02 08:39:49 +02:00

Add better creation handling

Remove mp4 conversion
This commit is contained in:
Elias 2019-02-15 19:15:50 +01:00
parent c096be89cc
commit cdfcf34ac2
5 changed files with 165 additions and 323 deletions

View File

@ -13,9 +13,8 @@ Item {
anchors.fill: parent
state: "out"
Component.onCompleted: {
create.state = "in"
}
Component.onCompleted: create.state = "in"
property url activeVideoFile: ""
property url activeFolder: ""
@ -27,29 +26,15 @@ Item {
activeVideoFile = videoFile
loader.setSource(
"Wizards/CreateWallpaper/CreateWallpaperWizard.qml", {
"filePath": activeVideoFile,
"importState": CreateWallpaperWizard.ImportState.Convert
})
}
onVideoImportFileSelected: {
create.state = "import"
activeVideoFile = videoFile
loader.setSource(
"Wizards/CreateWallpaper/CreateWallpaperWizard.qml", {
"filePath": activeVideoFile,
"importState": CreateWallpaperWizard.ImportState.Import
"filePath": activeVideoFile
})
}
onProjectFileSelected: {
create.state = "import"
activeFolder = projectFile
loader.setSource("CreateNew.qml", {
})
// TODO
// activeFolder = projectFile
// loader.setSource("CreateNew.qml", { })
}
}

View File

@ -13,15 +13,14 @@ Item {
Component.onCompleted: createWallpaper.state = "in"
signal videoImportConvertFileSelected(var videoFile)
signal videoImportFileSelected(var videoFile)
signal projectFileSelected(var projectFile)
WorkshopLoader {
id: wl
}
Text {
id: txtHeadline
text: qsTr("Import Video Wallpaper")
text: qsTr("Import Wallpaper")
opacity: 0
anchors {
top: parent.top
@ -42,10 +41,9 @@ Item {
anchors {
top: parent.top
topMargin: 50
left:parent.left
left: parent.left
}
Rectangle {
id: importVideoBg
radius: 3
@ -91,9 +89,10 @@ Item {
FileDialog {
id: fileDialogImportVideo
// nameFilters: ["Video files (*.mp4)"]
nameFilters: ["Video files (*.webm)"]
onAccepted: {
videoImportConvertFileSelected(fileDialogImportVideo.currentFile)
videoImportConvertFileSelected(
fileDialogImportVideo.currentFile)
}
}
}
@ -122,7 +121,7 @@ Item {
anchors {
top: parent.top
topMargin: 50
left:wrapperImportVideo.right
left: wrapperImportVideo.right
leftMargin: 20
}
@ -137,7 +136,7 @@ Item {
Image {
id: imgUploadImportVideo2
source: "qrc:/assets/icons/icon_movie.svg"
source: "qrc:/assets/icons/icon_scene.svg"
height: 120
width: 120
anchors {
@ -154,7 +153,8 @@ Item {
}
Button {
text: qsTr("Convert Video")
text: qsTr("Import ThreeJs Scene")
enabled: false
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
@ -166,14 +166,15 @@ Item {
icon.color: "white"
icon.width: 16
icon.height: 16
onClicked: fileDialogImportVideo.open()
onClicked: fileDialogImportProject.open()
}
FileDialog {
id: fileDialogImportVideo2
// nameFilters: ["Video files (*.mp4)"]
id: fileDialogImportProject
nameFilters: ["ThreeJS Scene files(scene.pkg)"]
onAccepted: {
videoImportConvertFileSelected(fileDialogImportVideo.currentFile)
projectFileSelected(
fileDialogImportProject.currentFile)
}
}
}
@ -204,7 +205,7 @@ Item {
anchors {
top: wrapperConvertVideo.bottom
left:parent.left
left: parent.left
}
RectangularGlow {
@ -224,16 +225,15 @@ Item {
opacity: 0
}
Rectangle {
id: importVideoBg3
radius: 3
z: 10
anchors {
fill: parent
margins: 10
}
z: 10
Button {
text: qsTr("Upload Exsisting Project to Steam")
anchors.centerIn: parent
@ -244,14 +244,7 @@ Item {
icon.width: 16
icon.height: 16
onClicked: {
fileDialogOpenProject.open()
}
}
FileDialog {
id: fileDialogOpenProject3
nameFilters: ["Project files (project.json)"]
onAccepted: {
projectFileSelected(fileDialogOpenProject.currentFile)
}
}
}
@ -292,7 +285,6 @@ Item {
opacity: 0
anchors.topMargin: -100
}
},
State {
name: "in"
@ -355,8 +347,6 @@ Item {
easing.type: Easing.InOutQuart
}
}
}
PropertyAnimation {
targets: [txtHeadline]
@ -379,32 +369,6 @@ Item {
/*##^## Designer {
D{i:0;autoSize:true;height:480;width:640}
}

View File

@ -15,18 +15,12 @@ Item {
property bool canNext: false
property int importState: CreateWallpaperWizard.ImportState.Import
enum ImportState {
Create,
Import
}
Component.onCompleted: {
state = "in"
print(importState)
utility.setNavigationActive(false)
if (importState === CreateWallpaperWizard.ImportState.Import) {
loader_wrapperContent.source = "qrc:/qml/Create/Wizards/CreateWallpaper/CreateWallpaperVideoImport.qml"
loader_wrapperContent.source
= "qrc:/qml/Create/Wizards/CreateWallpaper/CreateWallpaperVideoImport.qml"
} else {
loader_wrapperContent.source = "qrc:/qml/Create/Wizards/CreateWallpaper/CreateWallpaperVideoImportConvert.qml"
}
@ -46,7 +40,6 @@ Item {
|| state === Create.State.ConvertingPreviewImageError
|| state === Create.State.AnalyseVideoError) {
createNew.state = "error"
return
}
}
}
@ -142,7 +135,7 @@ Item {
id: timerBack
interval: 800
onTriggered: {
screenPlayCreate.abort()
screenPlayCreate.abortAndCleanup()
utility.setNavigationActive(true)
utility.setNavigation("Create")
}
@ -195,7 +188,7 @@ Item {
opacity: .4
}
PropertyChanges {
target: wrapperContent
target: loader_wrapperContent
opacity: 0
z: 0
}
@ -216,7 +209,7 @@ Item {
opacity: .4
}
PropertyChanges {
target: wrapperContent
target: loader_wrapperContent
opacity: 0
z: 0
}
@ -301,7 +294,7 @@ Item {
to: "error"
SequentialAnimation {
PropertyAnimation {
target: wrapperContent
target: loader_wrapperContent
duration: 600
property: "opacity"
easing.type: Easing.OutQuart
@ -322,7 +315,7 @@ Item {
to: "success"
SequentialAnimation {
PropertyAnimation {
target: wrapperContent
target: loader_wrapperContent
duration: 600
property: "opacity"
easing.type: Easing.OutQuart

View File

@ -65,21 +65,26 @@ void Create::createWallpaperStart(QString videoPath)
return;
m_createWallpaperData.exportPath = dir.path() + "/" + folderName;
m_workingDir = m_createWallpaperData.exportPath;
this->setWorkingDir(m_createWallpaperData.exportPath);
// If we return early/false this means the creation
// process did not work
// Todo: cleanup!
bool ok = true;
if (!this->createWallpaperInfo())
return;
ok = false;
if (!this->createWallpaperVideoPreview())
return;
if (ok && !this->createWallpaperVideoPreview())
ok = false;
if (!this->createWallpaperVideo())
return;
if (ok && !this->createWallpaperGifPreview())
ok = false;
if (ok && !this->extractWallpaperAudio())
ok = false;
if (!ok)
abortAndCleanup();
});
}
@ -167,11 +172,106 @@ bool Create::createWallpaperInfo()
bool Create::createWallpaperVideoPreview()
{
/*
*
* Create png
*
*/
QStringList args;
args.append("-loglevel");
args.append("error");
args.append("-y");
args.append("-stats");
args.append("-i");
args.append(m_createWallpaperData.videoPath);
args.append("-speed");
args.append("ultrafast");
args.append("-vf");
// We allways want to have a 5 second clip via 24fps -> 120 frames
// Divided by the number of frames we can skip (timeInSeconds * Framrate)
// scale & crop parameter: https://unix.stackexchange.com/a/284731
args.append("select='not(mod(n," + QString::number((m_createWallpaperData.length / 5)) + "))',setpts=N/FRAME_RATE/TB,crop=in_h*16/9:in_h,scale=-2:400");
// Disable audio
args.append("-an");
args.append(m_createWallpaperData.exportPath + "/preview.webm");
QScopedPointer<QProcess> proConvertPreviewWebM(new QProcess());
proConvertPreviewWebM.data()->setArguments(args);
#ifdef Q_OS_WIN
proConvertPreviewWebM.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg.exe");
#endif
#ifdef Q_OS_MACOS
proConvertPreviewMP4.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg");
#endif
emit createWallpaperStateChanged(Create::State::ConvertingPreviewVideo);
connect(this, &Create::abortCreateWallpaper, proConvertPreviewWebM.data(), &QProcess::kill);
proConvertPreviewWebM.data()->start();
while (!proConvertPreviewWebM.data()->waitForFinished(100)) //Wake up every 100ms and check if we must exit
{
QCoreApplication::processEvents();
}
disconnect(this, &Create::abortCreateWallpaper, proConvertPreviewWebM.data(), &QProcess::kill);
QString tmpErr = proConvertPreviewWebM.data()->readAllStandardError();
if (!tmpErr.isEmpty()) {
QFile previewVideo(m_createWallpaperData.exportPath + "/preview.webm");
if (!previewVideo.exists() && !(previewVideo.size() > 0)) {
emit processOutput(tmpErr);
emit createWallpaperStateChanged(Create::State::ConvertingPreviewVideoError);
return false;
}
}
this->processOutput(proConvertPreviewWebM.data()->readAll());
proConvertPreviewWebM.data()->close();
emit createWallpaperStateChanged(Create::State::ConvertingPreviewVideoFinished);
return true;
}
bool Create::createWallpaperGifPreview()
{
emit createWallpaperStateChanged(Create::State::ConvertingPreviewGif);
QStringList args;
args.append("-y");
args.append("-stats");
args.append("-i");
args.append(m_createWallpaperData.exportPath + "/preview.webm");
args.append("-filter_complex");
args.append("[0:v] fps=12,scale=w=480:h=-1,split [a][b];[a] palettegen=stats_mode=single [p];[b][p] paletteuse=new=1");
args.append(m_createWallpaperData.exportPath + "/preview.gif");
QScopedPointer<QProcess> proConvertGif(new QProcess());
proConvertGif.data()->setArguments(args);
#ifdef Q_OS_WIN
proConvertGif.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg.exe");
#endif
#ifdef Q_OS_MACOS
proConvertGif.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg");
#endif
connect(this, &Create::abortCreateWallpaper, proConvertGif.data(), &QProcess::kill);
proConvertGif.data()->start();
while (!proConvertGif.data()->waitForFinished(100)) //Wake up every 100ms and check if we must exit
{
QCoreApplication::processEvents();
}
disconnect(this, &Create::abortCreateWallpaper, proConvertGif.data(), &QProcess::kill);
QString tmpErrGif = proConvertGif.data()->readAllStandardError();
if (!tmpErrGif.isEmpty()) {
QFile previewGif(m_createWallpaperData.exportPath + "/preview.gif");
if (!previewGif.exists() && !(previewGif.size() > 0)) {
emit createWallpaperStateChanged(Create::State::ConvertingPreviewGifError);
return false;
}
}
this->processOutput(proConvertGif.data()->readAll());
proConvertGif.data()->close();
emit createWallpaperStateChanged(Create::State::ConvertingPreviewGifFinished);
return true;
}
bool Create::createWallpaperImagePreview()
{
emit createWallpaperStateChanged(Create::State::ConvertingPreviewImage);
@ -217,118 +317,12 @@ bool Create::createWallpaperVideoPreview()
proConvertImage.data()->close();
emit createWallpaperStateChanged(Create::State::ConvertingPreviewImageFinished);
/*
*
* Create preview mp4
*
*/
args.append("-loglevel");
args.append("error");
args.append("-y");
args.append("-stats");
args.append("-i");
args.append(m_createWallpaperData.videoPath);
args.append("-speed");
args.append("ultrafast");
args.append("-vf");
// We allways want to have a 5 second clip via 24fps -> 120 frames
// Divided by the number of frames we can skip (timeInSeconds * Framrate)
// scale & crop parameter: https://unix.stackexchange.com/a/284731
args.append("select='not(mod(n," + QString::number((m_createWallpaperData.length / 5)) + "))',setpts=N/FRAME_RATE/TB,crop=in_h*16/9:in_h,scale=-2:400");
// Disable audio
args.append("-an");
args.append(m_createWallpaperData.exportPath + "/preview.mp4");
QScopedPointer<QProcess> proConvertPreviewMP4(new QProcess());
proConvertPreviewMP4.data()->setArguments(args);
#ifdef Q_OS_WIN
proConvertPreviewMP4.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg.exe");
#endif
#ifdef Q_OS_MACOS
proConvertPreviewMP4.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg");
#endif
emit createWallpaperStateChanged(Create::State::ConvertingPreviewVideo);
connect(this, &Create::abortCreateWallpaper, proConvertPreviewMP4.data(), &QProcess::kill);
proConvertPreviewMP4.data()->start();
while (!proConvertPreviewMP4.data()->waitForFinished(100)) //Wake up every 100ms and check if we must exit
{
QCoreApplication::processEvents();
}
disconnect(this, &Create::abortCreateWallpaper, proConvertPreviewMP4.data(), &QProcess::kill);
QString tmpErr = proConvertPreviewMP4.data()->readAllStandardError();
if (!tmpErr.isEmpty()) {
QFile previewVideo(m_createWallpaperData.exportPath + "/preview.mp4");
if (!previewVideo.exists() && !(previewVideo.size() > 0)) {
emit processOutput(tmpErr);
emit createWallpaperStateChanged(Create::State::ConvertingPreviewVideoError);
return false;
}
}
this->processOutput(proConvertPreviewMP4.data()->readAll());
proConvertPreviewMP4.data()->close();
emit createWallpaperStateChanged(Create::State::ConvertingPreviewVideoFinished);
/*
*
* Create gif
*
*/
emit createWallpaperStateChanged(Create::State::ConvertingPreviewGif);
args.clear();
args.append("-y");
args.append("-stats");
args.append("-i");
args.append(m_createWallpaperData.exportPath + "/preview.mp4");
args.append("-filter_complex");
args.append("[0:v] fps=12,scale=w=480:h=-1,split [a][b];[a] palettegen=stats_mode=single [p];[b][p] paletteuse=new=1");
args.append(m_createWallpaperData.exportPath + "/preview.gif");
QScopedPointer<QProcess> proConvertGif(new QProcess());
proConvertGif.data()->setArguments(args);
#ifdef Q_OS_WIN
proConvertGif.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg.exe");
#endif
#ifdef Q_OS_MACOS
proConvertGif.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg");
#endif
connect(this, &Create::abortCreateWallpaper, proConvertGif.data(), &QProcess::kill);
proConvertGif.data()->start();
while (!proConvertGif.data()->waitForFinished(100)) //Wake up every 100ms and check if we must exit
{
QCoreApplication::processEvents();
}
disconnect(this, &Create::abortCreateWallpaper, proConvertGif.data(), &QProcess::kill);
QString tmpErrGif = proConvertGif.data()->readAllStandardError();
if (!tmpErrGif.isEmpty()) {
QFile previewGif(m_createWallpaperData.exportPath + "/preview.gif");
if (!previewGif.exists() && !(previewGif.size() > 0)) {
emit createWallpaperStateChanged(Create::State::ConvertingPreviewGifError);
return false;
}
}
this->processOutput(proConvertGif.data()->readAll());
proConvertGif.data()->close();
emit createWallpaperStateChanged(Create::State::ConvertingPreviewGifFinished);
return true;
}
bool Create::createWallpaperVideo()
bool Create::extractWallpaperAudio()
{
/*
*
* Extract audio
*
*/
emit createWallpaperStateChanged(Create::State::ConvertingAudio);
QStringList args;
@ -374,105 +368,6 @@ bool Create::createWallpaperVideo()
proConvertAudio.data()->close();
emit createWallpaperStateChanged(Create::State::ConvertingAudioFinished);
/*
*
* Create video
*
*/
emit createWallpaperStateChanged(Create::State::ConvertingVideo);
args.clear();
args.append("-hide_banner");
args.append("-y");
args.append("-stats");
args.append("-i");
args.append(m_createWallpaperData.videoPath);
args.append("-c:v");
args.append("libvpx-vp9");
args.append("-crf");
args.append("30");
args.append("-threads");
args.append("16");
args.append("-slices");
args.append("16");
args.append("-cpu-used");
args.append("4");
args.append("-pix_fmt");
args.append("yuv420p");
args.append("-b:v");
args.append("0");
args.append(m_createWallpaperData.exportPath + "/video.webm");
QScopedPointer<QProcess> proConvertVideo(new QProcess());
proConvertVideo.data()->setArguments(args);
proConvertVideo.data()->setProcessChannelMode(QProcess::MergedChannels);
#ifdef Q_OS_WIN
proConvertVideo.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg.exe");
#endif
#ifdef Q_OS_MACOS
proConvertVideo.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg");
#endif
connect(proConvertVideo.data(), &QProcess::readyRead, this, [&]() {
// Somehow readyRead gets seldom called in the end with an
// not valid QProcess pointer....
if (proConvertVideo.isNull()) {
qDebug() << "EROR NULL";
return;
}
if (!proConvertVideo.data()->isOpen()) {
qDebug() << "ERROR NOT OPEN";
return;
}
if (!proConvertVideo.data()->isReadable()) {
qDebug() << "ERROR CANNOT READ LINE";
return;
}
QString tmpOut = proConvertVideo.data()->readAll();
auto tmpList = tmpOut.split(QRegExp("\\s+"), QString::SkipEmptyParts);
if (tmpList.length() > 2) {
bool ok = false;
float currentFrame = QString(tmpList.at(1)).toFloat(&ok);
if (!ok)
return;
float progress = currentFrame / (m_createWallpaperData.length * m_createWallpaperData.framerate);
this->setProgress(progress);
}
this->processOutput(tmpOut);
},
Qt::QueuedConnection);
connect(this, &Create::abortCreateWallpaper, proConvertVideo.data(), &QProcess::kill);
proConvertVideo.data()->start(QIODevice::ReadOnly);
while (!proConvertVideo.data()->waitForFinished(100)) //Wake up every 100ms and check if we must exit
{
QCoreApplication::processEvents();
}
disconnect(proConvertVideo.data(), &QProcess::readyReadStandardOutput, nullptr, nullptr);
disconnect(this, &Create::abortCreateWallpaper, proConvertVideo.data(), &QProcess::kill);
QString out = proConvertVideo.data()->readAllStandardOutput();
this->processOutput(out);
QString tmpErrVideo = proConvertVideo.data()->readAllStandardError();
if (!tmpErrVideo.isEmpty()) {
QFile video(m_createWallpaperData.exportPath + "/video.webm");
if (!video.exists() && !(video.size() > 0)) {
emit createWallpaperStateChanged(Create::State::ConvertingVideoError);
return false;
}
}
proConvertVideo.data()->close();
emit createWallpaperStateChanged(Create::State::ConvertingVideoFinished);
return true;
}
@ -494,18 +389,19 @@ bool Create::createWallpaperProjectFile(const QString title, const QString descr
configObj.insert("file", "video.webm");
configObj.insert("preview", "preview.png");
configObj.insert("previewGIF", "preview.gif");
configObj.insert("previewMP4", "preview.mp4");
configObj.insert("previewWebM", "preview.webm");
configObj.insert("type", "video");
QJsonDocument configJsonDocument(configObj);
out << configJsonDocument.toJson();
configFile.close();
return true;
emit createWallpaperStateChanged(Create::State::Finished);
return true;
}
void Create::abort()
void Create::abortAndCleanup()
{
emit abortCreateWallpaper();
m_futureWatcher.cancel();
@ -516,6 +412,8 @@ void Create::abort()
if (!exportPath.removeRecursively()) {
emit createWallpaperStateChanged(Create::State::AbortCleanupError);
qWarning() << "Could not delete temp exportPath: " << exportPath;
} else {
qDebug() << "cleanup " << m_createWallpaperData.exportPath;
}
}
}

View File

@ -50,21 +50,23 @@ public:
AnalyseVideo,
AnalyseVideoFinished,
AnalyseVideoError,
ConvertingPreviewImage,
ConvertingPreviewImageFinished,
ConvertingPreviewImageError,
ConvertingPreviewVideo,
ConvertingPreviewVideoFinished,
ConvertingPreviewVideoError, //10
ConvertingPreviewVideoError,
ConvertingPreviewGif,
ConvertingPreviewGifFinished,
ConvertingPreviewGifError,
ConvertingPreviewImage,
ConvertingPreviewImageFinished,
ConvertingPreviewImageError,
ConvertingAudio,
ConvertingAudioFinished,
ConvertingAudioError,
ConvertingVideo,
ConvertingVideoFinished,
ConvertingVideoError,
// Oh well... Due to so many patents around video codecs
// the user has to convert the video on his own :(
// ConvertingVideo,
// ConvertingVideoFinished,
// ConvertingVideoError,
AbortCleanupError,
Finished,
ErrorUnknown,
@ -97,11 +99,11 @@ public slots:
void createWallpaperStart(QString videoPath);
bool createWallpaperInfo();
bool createWallpaperVideoPreview();
bool createWallpaperVideo();
bool createWallpaperGifPreview();
bool createWallpaperImagePreview();
bool extractWallpaperAudio();
bool createWallpaperProjectFile(const QString title, const QString description);
void abort();
void abortAndCleanup();
void setWorkingDir(QString workingDir)
{