1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-09-15 06:52:34 +02:00

Add ability to save wallpapers

Add preview
Cleanup
This commit is contained in:
Elias 2019-03-28 21:26:47 +01:00
parent 0d12c84107
commit 22ef3494e0
6 changed files with 102 additions and 77 deletions

View File

@ -3,14 +3,16 @@ import QtGraphicalEffects 1.0
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.3 import QtQuick.Controls.Material 2.3
import Qt.labs.platform 1.0 import Qt.labs.platform 1.0
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.12
import net.aimber.create 1.0 import net.aimber.create 1.0
Item { Item {
id: wrapperContent id: wrapperContent
property bool conversionFinishedSuccessful: false
property string customVideoPreviewPath: "" property bool canSave: false
signal save
Text { Text {
id: txtHeadline id: txtHeadline
@ -96,18 +98,15 @@ Item {
imgPreview.source = "file:///" imgPreview.source = "file:///"
+ screenPlayCreate.workingDir + "/preview.png" + screenPlayCreate.workingDir + "/preview.png"
imgPreview.visible = true imgPreview.visible = true
txtConvert.text = qsTr( txtConvert.text = qsTr("Converting Video preview mp4")
"Converting Video preview mp4")
} }
if (state === CreateImportVideo.State.ConvertingPreviewVideo) { if (state === CreateImportVideo.State.ConvertingPreviewVideo) {
txtConvert.text = qsTr( txtConvert.text = qsTr("Generating preview video...")
"Generating preview video...")
} }
if (state === CreateImportVideo.State.ConvertingPreviewGif) { if (state === CreateImportVideo.State.ConvertingPreviewGif) {
txtConvert.text = qsTr( txtConvert.text = qsTr("Generating preview gif...")
"Generating preview gif...")
} }
if (state === CreateImportVideo.State.ConvertingPreviewGifFinished) { if (state === CreateImportVideo.State.ConvertingPreviewGifFinished) {
@ -124,8 +123,9 @@ Item {
} }
if (state === CreateImportVideo.State.Finished) { if (state === CreateImportVideo.State.Finished) {
imgSuccess.source = "file:///" txtConvert.text = ""
+ screenPlayCreate.workingDir + "/preview.gif" conversionFinishedSuccessful = true
busyIndicator.running = false
} }
} }
onProgressChanged: { onProgressChanged: {
@ -151,16 +151,17 @@ Item {
Rectangle { Rectangle {
height: 50 height: 50
color: "#eeeeee" color: "#eeeeee"
Layout.fillWidth: true Layout.preferredWidth: imgWrapper.width
Text { Text {
id: txtCustomPreviewPath id: txtCustomPreviewPath
color: "#333333" color: "#333333"
text: qsTr("Add custom preview image") text: qsTr("Add custom preview image")
anchors { anchors {
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
leftMargin: 10 leftMargin: 20
} }
} }
@ -176,10 +177,9 @@ Item {
onClicked: fileDialogOpenFile.open() onClicked: fileDialogOpenFile.open()
} }
FileDialog { FileDialog {
id: fileDialogOpenFile id: fileDialogOpenFile
nameFilters: ["*.png *.jpg"] nameFilters: []
onAccepted: { onAccepted: {
var file = fileDialogOpenFile.file.toString() var file = fileDialogOpenFile.file.toString()
@ -207,44 +207,44 @@ Item {
right: parent.right right: parent.right
left: parent.left left: parent.left
margins: 30 margins: 30
top:parent.top top: parent.top
topMargin: 0 topMargin: 0
bottom: column1.top bottom: column1.top
bottomMargin: 50 bottomMargin: 50
} }
TextField { TextField {
id: textField id: textFieldName
placeholderText: qsTr("Name") placeholderText: qsTr("Name")
width:parent.width width: parent.width
Layout.fillWidth: true Layout.fillWidth: true
onTextChanged: { onTextChanged: {
if (textField.text.length >= 3) { if (textFieldName.text.length >= 3) {
canNext = true canSave = true
} else { } else {
canNext = false canSave = false
} }
} }
} }
TextField { TextField {
id: textField1 id: textFieldDescription
placeholderText: qsTr("Description") placeholderText: qsTr("Description")
width:parent.width width: parent.width
Layout.fillWidth: true Layout.fillWidth: true
} }
TextField { TextField {
id: textField2 id: textFieldYoutubeURL
placeholderText: qsTr("Youtube URL") placeholderText: qsTr("Youtube URL")
width:parent.width width: parent.width
Layout.fillWidth: true Layout.fillWidth: true
} }
TextField { TextField {
id: textField3 id: textFieldTags
width:parent.width width: parent.width
placeholderText: qsTr("Tags") placeholderText: qsTr("Tags (seperate with comma)")
Layout.fillWidth: true Layout.fillWidth: true
} }
} }
@ -271,33 +271,32 @@ Item {
} }
} }
NextButton { Button {
id: btnFinish id: btnFinish
onClicked: { text: qsTr("Save")
if (btnFinish.state === "enabled" && canNext) { Material.background: Material.Gray
screenPlayCreate.createWallpaperProjectFile( Material.foreground: "white"
textField.text, textField1.text) enabled: {
utility.setNavigationActive(true) if (canSave && conversionFinishedSuccessful) {
createNew.state = "success" return true
} else {
return false
} }
} }
}
}
Connections { onClicked: {
target: screenPlayCreate if (conversionFinishedSuccessful) {
onCreateWallpaperStateChanged: { screenPlayCreate.saveWallpaper(
if (state === CreateImportVideo.State.ConvertingVideoFinished) { textFieldName.text, textFieldDescription.text, textFieldYoutubeURL.text, textFieldTags.text)
btnFinish.state = "enabled" }
} }
} }
} }
} }
} }
/*##^## Designer { /*##^## Designer {
D{i:0;autoSize:true;height:480;width:640} D{i:0;autoSize:true;height:480;width:950}
} }
##^##*/ ##^##*/

View File

@ -30,12 +30,14 @@ Item {
Connections { Connections {
target: screenPlayCreate target: screenPlayCreate
onCreateWallpaperStateChanged: { onCreateWallpaperStateChanged: {
if (state === CreateImportVideo.State.AnalyseVideoError
if (state === CreateImportVideo.State.ConvertingPreviewGifError
|| state === CreateImportVideo.State.ConvertingPreviewVideoError || state === CreateImportVideo.State.ConvertingPreviewVideoError
|| state === CreateImportVideo.State.ConvertingPreviewGifError
|| state === CreateImportVideo.State.ConvertingPreviewImageError || state === CreateImportVideo.State.ConvertingPreviewImageError
|| state === CreateImportVideo.State.AnalyseVideoError) { || state === CreateImportVideo.State.ConvertingAudioError
createNew.state = "error" || state === CreateImportVideo.State.AbortCleanupError
|| state === CreateImportVideo.State.ErrorUnknown) {
createNew.state = "result"
} }
} }
} }
@ -84,6 +86,12 @@ Item {
id: loader_wrapperContent id: loader_wrapperContent
anchors.fill: parent anchors.fill: parent
z: 10 z: 10
Connections {
target: loader_wrapperContent.sourceComponent
onSave:{
createNew.state = "result"
}
}
} }
CreateWallpaperResult { CreateWallpaperResult {
@ -275,7 +283,7 @@ Item {
}, },
Transition { Transition {
from: "in" from: "in"
to: "error" to: "result"
SequentialAnimation { SequentialAnimation {
PropertyAnimation { PropertyAnimation {
target: loader_wrapperContent target: loader_wrapperContent
@ -293,21 +301,6 @@ Item {
easing.type: Easing.OutQuart easing.type: Easing.OutQuart
} }
} }
},
Transition {
from: "in"
to: "success"
SequentialAnimation {
PropertyAnimation {
target: loader_wrapperContent
duration: 600
property: "opacity"
easing.type: Easing.OutQuart
}
PauseAnimation {
duration: 50
}
}
} }
] ]
} }

View File

@ -55,18 +55,20 @@ void Create::createWallpaperStart(QString videoPath)
videoPath.remove("file:///"); videoPath.remove("file:///");
QDir dir; QDir dir;
dir.cd(this->m_settings->localStoragePath().toLocalFile()); dir.cd(m_settings->localStoragePath().toLocalFile());
// Create a temp dir so we can later alter it to the workshop id // Create a temp dir so we can later alter it to the workshop id
auto folderName = QString("_tmp_" + QTime::currentTime().toString()).replace(":", ""); auto folderName = QString("_tmp_" + QTime::currentTime().toString()).replace(":", "");
if (!dir.mkdir(folderName)) { if (!dir.mkdir(folderName)) {
emit createWallpaperStateChanged(CreateImportVideo::State::CreateTmpFolderError);
emit abortCreateWallpaper(); emit abortCreateWallpaper();
return; return;
} }
setWorkingDir(dir.path() + "/" + folderName);
m_createImportVideoThread = new QThread; m_createImportVideoThread = new QThread;
m_createImportVideo = new CreateImportVideo(videoPath, dir.path() + "/" + folderName); m_createImportVideo = new CreateImportVideo(videoPath, workingDir());
connect(m_createImportVideo, &CreateImportVideo::createWallpaperStateChanged, this, &Create::createWallpaperStateChanged); connect(m_createImportVideo, &CreateImportVideo::createWallpaperStateChanged, this, &Create::createWallpaperStateChanged);
connect(m_createImportVideoThread, &QThread::started, m_createImportVideo, &CreateImportVideo::process); connect(m_createImportVideoThread, &QThread::started, m_createImportVideo, &CreateImportVideo::process);
@ -78,8 +80,17 @@ void Create::createWallpaperStart(QString videoPath)
m_createImportVideoThread->start(); m_createImportVideoThread->start();
} }
void Create::createWallpaperProjectFile(QString name, QString description, QString youtube, QStringList tags)
{
}
void Create::abortAndCleanup() void Create::abortAndCleanup()
{ {
if (m_createImportVideo != nullptr || m_createImportVideoThread != nullptr) {
return;
}
// Save to export path before aborting to be able to cleanup the tmp folder // Save to export path before aborting to be able to cleanup the tmp folder
QString tmpExportPath = m_createImportVideo->m_exportPath; QString tmpExportPath = m_createImportVideo->m_exportPath;
@ -94,6 +105,8 @@ void Create::abortAndCleanup()
qDebug() << "cleanup " << tmpExportPath; qDebug() << "cleanup " << tmpExportPath;
} }
} }
m_createImportVideo = nullptr;
m_createImportVideoThread = nullptr;
}); });
m_createImportVideoThread->requestInterruption(); m_createImportVideoThread->requestInterruption();
} }

View File

@ -31,6 +31,7 @@ class Create : public QObject {
public: public:
explicit Create(Settings* st, QMLUtilities* util, QObject* parent = nullptr); explicit Create(Settings* st, QMLUtilities* util, QObject* parent = nullptr);
Q_PROPERTY(QString workingDir READ workingDir WRITE setWorkingDir NOTIFY workingDirChanged)
Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged) Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged)
Create() {} Create() {}
@ -41,17 +42,24 @@ public:
return m_progress; return m_progress;
} }
QString workingDir() const
{
return m_workingDir;
}
signals: signals:
void createWallpaperStateChanged(CreateImportVideo::State state); void createWallpaperStateChanged(CreateImportVideo::State state);
void processOutput(QString text); void processOutput(QString text);
void progressChanged(float progress); void progressChanged(float progress);
void abortCreateWallpaper(); void abortCreateWallpaper();
void workingDirChanged(QString workingDir);
public slots: public slots:
void copyProject(QString relativeProjectPath, QString toPath); void copyProject(QString relativeProjectPath, QString toPath);
bool copyRecursively(const QString& srcFilePath, const QString& tgtFilePath); bool copyRecursively(const QString& srcFilePath, const QString& tgtFilePath);
void abortAndCleanup();
void createWallpaperStart(QString videoPath); void createWallpaperStart(QString videoPath);
void saveWallpaper(QString name, QString description, QString youtube, QString tags);
void abortAndCleanup();
void setProgress(float progress) void setProgress(float progress)
{ {
@ -62,6 +70,15 @@ public slots:
emit progressChanged(m_progress); emit progressChanged(m_progress);
} }
void setWorkingDir(QString workingDir)
{
if (m_workingDir == workingDir)
return;
m_workingDir = workingDir;
emit workingDirChanged(m_workingDir);
}
private: private:
CreateImportVideo* m_createImportVideo; CreateImportVideo* m_createImportVideo;
Settings* m_settings; Settings* m_settings;
@ -69,4 +86,5 @@ private:
QMLUtilities* m_utils; QMLUtilities* m_utils;
float m_progress = 0.0f; float m_progress = 0.0f;
QString m_workingDir;
}; };

View File

@ -14,11 +14,13 @@ CreateImportVideo::CreateImportVideo(QString videoPath, QString exportPath, QObj
void CreateImportVideo::process() void CreateImportVideo::process()
{ {
qDebug() << "start converting video" << QThread::currentThreadId(); qDebug() << "start converting video in thread: " << QThread::currentThreadId();
createWallpaperInfo(); createWallpaperInfo();
createWallpaperVideoPreview(); createWallpaperVideoPreview();
createWallpaperGifPreview(); createWallpaperGifPreview();
extractWallpaperAudio(); extractWallpaperAudio();
emit createWallpaperStateChanged(CreateImportVideo::State::Finished);
emit finished(); emit finished();
} }
@ -117,20 +119,20 @@ bool CreateImportVideo::createWallpaperVideoPreview()
{ {
QStringList args; QStringList args;
// args.append("-loglevel"); args.append("-loglevel");
// args.append("error"); args.append("error");
// args.append("-y"); args.append("-y");
// args.append("-stats"); args.append("-stats");
args.append("-i"); args.append("-i");
args.append(m_videoPath); args.append(m_videoPath);
//args.append("-vf"); args.append("-vf");
// We allways want to have a 5 second clip via 24fps -> 120 frames // We allways want to have a 5 second clip via 24fps -> 120 frames
// Divided by the number of frames we can skip (timeInSeconds * Framrate) // Divided by the number of frames we can skip (timeInSeconds * Framrate)
// scale & crop parameter: https://unix.stackexchange.com/a/284731 // scale & crop parameter: https://unix.stackexchange.com/a/284731
//args.append("select='not(mod(n," + QString::number((m_length / 5)) + "))',setpts=N/FRAME_RATE/TB,crop=in_h*16/9:in_h,scale=-2:400"); args.append("select='not(mod(n," + QString::number((m_length / 5)) + "))',setpts=N/FRAME_RATE/TB,crop=in_h*16/9:in_h,scale=-2:400");
// Disable audio // Disable audio
//args.append("-an"); args.append("-an");
args.append(m_exportPath + "/preview.webm"); args.append(m_exportPath + "/preview.webm");
QScopedPointer<QProcess> proConvertPreviewWebM(new QProcess()); QScopedPointer<QProcess> proConvertPreviewWebM(new QProcess());
@ -143,7 +145,6 @@ bool CreateImportVideo::createWallpaperVideoPreview()
#endif #endif
emit createWallpaperStateChanged(CreateImportVideo::State::ConvertingPreviewVideo); emit createWallpaperStateChanged(CreateImportVideo::State::ConvertingPreviewVideo);
proConvertPreviewWebM.data()->start(); proConvertPreviewWebM.data()->start();
while (!proConvertPreviewWebM.data()->waitForFinished(100)) //Wake up every 100ms and check if we must exit while (!proConvertPreviewWebM.data()->waitForFinished(100)) //Wake up every 100ms and check if we must exit
{ {

View File

@ -45,6 +45,7 @@ public:
// ConvertingVideoFinished, // ConvertingVideoFinished,
// ConvertingVideoError, // ConvertingVideoError,
AbortCleanupError, AbortCleanupError,
CreateTmpFolderError,
Finished, Finished,
ErrorUnknown, ErrorUnknown,
}; };