1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-07-08 21:56:04 +02:00

Refactor video wizard into a single wizard

This commit is contained in:
Elias Steurer 2024-01-05 14:10:18 +01:00
parent b41242a938
commit bd5516fb41
19 changed files with 231 additions and 1285 deletions

View File

@ -64,16 +64,11 @@ set(QML
qml/Create/Wizards/GodotWallpaper.qml
qml/Create/Wizards/HTMLWallpaper.qml
qml/Create/Wizards/HTMLWidget.qml
qml/Create/Wizards/Importh264/Importh264.qml
qml/Create/Wizards/Importh264/Importh264Convert.qml
qml/Create/Wizards/Importh264/Importh264Init.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperFileSelect.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperSettings.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml
qml/Create/Wizards/ImportWebm/ImportWebm.qml
qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml
qml/Create/Wizards/ImportWebm/ImportWebmInit.qml
qml/Create/Wizards/QMLWallpaper.qml
qml/Create/Wizards/QMLWidget.qml
qml/Create/Wizards/WebsiteWallpaper.qml

View File

@ -34,7 +34,6 @@ class Create : public QObject {
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
Q_PROPERTY(QString workingDir READ workingDir WRITE setWorkingDir NOTIFY workingDirChanged)
Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged)
@ -45,13 +44,22 @@ public:
Create();
enum class VideoCodec {
VP8,
VP9,
AV1,
H264
};
Q_ENUM(VideoCodec)
Q_INVOKABLE void cancel();
Q_INVOKABLE void createWallpaperStart(
QString videoPath,
ScreenPlay::Video::VideoCodec codec,
const int quality = 50);
Q_INVOKABLE void saveWallpaper(const QString title,
const QString description,
QString filePath,
QString previewImagePath,
const QString youtube,
const ScreenPlay::Video::VideoCodec codec,
const QVector<QString> tags);
Q_INVOKABLE void abortAndCleanup();
float progress() const { return m_progress; }
QString workingDir() const { return m_workingDir; }
@ -68,22 +76,6 @@ signals:
void finished();
public slots:
void cancel();
void createWallpaperStart(QString videoPath, Create::VideoCodec codec = Create::VideoCodec::VP9, const int quality = 50);
void importH264(QString videoPath);
void saveWallpaper(const QString title,
const QString description,
QString filePath,
QString previewImagePath,
const QString youtube,
const ScreenPlay::Create::VideoCodec codec,
const QVector<QString> tags);
void abortAndCleanup();
void setProgress(float progress)
{
if (qFuzzyCompare(m_progress, progress))

View File

@ -19,6 +19,7 @@
#include <QtMath>
#include "ScreenPlay/createimportstates.h"
#include "ScreenPlayUtil/contenttypes.h"
namespace ScreenPlay {
@ -30,8 +31,12 @@ class CreateImportVideo : public QObject {
Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged)
public:
explicit CreateImportVideo(const QString& videoPath, const QString& exportPath, const QString& codec, const int quality, std::atomic<bool>& interrupt);
explicit CreateImportVideo(const QString& videoPath, const QString& exportPath, std::atomic<bool>& interrupt);
explicit CreateImportVideo(
const QString& videoPath,
const QString& exportPath,
const ScreenPlay::Video::VideoCodec targetCodec,
const int quality,
std::atomic<bool>& interrupt);
enum class Executable {
FFMPEG,
@ -50,7 +55,8 @@ public:
QString m_videoPath;
QString m_exportPath;
QString m_format;
QString m_codec;
Video::VideoCodec m_targetCodec;
Video::VideoCodec m_sourceCodec;
const int m_quality = 50;
int m_numberOfFrames { 0 };

View File

@ -23,10 +23,8 @@
#include <QtConcurrent/QtConcurrent>
#include "ScreenPlay/globalvariables.h"
#include "ScreenPlay/profilelistmodel.h"
#include "ScreenPlay/settings.h"
#include "ScreenPlayUtil/projectfile.h"
#include "ScreenPlayUtil/util.h"
#include <memory>

View File

@ -17,7 +17,7 @@ Rectangle {
property alias model: listView.model
property StackView stackView
width: 380
width: 340
state: expanded ? "" : "inactive"
layer.enabled: true
Component.onCompleted: expanded = true
@ -56,19 +56,7 @@ Rectangle {
}
ListElement {
headline: qsTr("Video Import h264 (.mp4)")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/Importh264/Importh264.qml"
category: "Video Wallpaper"
}
ListElement {
headline: qsTr("Video Import VP8 & VP9 (.webm)")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/ImportWebm/ImportWebm.qml"
category: "Video Wallpaper"
}
ListElement {
headline: qsTr("Video import (all types)")
headline: qsTr("Import Video")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml"
category: "Video Wallpaper"
objectName: "videoImportConvert"
@ -83,25 +71,25 @@ Rectangle {
ListElement {
headline: qsTr("3D Engine Wallpaper (Godot 4.2)")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/GodotWallpaper.qml"
category: "3D Engine & Code Wallpaper"
category: "3D Engine & \nCode Wallpaper"
}
ListElement {
headline: qsTr("QML Wallpaper")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/QMLWallpaper.qml"
category: "3D Engine & Code Wallpaper"
category: "3D Engine & \nCode Wallpaper"
}
ListElement {
headline: qsTr("HTML5 Wallpaper")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/HTMLWallpaper.qml"
category: "3D Engine & Code Wallpaper"
category: "3D Engine & \nCode Wallpaper"
}
ListElement {
headline: qsTr("Website Wallpaper")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/WebsiteWallpaper.qml"
category: "3D Engine & Code Wallpaper"
category: "3D Engine & \nCode Wallpaper"
}
ListElement {
@ -123,9 +111,10 @@ Rectangle {
}
section.delegate: Item {
height: 60
height: headline.contentHeight + 20
Text {
id:headline
font.pointSize: 18
color: Material.primaryTextColor
text: section

View File

@ -19,18 +19,20 @@ Item {
anchors.fill: parent
interactive: false
clip: true
CreateWallpaperInit {
onNext: function (filePath, codec) {
startConvert(filePath, codec);
CreateWallpaperFileSelect {
onNext: function (filePath) {
createWallpaperVideoImportConvert.filePath = filePath
swipeView.currentIndex = 1
}
}
function startConvert(filePath, codec) {
root.wizardStarted();
swipeView.currentIndex = 1;
createWallpaperVideoImportConvert.codec = codec;
createWallpaperVideoImportConvert.filePath = filePath;
App.create.createWallpaperStart(filePath, codec, quality);
CreateWallpaperSettings {
id: createWallpaperSettings
onNext: function (codec,quality) {
root.wizardStarted()
swipeView.currentIndex = 2
createWallpaperVideoImportConvert.codec = codec
App.create.createWallpaperStart(createWallpaperVideoImportConvert.filePath, codec, quality)
}
}
@ -40,7 +42,6 @@ Item {
onAbort: root.wizardExited()
}
CreateWallpaperResult {
}
CreateWallpaperResult {}
}
}

View File

@ -11,6 +11,7 @@ import "../../"
Item {
id: root
property var allowedVideoFileEndings: ["*.webm", "*.mkv", "*.mp4", "*.mpg", "*.mp2", "*.mpeg", "*.ogv", "*.avi", "*.wmv", "*.m4v", "*.3gp"]
signal next(var filePath)
@ -29,7 +30,7 @@ Item {
Util.Headline {
Layout.fillWidth: true
text: qsTr("Import a .mp4 video")
text: qsTr("Import Video Wallpaper")
}
RowLayout {
@ -42,37 +43,37 @@ Item {
Layout.fillHeight: true
spacing: 40
Text {
id: txtDescription
text: qsTr("ScreenPlay v0.15 and up can play *.mp4 (also more known as h264). This can improove performance on older systems.")
color: Material.primaryTextColor
Layout.fillWidth: true
font.pointSize: 13
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.family: App.settings.font
}
DropArea {
id: dropArea
Layout.fillHeight: true
Layout.fillWidth: true
onExited: {
bg.color = Qt.darker(Material.backgroundColor);
}
onEntered: {
bg.color = Qt.darker(Qt.darker(Material.backgroundColor));
drag.accept(Qt.LinkAction);
}
onDropped: {
let file = App.util.toLocal(drop.urls[0]);
bg.color = Qt.darker(Qt.darker(Material.backgroundColor));
if (file.endsWith(".mp4"))
root.next(drop.urls[0]);
else
txtFile.text = qsTr("Invalid file type. Must be valid h264 (*.mp4)!");
bg.color = Qt.darker(Material.backgroundColor)
}
onEntered: drag => {
bg.color = Qt.darker(
Qt.darker(Material.backgroundColor))
drag.accept(Qt.LinkAction)
}
onDropped: drop => {
let file = App.util.toLocal(drop.urls[0])
bg.color = Qt.darker(
Qt.darker(Material.backgroundColor))
let found = false
for (let ending in root.allowedVideoFileEndings) {
if (file.endsWith(ending)) {
found = true
break
}
}
if (found) {
root.next(drop.urls[0])
} else {
txtFile.text = qsTr(
"Invalid file type. Must be valid video!")
}
}
Rectangle {
id: bg
@ -94,7 +95,8 @@ Item {
Text {
id: txtFile
text: qsTr("Drop a *.mp4 file here or use 'Select file' below.")
text: qsTr("Drag and drop your video here. Supported video formats are:\n\n%1").arg(
root.allowedVideoFileEndings.join(" "))
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
color: Material.primaryTextColor
font.pointSize: 13
@ -123,7 +125,8 @@ Item {
icon.width: 16
icon.height: 16
font.family: App.settings.font
onClicked: Qt.openUrlExternally("https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
onClicked: Qt.openUrlExternally(
"https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
anchors {
bottom: parent.bottom
@ -137,7 +140,7 @@ Item {
highlighted: true
font.family: App.settings.font
onClicked: {
fileDialogImportVideo.open();
fileDialogImportVideo.open()
}
FileDialog {
@ -145,7 +148,7 @@ Item {
nameFilters: ["Video files (*.mp4)"]
onAccepted: {
root.next(fileDialogImportVideo.currentFile);
root.next(fileDialogImportVideo.currentFile)
}
}

View File

@ -14,7 +14,7 @@ Item {
property int quality: sliderQuality.slider.value
signal next(var filePath, var codec)
signal next(var codec, var quality)
ColumnLayout {
spacing: 40
@ -29,14 +29,13 @@ Item {
Util.Headline {
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
text: qsTr("Import any video type")
text: qsTr("Import Video Wallpaper - Select Codec")
}
Text {
id: txtDescription
text: qsTr("Depending on your PC configuration it is better to convert your wallpaper to a specific video codec. If both have bad performance you can also try a QML wallpaper! Supported video formats are: \n
*.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv")
text: qsTr("Depending on your PC configuration it is better to convert your wallpaper to a specific video codec. We skip encoding if the input format matches the ouput format.")
color: Material.primaryTextColor
Layout.fillWidth: true
font.pointSize: 13
@ -63,11 +62,15 @@ Item {
Layout.preferredWidth: 400
textRole: "text"
valueRole: "value"
currentIndex: 1
currentIndex: 0
font.family: App.settings.font
model: ListModel {
id: model
ListElement {
text: "✨h.264 (Better for all hardware)"
value: Util.Video.VideoCodec.H264
}
ListElement {
text: "VP8 (Better for older hardware)"
@ -86,7 +89,7 @@ Item {
id: sliderQuality
iconSource: "qrc:/qml/ScreenPlayApp/assets/icons/icon_settings.svg"
headline: qsTr("Quality slider. Lower value means better quality.")
headline: qsTr("Set video quality. Lower value means better quality.")
Layout.preferredWidth: 400
slider {
@ -107,7 +110,8 @@ Item {
icon.width: 16
icon.height: 16
font.family: App.settings.font
onClicked: Qt.openUrlExternally("https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
onClicked: Qt.openUrlExternally(
"https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
anchors {
bottom: parent.bottom
@ -116,23 +120,15 @@ Item {
}
Button {
objectName: "createWallpaperInitFileSelectButton"
text: qsTr("Select file")
objectName: "createWallpaperStartImportButton"
text: qsTr("Start import")
highlighted: true
font.family: App.settings.font
onClicked: {
fileDialogImportVideo.open();
let a = Util.Video.VideoCodec.H264
let targetCodec = comboBoxCodec.currentValue
root.next(a, sliderQuality.slider.value)
}
FileDialog {
id: fileDialogImportVideo
nameFilters: ["Video files (*.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv)"]
onAccepted: {
root.next(fileDialogImportVideo.currentFile, model.get(comboBoxCodec.currentIndex).value);
}
}
anchors {
right: parent.right
bottom: parent.bottom

View File

@ -12,7 +12,7 @@ Item {
property bool conversionFinishedSuccessful: false
property bool canSave: false
property var codec: Create.VP8
property var codec: Util.Video.VideoCodec.H264
property string filePath
signal abort
@ -335,7 +335,14 @@ Item {
onClicked: {
if (conversionFinishedSuccessful) {
btnSave.enabled = false;
App.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, codec, textFieldTags.getTags());
App.create.saveWallpaper(
textFieldName.text,
textFieldDescription.text,
root.filePath,
previewSelector.imageSource,
textFieldYoutubeURL.text,
root.codec,
textFieldTags.getTags());
savePopup.open();
}
}

View File

@ -1,39 +0,0 @@
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
import ScreenPlayApp
import ScreenPlay
Item {
id: root
signal wizardStarted
signal wizardExited
signal next
SwipeView {
id: swipeView
anchors.fill: parent
interactive: false
clip: true
ImportWebmInit {
onNext: function (filePath) {
root.wizardStarted();
swipeView.currentIndex = 1;
createWallpaperVideoImportConvert.filePath = filePath;
App.util.setNavigationActive(false);
App.create.createWallpaperStart(filePath);
}
}
ImportWebmConvert {
id: createWallpaperVideoImportConvert
onExit: root.wizardExited()
}
}
}

View File

@ -1,373 +0,0 @@
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util
Item {
id: root
property bool conversionFinishedSuccessful: false
property bool canSave: false
property string filePath
signal exit
signal save
function basename(str) {
let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1));
let filename = filenameWithExtentions.split('.').slice(0, -1).join('.');
return filename;
}
function checkCanSave() {
if (canSave && conversionFinishedSuccessful)
btnSave.enabled = true;
else
btnSave.enabled = false;
}
onCanSaveChanged: root.checkCanSave()
onFilePathChanged: {
textFieldName.text = basename(filePath);
}
Connections {
function onCreateWallpaperStateChanged(state) {
switch (state) {
case Import.State.AnalyseVideo:
txtConvert.text = qsTr("AnalyseVideo...");
break;
case Import.State.ConvertingPreviewImage:
txtConvert.text = qsTr("Generating preview image...");
break;
case Import.State.ConvertingPreviewThumbnailImage:
txtConvert.text = qsTr("Generating preview thumbnail image...");
break;
case Import.State.ConvertingPreviewImageFinished:
imgPreview.source = "file:///" + App.create.workingDir + "/preview.jpg";
imgPreview.visible = true;
break;
case Import.State.ConvertingPreviewVideo:
txtConvert.text = qsTr("Generating 5 second preview video...");
break;
case Import.State.ConvertingPreviewGif:
txtConvert.text = qsTr("Generating preview gif...");
break;
case Import.State.ConvertingPreviewGifFinished:
gifPreview.source = "file:///" + App.create.workingDir + "/preview.gif";
imgPreview.visible = false;
gifPreview.visible = true;
gifPreview.playing = true;
break;
case Import.State.ConvertingAudio:
txtConvert.text = qsTr("Converting Audio...");
break;
case Import.State.ConvertingVideo:
txtConvert.text = qsTr("Converting Video... This can take some time!");
break;
case Import.State.ConvertingVideoError:
txtConvert.text = qsTr("Converting Video ERROR!");
break;
case Import.State.AnalyseVideoError:
txtConvert.text = qsTr("Analyse Video ERROR!");
break;
case Import.State.Finished:
txtConvert.text = "";
conversionFinishedSuccessful = true;
busyIndicator.running = false;
btnExit.enabled = false;
root.checkCanSave();
break;
}
}
function onProgressChanged(progress) {
var percentage = Math.floor(progress * 100);
if (percentage > 100 || progress > 0.95)
percentage = 100;
if (percentage === NaN)
print(progress, percentage);
txtConvertNumber.text = percentage + "%";
}
target: App.create
}
Util.Headline {
id: txtHeadline
text: qsTr("Import a video to a wallpaper")
anchors {
top: parent.top
left: parent.left
margins: 40
bottomMargin: 0
}
}
Item {
id: wrapperLeft
width: parent.width * 0.66
anchors {
left: parent.left
top: txtHeadline.bottom
margins: 30
bottom: parent.bottom
}
Rectangle {
id: imgWrapper
color: Material.color(Material.Grey)
anchors {
top: parent.top
right: parent.right
rightMargin: 20
bottom: previewSelector.top
bottomMargin: 20
left: parent.left
}
Image {
id: imgPreview
fillMode: Image.PreserveAspectCrop
asynchronous: true
visible: false
anchors.fill: parent
}
AnimatedImage {
id: gifPreview
fillMode: Image.PreserveAspectCrop
asynchronous: true
playing: true
visible: false
anchors.fill: parent
}
Rectangle {
id: shadow
anchors.fill: parent
gradient: Gradient {
GradientStop {
id: gradientStop0
position: 1
color: "#DD000000"
}
GradientStop {
id: gradientStop1
position: 0
color: "#00000000"
}
}
}
BusyIndicator {
id: busyIndicator
anchors.centerIn: parent
running: true
}
Text {
id: txtConvertNumber
color: "white"
font.pointSize: 21
font.family: App.settings.font
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 40
}
}
Text {
id: txtConvert
color: Material.secondaryTextColor
text: qsTr("Generating preview video...")
font.pointSize: 14
font.family: App.settings.font
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 20
}
}
}
Util.ImageSelector {
id: previewSelector
height: 80
anchors {
right: parent.right
rightMargin: 20
left: parent.left
bottom: parent.bottom
}
}
}
Item {
id: wrapperRight
width: parent.width * 0.33
anchors {
top: txtHeadline.bottom
topMargin: 30
bottom: parent.bottom
right: parent.right
}
ColumnLayout {
id: column
spacing: 0
anchors {
right: parent.right
left: parent.left
margins: 30
top: parent.top
topMargin: 0
bottom: column1.top
bottomMargin: 50
}
Util.TextField {
id: textFieldName
placeholderText: qsTr("Name (required!)")
width: parent.width
Layout.fillWidth: true
onTextChanged: {
if (textFieldName.text.length >= 3)
canSave = true;
else
canSave = false;
}
}
Util.TextField {
id: textFieldDescription
placeholderText: qsTr("Description")
width: parent.width
Layout.fillWidth: true
}
Util.TextField {
id: textFieldYoutubeURL
placeholderText: qsTr("Youtube URL")
width: parent.width
Layout.fillWidth: true
}
Util.TagSelector {
id: textFieldTags
width: parent.width
Layout.fillWidth: true
}
}
Row {
id: column1
height: 80
width: childrenRect.width
spacing: 10
anchors {
right: parent.right
rightMargin: 30
bottomMargin: -10
bottom: parent.bottom
}
Button {
id: btnExit
text: qsTr("Abort")
Material.accent: Material.color(Material.Red)
highlighted: true
font.family: App.settings.font
onClicked: {
root.exit();
App.create.cancel();
}
}
Button {
id: btnSave
objectName: "btnSave"
text: qsTr("Save")
enabled: false
Material.background: Material.accent
Material.foreground: "white"
font.family: App.settings.font
onClicked: {
if (conversionFinishedSuccessful) {
btnSave.enabled = false;
App.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, Util.Video.VideoCodec.VP9, textFieldTags.getTags());
savePopup.open();
}
}
}
}
}
Popup {
id: savePopup
modal: true
focus: true
width: 250
anchors.centerIn: parent
height: 200
onOpened: timerSave.start()
BusyIndicator {
anchors.centerIn: parent
running: true
}
Text {
text: qsTr("Save Wallpaper...")
color: Material.primaryTextColor
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 30
font.family: App.settings.font
}
Timer {
id: timerSave
interval: 1000 + Math.random() * 1000
onTriggered: {
savePopup.close();
App.util.setNavigationActive(true);
root.exit();
}
}
}
}

View File

@ -1,158 +0,0 @@
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
import QtQuick.Dialogs
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util
import "../../"
Item {
id: root
signal next(var filePath)
ColumnLayout {
id: wrapper
spacing: 40
anchors {
top: parent.top
bottom: btnOpenDocs.top
left: parent.left
right: parent.right
margins: 20
}
Util.Headline {
Layout.fillWidth: true
text: qsTr("Import a .webm video")
}
RowLayout {
Layout.fillHeight: true
Layout.fillWidth: true
spacing: 40
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 40
Text {
id: txtDescription
text: qsTr("When importing webm we can skip the long conversion. When you get unsatisfying results with the ScreenPlay importer from 'ideo import and convert (all types)' you can also convert via the free and open source HandBrake!")
color: Material.primaryTextColor
Layout.fillWidth: true
font.pointSize: 13
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.family: App.settings.font
}
DropArea {
id: dropArea
Layout.fillHeight: true
Layout.fillWidth: true
onExited: {
bg.color = Qt.darker(Material.backgroundColor);
}
onEntered: {
bg.color = Qt.darker(Qt.darker(Material.backgroundColor));
drag.accept(Qt.LinkAction);
}
onDropped: {
let file = App.util.toLocal(drop.urls[0]);
bg.color = Qt.darker(Qt.darker(Material.backgroundColor));
if (file.endsWith(".webm"))
root.next(drop.urls[0]);
else
txtFile.text = qsTr("Invalid file type. Must be valid VP8 or VP9 (*.webm)!");
}
Rectangle {
id: bg
anchors.fill: parent
radius: 3
color: Qt.darker(Material.backgroundColor)
}
Image {
id: bgPattern
anchors.fill: parent
fillMode: Image.Tile
opacity: 0.2
source: "qrc:/qml/ScreenPlayApp/assets/images/noisy-texture-3.png"
}
Text {
id: txtFile
text: qsTr("Drop a *.webm file here or use 'Select file' below.")
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
color: Material.primaryTextColor
font.pointSize: 13
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
font.family: App.settings.font
anchors {
fill: parent
margins: 40
}
}
}
}
}
}
Button {
id: btnOpenDocs
text: qsTr("Open Documentation")
Material.accent: Material.color(Material.LightGreen)
highlighted: true
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_document.svg"
icon.color: "white"
icon.width: 16
icon.height: 16
font.family: App.settings.font
onClicked: Qt.openUrlExternally("https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
anchors {
bottom: parent.bottom
left: parent.left
margins: 20
}
}
Button {
text: qsTr("Select file")
highlighted: true
font.family: App.settings.font
onClicked: {
fileDialogImportVideo.open();
}
FileDialog {
id: fileDialogImportVideo
nameFilters: ["Video files (*.webm)"]
onAccepted: {
root.next(fileDialogImportVideo.currentFile);
}
}
anchors {
right: parent.right
bottom: parent.bottom
margins: 20
}
}
}

View File

@ -1,39 +0,0 @@
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
import ScreenPlayApp
import ScreenPlay
Item {
id: root
signal wizardStarted
signal wizardExited
signal next
SwipeView {
id: swipeView
anchors.fill: parent
interactive: false
clip: true
Importh264Init {
onNext: function (filePath) {
root.wizardStarted();
swipeView.currentIndex = 1;
createWallpaperVideoImportConvert.filePath = filePath;
App.util.setNavigationActive(false);
App.create.importH264(filePath);
}
}
Importh264Convert {
id: createWallpaperVideoImportConvert
onExit: root.wizardExited()
}
}
}

View File

@ -1,374 +0,0 @@
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util
Item {
id: root
property bool conversionFinishedSuccessful: false
property bool canSave: false
property string filePath
signal exit
signal save
function basename(str) {
let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1));
let filename = filenameWithExtentions.split('.').slice(0, -1).join('.');
return filename;
}
function checkCanSave() {
if (canSave && conversionFinishedSuccessful)
btnSave.enabled = true;
else
btnSave.enabled = false;
}
onCanSaveChanged: root.checkCanSave()
onFilePathChanged: {
textFieldName.text = basename(filePath);
}
Connections {
function onCreateWallpaperStateChanged(state) {
switch (state) {
case Import.State.AnalyseVideo:
txtConvert.text = qsTr("AnalyseVideo...");
break;
case Import.State.ConvertingPreviewImage:
txtConvert.text = qsTr("Generating preview image...");
break;
case Import.State.ConvertingPreviewThumbnailImage:
txtConvert.text = qsTr("Generating preview thumbnail image...");
break;
case Import.State.ConvertingPreviewImageFinished:
imgPreview.source = "file:///" + App.create.workingDir + "/preview.jpg";
imgPreview.visible = true;
break;
case Import.State.ConvertingPreviewVideo:
txtConvert.text = qsTr("Generating 5 second preview video...");
break;
case Import.State.ConvertingPreviewGif:
txtConvert.text = qsTr("Generating preview gif...");
break;
case Import.State.ConvertingPreviewGifFinished:
gifPreview.source = "file:///" + App.create.workingDir + "/preview.gif";
imgPreview.visible = false;
gifPreview.visible = true;
gifPreview.playing = true;
break;
case Import.State.ConvertingAudio:
txtConvert.text = qsTr("Converting Audio...");
break;
case Import.State.ConvertingVideo:
txtConvert.text = qsTr("Converting Video... This can take some time!");
break;
case Import.State.ConvertingVideoError:
txtConvert.text = qsTr("Converting Video ERROR!");
break;
case Import.State.AnalyseVideoError:
txtConvert.text = qsTr("Analyse Video ERROR!");
break;
case Import.State.Finished:
txtConvert.text = "";
conversionFinishedSuccessful = true;
busyIndicator.running = false;
btnExit.enabled = false;
root.checkCanSave();
break;
}
}
function onProgressChanged(progress) {
var percentage = Math.floor(progress * 100);
if (percentage > 100 || progress > 0.95)
percentage = 100;
if (percentage === NaN)
print(progress, percentage);
txtConvertNumber.text = percentage + "%";
}
target: App.create
}
Util.Headline {
id: txtHeadline
text: qsTr("Import a video to a wallpaper")
anchors {
top: parent.top
left: parent.left
margins: 40
bottomMargin: 0
}
}
Item {
id: wrapperLeft
width: parent.width * 0.66
anchors {
left: parent.left
top: txtHeadline.bottom
margins: 30
bottom: parent.bottom
}
Rectangle {
id: imgWrapper
color: Material.color(Material.Grey)
anchors {
top: parent.top
right: parent.right
rightMargin: 20
bottom: previewSelector.top
bottomMargin: 20
left: parent.left
}
Image {
id: imgPreview
fillMode: Image.PreserveAspectCrop
asynchronous: true
visible: false
anchors.fill: parent
}
AnimatedImage {
id: gifPreview
fillMode: Image.PreserveAspectCrop
asynchronous: true
playing: true
visible: false
anchors.fill: parent
}
Rectangle {
id: shadow
anchors.fill: parent
gradient: Gradient {
GradientStop {
id: gradientStop0
position: 1
color: "#DD000000"
}
GradientStop {
id: gradientStop1
position: 0
color: "#00000000"
}
}
}
BusyIndicator {
id: busyIndicator
anchors.centerIn: parent
running: true
}
Text {
id: txtConvertNumber
color: "white"
font.pointSize: 21
font.family: App.settings.font
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 40
}
}
Text {
id: txtConvert
color: Material.secondaryTextColor
text: qsTr("Generating preview video...")
font.pointSize: 14
font.family: App.settings.font
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 20
}
}
}
Util.ImageSelector {
id: previewSelector
height: 80
anchors {
right: parent.right
rightMargin: 20
left: parent.left
bottom: parent.bottom
}
}
}
Item {
id: wrapperRight
width: parent.width * 0.33
anchors {
top: txtHeadline.bottom
topMargin: 30
bottom: parent.bottom
right: parent.right
}
ColumnLayout {
id: column
spacing: 0
anchors {
right: parent.right
left: parent.left
margins: 30
top: parent.top
topMargin: 0
bottom: column1.top
bottomMargin: 50
}
Util.TextField {
id: textFieldName
placeholderText: qsTr("Name (required!)")
width: parent.width
Layout.fillWidth: true
onTextChanged: {
if (textFieldName.text.length >= 3)
canSave = true;
else
canSave = false;
}
}
Util.TextField {
id: textFieldDescription
placeholderText: qsTr("Description")
width: parent.width
Layout.fillWidth: true
}
Util.TextField {
id: textFieldYoutubeURL
placeholderText: qsTr("Youtube URL")
width: parent.width
Layout.fillWidth: true
}
Util.TagSelector {
id: textFieldTags
width: parent.width
Layout.fillWidth: true
}
}
Row {
id: column1
height: 80
width: childrenRect.width
spacing: 10
anchors {
right: parent.right
rightMargin: 30
bottomMargin: -10
bottom: parent.bottom
}
Button {
id: btnExit
text: qsTr("Abort")
Material.background: Material.Red
Material.foreground: "white"
font.family: App.settings.font
onClicked: {
root.exit();
App.create.cancel();
}
}
Button {
id: btnSave
objectName: "btnSave"
text: qsTr("Save")
enabled: false
Material.background: Material.accent
Material.foreground: "white"
font.family: App.settings.font
onClicked: {
if (conversionFinishedSuccessful) {
btnSave.enabled = false;
App.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, Create.H264, textFieldTags.getTags());
savePopup.open();
}
}
}
}
}
Popup {
id: savePopup
modal: true
focus: true
width: 250
anchors.centerIn: parent
height: 200
onOpened: timerSave.start()
BusyIndicator {
anchors.centerIn: parent
running: true
}
Text {
text: qsTr("Save Wallpaper...")
color: Material.primaryTextColor
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 30
font.family: App.settings.font
}
Timer {
id: timerSave
interval: 1000 + Math.random() * 1000
onTriggered: {
savePopup.close();
App.util.setNavigationActive(true);
root.exit();
}
}
}
}

View File

@ -340,9 +340,15 @@ Item {
}
}
}
MessageDialog {
id: errorDialog
buttons: MessageDialog.Ok
Dialog {
id: dialog
standardButtons: Dialog.Ok
title: qsTr("Export Godot project")
property alias message: messageText.text
Text {
id: messageText
}
}
Button {
@ -375,21 +381,22 @@ Item {
absoluteStoragePath,
App.globalVariables.godotEditorExecutablePath).then(
result => {
if(!result.success){
errorDialog.text = ("Error exporting Godot")
errorDialog.informativeText = result.messag
errorDialog.open()
return
if (!result.success) {
dialog.title = ("Error exporting Godot")
dialog.message = result.message
dialog.open()
} else {
const screenFile = item.m_file
let success = App.screenPlayManager.createWallpaper(
root.type,
cbVideoFillMode.currentValue,
absoluteStoragePath,
previewImage, screenFile,
activeMonitors, volume,
1, {}, true)
}
const screenFile = item.m_file
let success = App.screenPlayManager.createWallpaper(
root.type,
cbVideoFillMode.currentValue,
absoluteStoragePath,
previewImage, screenFile,
activeMonitors, volume,
1, {}, true)
})
root.state = "inactive"
return
}

View File

@ -2,6 +2,7 @@
#include "ScreenPlay/create.h"
#include "ScreenPlayUtil/util.h"
#include "qguiapplication.h"
namespace ScreenPlay {
@ -43,7 +44,7 @@ void Create::reset()
/*!
\brief Starts the process.
*/
void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, const int quality)
void Create::createWallpaperStart(QString videoPath, ScreenPlay::Video::VideoCodec target_codec, const int quality)
{
reset();
ScreenPlay::Util util;
@ -63,19 +64,6 @@ void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, c
return;
}
QString target_codec;
switch (codec) {
case Create::VideoCodec::VP8:
target_codec = "vp8";
break;
case Create::VideoCodec::VP9:
target_codec = "vp9";
break;
case Create::VideoCodec::AV1:
target_codec = "av1";
break;
}
m_createImportFuture = QtConcurrent::run(QThreadPool::globalInstance(), [videoPath, target_codec, quality, this]() {
CreateImportVideo import(videoPath, workingDir(), target_codec, quality, m_interrupt);
QObject::connect(&import, &CreateImportVideo::createWallpaperStateChanged, this, &Create::createWallpaperStateChanged, Qt::ConnectionType::QueuedConnection);
@ -134,13 +122,7 @@ void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, c
}
}
// Skip convert for webm
if (import.m_isWebm) {
emit createWallpaperStateChanged(Import::State::Finished);
return;
}
qInfo() << "createWallpaperVideo()";
qInfo() << "createWallpaperVideo";
if (!import.createWallpaperVideo() || m_interrupt) {
emit createWallpaperStateChanged(Import::State::Failed);
emit import.abortAndCleanup();
@ -157,91 +139,6 @@ void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, c
m_createImportFutureWatcher.setFuture(m_createImportFuture);
}
void Create::importH264(QString videoPath)
{
reset();
ScreenPlay::Util util;
videoPath = util.toLocal(videoPath);
const QDir installedDir = util.toLocal(m_globalVariables->localStoragePath().toString());
// Create a temp dir so we can later alter it to the workshop id
const QDateTime date = QDateTime::currentDateTime();
const auto folderName = date.toString("ddMMyyyyhhmmss");
setWorkingDir(installedDir.path() + "/" + folderName);
if (!installedDir.mkdir(folderName)) {
qInfo() << "Unable to create folder with name: " << folderName << " at: " << installedDir;
emit createWallpaperStateChanged(Import::State::CreateTmpFolderError);
emit abortCreateWallpaper();
return;
}
m_createImportFuture = QtConcurrent::run(QThreadPool::globalInstance(), [videoPath, this]() {
CreateImportVideo import(videoPath, workingDir(), m_interrupt);
QObject::connect(&import, &CreateImportVideo::createWallpaperStateChanged, this, &Create::createWallpaperStateChanged, Qt::ConnectionType::QueuedConnection);
QObject::connect(&import, &CreateImportVideo::abortAndCleanup, this, &Create::abortAndCleanup, Qt::ConnectionType::QueuedConnection);
QObject::connect(
&import, &CreateImportVideo::processOutput, this, [this](const QString text) {
appendFfmpegOutput(text + "\n");
},
Qt::ConnectionType::QueuedConnection);
if (!import.createWallpaperInfo() || m_interrupt) {
emit createWallpaperStateChanged(Import::State::Failed);
emit import.abortAndCleanup();
return;
}
qInfo() << "createWallpaperImageThumbnailPreview()";
if (!import.createWallpaperImageThumbnailPreview() || m_interrupt) {
emit createWallpaperStateChanged(Import::State::Failed);
emit import.abortAndCleanup();
return;
}
qInfo() << "createWallpaperImagePreview()";
if (!import.createWallpaperImagePreview() || m_interrupt) {
emit createWallpaperStateChanged(Import::State::Failed);
emit import.abortAndCleanup();
return;
}
// Skip preview convert for webm
if (!import.createWallpaperVideoPreview() || m_interrupt) {
emit createWallpaperStateChanged(Import::State::Failed);
emit import.abortAndCleanup();
return;
}
qInfo() << "createWallpaperGifPreview()";
if (!import.createWallpaperGifPreview() || m_interrupt) {
emit createWallpaperStateChanged(Import::State::Failed);
emit import.abortAndCleanup();
return;
}
// If the video has no audio we can skip the extraction
if (!import.m_skipAudio) {
qInfo() << "extractWallpaperAudio()";
if (!import.extractWallpaperAudio() || m_interrupt) {
emit createWallpaperStateChanged(Import::State::Failed);
emit import.abortAndCleanup();
return;
}
}
emit createWallpaperStateChanged(Import::State::Finished);
return;
});
QObject::connect(&m_createImportFutureWatcher, &QFutureWatcherBase::finished, this, [this]() {
if (m_interrupt)
abortAndCleanup();
});
m_createImportFutureWatcher.setFuture(m_createImportFuture);
}
/*!
\brief When converting of the wallpaper steps where successful.
@ -252,7 +149,7 @@ void Create::saveWallpaper(
QString filePath,
QString previewImagePath,
const QString youtube,
const Create::VideoCodec codec,
const ScreenPlay::Video::VideoCodec codec,
const QVector<QString> tags)
{
ScreenPlay::Util util;
@ -282,13 +179,13 @@ void Create::saveWallpaper(
}
QFileInfo filePathFile(filePath);
if (filePath.endsWith(".webm") || filePath.endsWith(".mp4")) {
if (!QFile::copy(filePath, m_workingDir + "/" + filePathFile.fileName())) {
qDebug() << "Could not copy" << filePath << " to " << m_workingDir + "/" + filePathFile.fileName();
emit createWallpaperStateChanged(Import::State::CopyFilesError);
return;
}
}
// if (filePath.endsWith(".webm") || filePath.endsWith(".mp4")) {
// if (!QFile::copy(filePath, m_workingDir + "/" + filePathFile.fileName())) {
// qDebug() << "Could not copy" << filePath << " to " << m_workingDir + "/" + filePathFile.fileName();
// emit createWallpaperStateChanged(Import::State::CopyFilesError);
// return;
// }
// }
emit createWallpaperStateChanged(Import::State::CopyFilesFinished);
emit createWallpaperStateChanged(Import::State::CreateProjectFile);
@ -296,8 +193,17 @@ void Create::saveWallpaper(
obj.insert("description", description);
obj.insert("title", title);
obj.insert("youtube", youtube);
obj.insert("videoCodec", QVariant::fromValue<VideoCodec>(codec).toString());
obj.insert("file", filePathFile.completeBaseName() + (codec == VideoCodec::H264 ? ".mp4" : ".webm"));
obj.insert("videoCodec", QVariant::fromValue<Video::VideoCodec>(codec).toString());
QString fileEnding;
if (codec == Video::VideoCodec::H264)
fileEnding = ".mp4";
if (codec == Video::VideoCodec::AV1)
fileEnding = ".mkv";
if (codec == Video::VideoCodec::VP8 || codec == Video::VideoCodec::VP9)
fileEnding = ".webm";
obj.insert("file", filePathFile.completeBaseName() + fileEnding);
obj.insert("previewGIF", "preview.gif");
obj.insert("previewWEBM", "preview.webm");
obj.insert("preview", previewImageFile.exists() ? previewImageFile.fileName() : "preview.jpg");

View File

@ -24,7 +24,7 @@ namespace ScreenPlay {
CreateImportVideo::CreateImportVideo(
const QString& videoPath,
const QString& exportPath,
const QString& codec,
const ScreenPlay::Video::VideoCodec targetCodec,
const int quality,
std::atomic<bool>& interrupt)
: QObject(nullptr)
@ -33,17 +33,7 @@ CreateImportVideo::CreateImportVideo(
{
m_videoPath = videoPath;
m_exportPath = exportPath;
m_codec = codec;
setupFFMPEG();
}
CreateImportVideo::CreateImportVideo(const QString& videoPath, const QString& exportPath, std::atomic<bool>& interrupt)
: QObject(nullptr)
, m_quality(0)
, m_interrupt(interrupt)
{
m_videoPath = videoPath;
m_exportPath = exportPath;
m_targetCodec = targetCodec;
setupFFMPEG();
}
@ -86,10 +76,6 @@ void CreateImportVideo::setupFFMPEG()
*/
bool CreateImportVideo::createWallpaperInfo()
{
if (m_videoPath.endsWith(".webm") || m_videoPath.endsWith(".mkv")) {
m_isWebm = true;
}
// Get video info
QStringList args;
args.append("-print_format");
@ -138,12 +124,7 @@ bool CreateImportVideo::createWallpaperInfo()
emit createWallpaperStateChanged(Import::State::AnalyseVideoError);
return false;
}
if (m_isWebm) {
return analyzeWebmReadFrames(obj.value());
} else {
return analyzeVideo(obj.value());
}
return analyzeVideo(obj.value());
}
/*!
@ -165,6 +146,15 @@ bool CreateImportVideo::analyzeWebmReadFrames(const QJsonObject& obj)
const QJsonObject firstStream = streams.first().toObject();
qInfo() << "streams:" << streams;
for (const auto& stream : streams) {
QString codec_type = stream.toObject().value("codec_type").toString();
if (codec_type == "audio") {
m_skipAudio = false;
} else {
m_skipAudio = true;
}
}
bool okParseNumberOfFrames { false };
int numberOfFrames = firstStream.value("nb_read_frames").toString().toInt(&okParseNumberOfFrames);
if (!okParseNumberOfFrames) {
@ -202,6 +192,37 @@ bool CreateImportVideo::analyzeVideo(const QJsonObject& obj)
{
// Check for audio and video streams
const QJsonArray arrayStream = obj.value("streams").toArray();
// Get framerate
const QJsonArray streams = obj.value("streams").toArray();
if (streams.empty()) {
qDebug() << "Error container does not have any video streams";
emit processOutput("Error container does not have any video streams");
return false;
}
const QJsonObject firstStream = streams.first().toObject();
const QString codecName = firstStream.value("codec_name").toVariant().toString();
// It is not that important to check for all codecs,
// we just need a check for the important once to skip
// import convertion if it is the same codec.
if (codecName == "vp8") {
m_sourceCodec = Video::VideoCodec::VP8;
} else if (codecName == "vp9") {
m_sourceCodec = Video::VideoCodec::VP9;
} else if (codecName == "av1") {
m_sourceCodec = Video::VideoCodec::AV1;
} else if (codecName == "h264") {
m_sourceCodec = Video::VideoCodec::H264;
} else if (codecName == "hevc") {
m_sourceCodec = Video::VideoCodec::H265; // HEVC is H.265
} else {
m_sourceCodec = Video::VideoCodec::Unknown;
}
if (m_sourceCodec == Video::VideoCodec::VP8 || m_sourceCodec == Video::VideoCodec::VP9) {
return analyzeWebmReadFrames(obj);
}
bool hasAudioStream { false };
bool hasVideoStream { false };
@ -257,16 +278,6 @@ bool CreateImportVideo::analyzeVideo(const QJsonObject& obj)
m_length = static_cast<int>(tmpLength);
// Get framerate
const QJsonArray streams = obj.value("streams").toArray();
if (streams.empty()) {
qDebug() << "Error container does not have any video streams";
emit processOutput("Error container does not have any video streams");
return false;
}
const QJsonObject firstStream = streams.first().toObject();
// The paramter gets us the exact framerate
// "avg_frame_rate":"47850000/797509"
// so we need no calc the value by dividing the two numbers
@ -519,6 +530,18 @@ bool CreateImportVideo::createWallpaperImagePreview()
*/
bool CreateImportVideo::createWallpaperVideo()
{
const QFileInfo sourceFile(m_videoPath);
if (m_sourceCodec == m_targetCodec) {
qInfo() << "Skip video convert because they are the same";
if (!QFile::copy(sourceFile.absoluteFilePath(), m_exportPath + "/" + sourceFile.fileName())) {
qDebug() << "Could not copy" << sourceFile.absoluteFilePath() << " to " << m_exportPath;
return false;
}
emit createWallpaperStateChanged(Import::State::Finished);
return true;
}
emit createWallpaperStateChanged(Import::State::ConvertingVideo);
connect(m_process.get(), &QProcess::readyReadStandardOutput, this, [&]() {
@ -543,6 +566,26 @@ bool CreateImportVideo::createWallpaperVideo()
emit processOutput(tmpOut);
});
QString targetCodec;
QString targetFileEnding;
if (m_targetCodec == Video::VideoCodec::VP8)
targetCodec = "libvpx";
targetFileEnding = ".webm";
if (m_targetCodec == Video::VideoCodec::VP8)
targetCodec = "libvpx";
targetFileEnding = ".webm";
if (m_targetCodec == Video::VideoCodec::AV1)
targetCodec = "libaom-av1";
targetFileEnding = ".mkv";
if (m_targetCodec == Video::VideoCodec::H264) {
targetFileEnding = ".mp4";
if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows) {
targetCodec = "h264_mf";
} else {
targetCodec = "libx264";
}
}
QStringList args;
args.append("-hide_banner");
args.append("-y");
@ -550,12 +593,7 @@ bool CreateImportVideo::createWallpaperVideo()
args.append("-i");
args.append(m_videoPath);
args.append("-c:v");
if (m_codec == "vp8")
args.append("libvpx");
if (m_codec == "vp9")
args.append("libvpx-vp9");
if (m_codec == "av1")
args.append("libaom-av1");
args.append(targetCodec);
args.append("-b:v");
args.append("13000k");
args.append("-threads");
@ -593,12 +631,7 @@ bool CreateImportVideo::createWallpaperVideo()
args.append("-i");
args.append(m_videoPath);
args.append("-c:v");
if (m_codec == "vp8")
args.append("libvpx");
if (m_codec == "vp9")
args.append("libvpx-vp9");
if (m_codec == "av1")
args.append("libaom-av1");
args.append(targetCodec);
args.append("-b:v");
args.append("13000k");
args.append("-threads");
@ -617,8 +650,7 @@ bool CreateImportVideo::createWallpaperVideo()
args.append(QString::number(m_quality));
args.append("-pass");
args.append("2");
const QFileInfo file(m_videoPath);
const QString convertedFileAbsolutePath { m_exportPath + "/" + file.completeBaseName() + ".webm" };
const QString convertedFileAbsolutePath { m_exportPath + "/" + sourceFile.completeBaseName() + targetFileEnding };
args.append(convertedFileAbsolutePath);
const QString ffmpegOutput = waitForFinished(args);
@ -696,7 +728,7 @@ QString CreateImportVideo::waitForFinished(
{
m_process = std::make_unique<QProcess>();
QObject::connect(m_process.get(), &QProcess::errorOccurred, [=, this](QProcess::ProcessError error) {
QObject::connect(m_process.get(), &QProcess::errorOccurred, this, [=, this](QProcess::ProcessError error) {
qDebug() << "error enum val = " << error << m_process->errorString();
emit createWallpaperStateChanged(Import::State::AnalyseVideoError);
m_process->terminate();

View File

@ -5,9 +5,6 @@
#include <QQmlEngine>
#include <QtCore/qmetatype.h>
// We must package everything into a class for
// qml to be able to have typed enums. Making
// qml enums unscoped as default was a mistake.
namespace ScreenPlay {
class ContentTypes : public QObject {

View File

@ -12,7 +12,7 @@ Item {
property string iconSource: "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume.svg"
property alias slider: slider
height: 70
height: 80
Text {
id: txtHeadline
@ -40,7 +40,7 @@ Item {
left: parent.left
}
Image {
ColorImage {
id: imgIcon
width: 20