mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-11-07 03:22:33 +01:00
Add better creation handling
Remove mp4 conversion
This commit is contained in:
parent
c096be89cc
commit
cdfcf34ac2
@ -13,9 +13,8 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
state: "out"
|
state: "out"
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: create.state = "in"
|
||||||
create.state = "in"
|
|
||||||
}
|
|
||||||
property url activeVideoFile: ""
|
property url activeVideoFile: ""
|
||||||
property url activeFolder: ""
|
property url activeFolder: ""
|
||||||
|
|
||||||
@ -27,29 +26,15 @@ Item {
|
|||||||
activeVideoFile = videoFile
|
activeVideoFile = videoFile
|
||||||
loader.setSource(
|
loader.setSource(
|
||||||
"Wizards/CreateWallpaper/CreateWallpaperWizard.qml", {
|
"Wizards/CreateWallpaper/CreateWallpaperWizard.qml", {
|
||||||
"filePath": activeVideoFile,
|
"filePath": activeVideoFile
|
||||||
"importState": CreateWallpaperWizard.ImportState.Convert
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onVideoImportFileSelected: {
|
|
||||||
create.state = "import"
|
|
||||||
|
|
||||||
|
|
||||||
activeVideoFile = videoFile
|
|
||||||
loader.setSource(
|
|
||||||
"Wizards/CreateWallpaper/CreateWallpaperWizard.qml", {
|
|
||||||
"filePath": activeVideoFile,
|
|
||||||
"importState": CreateWallpaperWizard.ImportState.Import
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onProjectFileSelected: {
|
onProjectFileSelected: {
|
||||||
create.state = "import"
|
create.state = "import"
|
||||||
|
// TODO
|
||||||
activeFolder = projectFile
|
// activeFolder = projectFile
|
||||||
loader.setSource("CreateNew.qml", {
|
// loader.setSource("CreateNew.qml", { })
|
||||||
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,15 +13,14 @@ Item {
|
|||||||
Component.onCompleted: createWallpaper.state = "in"
|
Component.onCompleted: createWallpaper.state = "in"
|
||||||
|
|
||||||
signal videoImportConvertFileSelected(var videoFile)
|
signal videoImportConvertFileSelected(var videoFile)
|
||||||
signal videoImportFileSelected(var videoFile)
|
|
||||||
|
|
||||||
signal projectFileSelected(var projectFile)
|
signal projectFileSelected(var projectFile)
|
||||||
|
|
||||||
WorkshopLoader {
|
WorkshopLoader {
|
||||||
id: wl
|
id: wl
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
id: txtHeadline
|
id: txtHeadline
|
||||||
text: qsTr("Import Video Wallpaper")
|
text: qsTr("Import Wallpaper")
|
||||||
opacity: 0
|
opacity: 0
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
@ -42,10 +41,9 @@ Item {
|
|||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
topMargin: 50
|
topMargin: 50
|
||||||
left:parent.left
|
left: parent.left
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: importVideoBg
|
id: importVideoBg
|
||||||
radius: 3
|
radius: 3
|
||||||
@ -91,9 +89,10 @@ Item {
|
|||||||
|
|
||||||
FileDialog {
|
FileDialog {
|
||||||
id: fileDialogImportVideo
|
id: fileDialogImportVideo
|
||||||
// nameFilters: ["Video files (*.mp4)"]
|
nameFilters: ["Video files (*.webm)"]
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
videoImportConvertFileSelected(fileDialogImportVideo.currentFile)
|
videoImportConvertFileSelected(
|
||||||
|
fileDialogImportVideo.currentFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,7 +121,7 @@ Item {
|
|||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
topMargin: 50
|
topMargin: 50
|
||||||
left:wrapperImportVideo.right
|
left: wrapperImportVideo.right
|
||||||
leftMargin: 20
|
leftMargin: 20
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +136,7 @@ Item {
|
|||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: imgUploadImportVideo2
|
id: imgUploadImportVideo2
|
||||||
source: "qrc:/assets/icons/icon_movie.svg"
|
source: "qrc:/assets/icons/icon_scene.svg"
|
||||||
height: 120
|
height: 120
|
||||||
width: 120
|
width: 120
|
||||||
anchors {
|
anchors {
|
||||||
@ -154,7 +153,8 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
text: qsTr("Convert Video")
|
text: qsTr("Import ThreeJs Scene")
|
||||||
|
enabled: false
|
||||||
anchors {
|
anchors {
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
@ -166,14 +166,15 @@ Item {
|
|||||||
icon.color: "white"
|
icon.color: "white"
|
||||||
icon.width: 16
|
icon.width: 16
|
||||||
icon.height: 16
|
icon.height: 16
|
||||||
onClicked: fileDialogImportVideo.open()
|
onClicked: fileDialogImportProject.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
FileDialog {
|
FileDialog {
|
||||||
id: fileDialogImportVideo2
|
id: fileDialogImportProject
|
||||||
// nameFilters: ["Video files (*.mp4)"]
|
nameFilters: ["ThreeJS Scene files(scene.pkg)"]
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
videoImportConvertFileSelected(fileDialogImportVideo.currentFile)
|
projectFileSelected(
|
||||||
|
fileDialogImportProject.currentFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,7 +205,7 @@ Item {
|
|||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: wrapperConvertVideo.bottom
|
top: wrapperConvertVideo.bottom
|
||||||
left:parent.left
|
left: parent.left
|
||||||
}
|
}
|
||||||
|
|
||||||
RectangularGlow {
|
RectangularGlow {
|
||||||
@ -224,16 +225,15 @@ Item {
|
|||||||
opacity: 0
|
opacity: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: importVideoBg3
|
id: importVideoBg3
|
||||||
radius: 3
|
radius: 3
|
||||||
|
z: 10
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
fill: parent
|
||||||
margins: 10
|
margins: 10
|
||||||
}
|
}
|
||||||
z: 10
|
|
||||||
Button {
|
Button {
|
||||||
text: qsTr("Upload Exsisting Project to Steam")
|
text: qsTr("Upload Exsisting Project to Steam")
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@ -244,14 +244,7 @@ Item {
|
|||||||
icon.width: 16
|
icon.width: 16
|
||||||
icon.height: 16
|
icon.height: 16
|
||||||
onClicked: {
|
onClicked: {
|
||||||
fileDialogOpenProject.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FileDialog {
|
|
||||||
id: fileDialogOpenProject3
|
|
||||||
nameFilters: ["Project files (project.json)"]
|
|
||||||
onAccepted: {
|
|
||||||
projectFileSelected(fileDialogOpenProject.currentFile)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,7 +285,6 @@ Item {
|
|||||||
opacity: 0
|
opacity: 0
|
||||||
anchors.topMargin: -100
|
anchors.topMargin: -100
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "in"
|
name: "in"
|
||||||
@ -355,8 +347,6 @@ Item {
|
|||||||
easing.type: Easing.InOutQuart
|
easing.type: Easing.InOutQuart
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
PropertyAnimation {
|
PropertyAnimation {
|
||||||
targets: [txtHeadline]
|
targets: [txtHeadline]
|
||||||
@ -379,32 +369,6 @@ Item {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*##^## Designer {
|
/*##^## Designer {
|
||||||
D{i:0;autoSize:true;height:480;width:640}
|
D{i:0;autoSize:true;height:480;width:640}
|
||||||
}
|
}
|
||||||
|
@ -15,18 +15,12 @@ Item {
|
|||||||
property bool canNext: false
|
property bool canNext: false
|
||||||
property int importState: CreateWallpaperWizard.ImportState.Import
|
property int importState: CreateWallpaperWizard.ImportState.Import
|
||||||
|
|
||||||
enum ImportState {
|
|
||||||
Create,
|
|
||||||
Import
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
state = "in"
|
state = "in"
|
||||||
print(importState)
|
|
||||||
utility.setNavigationActive(false)
|
utility.setNavigationActive(false)
|
||||||
if (importState === CreateWallpaperWizard.ImportState.Import) {
|
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 {
|
} else {
|
||||||
loader_wrapperContent.source = "qrc:/qml/Create/Wizards/CreateWallpaper/CreateWallpaperVideoImportConvert.qml"
|
loader_wrapperContent.source = "qrc:/qml/Create/Wizards/CreateWallpaper/CreateWallpaperVideoImportConvert.qml"
|
||||||
}
|
}
|
||||||
@ -46,7 +40,6 @@ Item {
|
|||||||
|| state === Create.State.ConvertingPreviewImageError
|
|| state === Create.State.ConvertingPreviewImageError
|
||||||
|| state === Create.State.AnalyseVideoError) {
|
|| state === Create.State.AnalyseVideoError) {
|
||||||
createNew.state = "error"
|
createNew.state = "error"
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,7 +135,7 @@ Item {
|
|||||||
id: timerBack
|
id: timerBack
|
||||||
interval: 800
|
interval: 800
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
screenPlayCreate.abort()
|
screenPlayCreate.abortAndCleanup()
|
||||||
utility.setNavigationActive(true)
|
utility.setNavigationActive(true)
|
||||||
utility.setNavigation("Create")
|
utility.setNavigation("Create")
|
||||||
}
|
}
|
||||||
@ -195,7 +188,7 @@ Item {
|
|||||||
opacity: .4
|
opacity: .4
|
||||||
}
|
}
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: wrapperContent
|
target: loader_wrapperContent
|
||||||
opacity: 0
|
opacity: 0
|
||||||
z: 0
|
z: 0
|
||||||
}
|
}
|
||||||
@ -216,7 +209,7 @@ Item {
|
|||||||
opacity: .4
|
opacity: .4
|
||||||
}
|
}
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: wrapperContent
|
target: loader_wrapperContent
|
||||||
opacity: 0
|
opacity: 0
|
||||||
z: 0
|
z: 0
|
||||||
}
|
}
|
||||||
@ -301,7 +294,7 @@ Item {
|
|||||||
to: "error"
|
to: "error"
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
PropertyAnimation {
|
PropertyAnimation {
|
||||||
target: wrapperContent
|
target: loader_wrapperContent
|
||||||
duration: 600
|
duration: 600
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
easing.type: Easing.OutQuart
|
easing.type: Easing.OutQuart
|
||||||
@ -322,7 +315,7 @@ Item {
|
|||||||
to: "success"
|
to: "success"
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
PropertyAnimation {
|
PropertyAnimation {
|
||||||
target: wrapperContent
|
target: loader_wrapperContent
|
||||||
duration: 600
|
duration: 600
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
easing.type: Easing.OutQuart
|
easing.type: Easing.OutQuart
|
||||||
|
@ -65,21 +65,26 @@ void Create::createWallpaperStart(QString videoPath)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_createWallpaperData.exportPath = dir.path() + "/" + folderName;
|
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
|
// If we return early/false this means the creation
|
||||||
// process did not work
|
// process did not work
|
||||||
// Todo: cleanup!
|
bool ok = true;
|
||||||
|
|
||||||
if (!this->createWallpaperInfo())
|
if (!this->createWallpaperInfo())
|
||||||
return;
|
ok = false;
|
||||||
|
|
||||||
if (!this->createWallpaperVideoPreview())
|
if (ok && !this->createWallpaperVideoPreview())
|
||||||
return;
|
ok = false;
|
||||||
|
|
||||||
if (!this->createWallpaperVideo())
|
if (ok && !this->createWallpaperGifPreview())
|
||||||
return;
|
ok = false;
|
||||||
|
|
||||||
|
if (ok && !this->extractWallpaperAudio())
|
||||||
|
ok = false;
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
abortAndCleanup();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,11 +172,106 @@ bool Create::createWallpaperInfo()
|
|||||||
bool Create::createWallpaperVideoPreview()
|
bool Create::createWallpaperVideoPreview()
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
QStringList args;
|
||||||
*
|
args.append("-loglevel");
|
||||||
* Create png
|
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);
|
emit createWallpaperStateChanged(Create::State::ConvertingPreviewImage);
|
||||||
|
|
||||||
@ -217,118 +317,12 @@ bool Create::createWallpaperVideoPreview()
|
|||||||
proConvertImage.data()->close();
|
proConvertImage.data()->close();
|
||||||
emit createWallpaperStateChanged(Create::State::ConvertingPreviewImageFinished);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Create::createWallpaperVideo()
|
bool Create::extractWallpaperAudio()
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Extract audio
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
emit createWallpaperStateChanged(Create::State::ConvertingAudio);
|
emit createWallpaperStateChanged(Create::State::ConvertingAudio);
|
||||||
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
@ -374,105 +368,6 @@ bool Create::createWallpaperVideo()
|
|||||||
proConvertAudio.data()->close();
|
proConvertAudio.data()->close();
|
||||||
emit createWallpaperStateChanged(Create::State::ConvertingAudioFinished);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,18 +389,19 @@ bool Create::createWallpaperProjectFile(const QString title, const QString descr
|
|||||||
configObj.insert("file", "video.webm");
|
configObj.insert("file", "video.webm");
|
||||||
configObj.insert("preview", "preview.png");
|
configObj.insert("preview", "preview.png");
|
||||||
configObj.insert("previewGIF", "preview.gif");
|
configObj.insert("previewGIF", "preview.gif");
|
||||||
configObj.insert("previewMP4", "preview.mp4");
|
configObj.insert("previewWebM", "preview.webm");
|
||||||
configObj.insert("type", "video");
|
configObj.insert("type", "video");
|
||||||
|
|
||||||
QJsonDocument configJsonDocument(configObj);
|
QJsonDocument configJsonDocument(configObj);
|
||||||
out << configJsonDocument.toJson();
|
out << configJsonDocument.toJson();
|
||||||
configFile.close();
|
configFile.close();
|
||||||
return true;
|
|
||||||
|
|
||||||
emit createWallpaperStateChanged(Create::State::Finished);
|
emit createWallpaperStateChanged(Create::State::Finished);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Create::abort()
|
void Create::abortAndCleanup()
|
||||||
{
|
{
|
||||||
emit abortCreateWallpaper();
|
emit abortCreateWallpaper();
|
||||||
m_futureWatcher.cancel();
|
m_futureWatcher.cancel();
|
||||||
@ -516,6 +412,8 @@ void Create::abort()
|
|||||||
if (!exportPath.removeRecursively()) {
|
if (!exportPath.removeRecursively()) {
|
||||||
emit createWallpaperStateChanged(Create::State::AbortCleanupError);
|
emit createWallpaperStateChanged(Create::State::AbortCleanupError);
|
||||||
qWarning() << "Could not delete temp exportPath: " << exportPath;
|
qWarning() << "Could not delete temp exportPath: " << exportPath;
|
||||||
|
} else {
|
||||||
|
qDebug() << "cleanup " << m_createWallpaperData.exportPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,21 +50,23 @@ public:
|
|||||||
AnalyseVideo,
|
AnalyseVideo,
|
||||||
AnalyseVideoFinished,
|
AnalyseVideoFinished,
|
||||||
AnalyseVideoError,
|
AnalyseVideoError,
|
||||||
ConvertingPreviewImage,
|
|
||||||
ConvertingPreviewImageFinished,
|
|
||||||
ConvertingPreviewImageError,
|
|
||||||
ConvertingPreviewVideo,
|
ConvertingPreviewVideo,
|
||||||
ConvertingPreviewVideoFinished,
|
ConvertingPreviewVideoFinished,
|
||||||
ConvertingPreviewVideoError, //10
|
ConvertingPreviewVideoError,
|
||||||
ConvertingPreviewGif,
|
ConvertingPreviewGif,
|
||||||
ConvertingPreviewGifFinished,
|
ConvertingPreviewGifFinished,
|
||||||
ConvertingPreviewGifError,
|
ConvertingPreviewGifError,
|
||||||
|
ConvertingPreviewImage,
|
||||||
|
ConvertingPreviewImageFinished,
|
||||||
|
ConvertingPreviewImageError,
|
||||||
ConvertingAudio,
|
ConvertingAudio,
|
||||||
ConvertingAudioFinished,
|
ConvertingAudioFinished,
|
||||||
ConvertingAudioError,
|
ConvertingAudioError,
|
||||||
ConvertingVideo,
|
// Oh well... Due to so many patents around video codecs
|
||||||
ConvertingVideoFinished,
|
// the user has to convert the video on his own :(
|
||||||
ConvertingVideoError,
|
// ConvertingVideo,
|
||||||
|
// ConvertingVideoFinished,
|
||||||
|
// ConvertingVideoError,
|
||||||
AbortCleanupError,
|
AbortCleanupError,
|
||||||
Finished,
|
Finished,
|
||||||
ErrorUnknown,
|
ErrorUnknown,
|
||||||
@ -97,11 +99,11 @@ public slots:
|
|||||||
void createWallpaperStart(QString videoPath);
|
void createWallpaperStart(QString videoPath);
|
||||||
bool createWallpaperInfo();
|
bool createWallpaperInfo();
|
||||||
bool createWallpaperVideoPreview();
|
bool createWallpaperVideoPreview();
|
||||||
bool createWallpaperVideo();
|
bool createWallpaperGifPreview();
|
||||||
|
bool createWallpaperImagePreview();
|
||||||
|
bool extractWallpaperAudio();
|
||||||
bool createWallpaperProjectFile(const QString title, const QString description);
|
bool createWallpaperProjectFile(const QString title, const QString description);
|
||||||
|
void abortAndCleanup();
|
||||||
void abort();
|
|
||||||
|
|
||||||
|
|
||||||
void setWorkingDir(QString workingDir)
|
void setWorkingDir(QString workingDir)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user