Render the ice as long videos and play them as wallpapers
render_wallpaper.py drives headless Firefox frame by frame (four at a time, resuming where it stopped), then ffmpeg. Thirty seconds at 30 fps is exactly one plasma cycle, so frame 900 meets frame 0 and the loop has no seam. plasma-plugin/dev.emil.video is a minimal Plasma 6 video wallpaper: one file per screen, filling the screen, looping. H.264 is encoded Baseline because Qt here decodes through openh264, which rejects High profile and leaves a frozen frame; a new source also has to be played explicitly. The #shot hash learned info=0 to hide the on-screen hint for renders.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import QtQuick
|
||||
import QtMultimedia
|
||||
import org.kde.plasma.plasmoid
|
||||
|
||||
// Plays one video file, filling the screen and looping for ever. Plasma keeps a
|
||||
// separate configuration per screen, so every monitor gets its own video.
|
||||
WallpaperItem {
|
||||
id: root
|
||||
|
||||
readonly property var activeConfiguration: {
|
||||
if (typeof wallpaper !== "undefined" && wallpaper && wallpaper.configuration)
|
||||
return wallpaper.configuration
|
||||
return typeof configuration !== "undefined" ? configuration : null
|
||||
}
|
||||
|
||||
function option(name, fallback) {
|
||||
if (!activeConfiguration)
|
||||
return fallback
|
||||
const value = activeConfiguration[name]
|
||||
return value === undefined ? fallback : value
|
||||
}
|
||||
|
||||
readonly property string videoPath: String(option("videoPath", ""))
|
||||
// shortcut: keeps decoding behind fullscreen windows too, add window tracking
|
||||
// (as the shader wallpaper plugin does) if the cost ever shows up in a game
|
||||
readonly property bool shouldPlay: videoPath.length > 0 && root.visible
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#03111d"
|
||||
}
|
||||
|
||||
VideoOutput {
|
||||
id: output
|
||||
anchors.fill: parent
|
||||
fillMode: VideoOutput.PreserveAspectCrop
|
||||
}
|
||||
|
||||
MediaPlayer {
|
||||
id: player
|
||||
videoOutput: output
|
||||
source: root.videoPath.length > 0 ? "file://" + root.videoPath : ""
|
||||
loops: MediaPlayer.Infinite
|
||||
playbackRate: Number(root.option("playbackRate", 1.0))
|
||||
|
||||
// Some containers do not restart on their own when they run out of frames.
|
||||
onMediaStatusChanged: {
|
||||
if (mediaStatus === MediaPlayer.EndOfMedia) {
|
||||
position = 0
|
||||
play()
|
||||
}
|
||||
}
|
||||
|
||||
onErrorOccurred: console.warn("video wallpaper:", error, errorString)
|
||||
}
|
||||
|
||||
Component.onCompleted: player.play()
|
||||
}
|
||||
Reference in New Issue
Block a user