node版本

λ node -v
v12.16.2

main.js

const ffi = require("@saleae/ffi");
const child_process = require("child_process");
const W32 = require("./w32"); const argv = process.argv.slice(2); if (!argv || !argv.length) process.exit(1); const play = child_process.fork("./play.js"); // ffplay -noborder -loop 0 -fs -vf scale=w=1920:h=-1 "${argv[0]}"
// -noborder 无边框
// -loop 0 循环次数,0无限循环
// -vf scale=w=1920:h=-1 使用scale滤镜, See also: https://trac.ffmpeg.org/wiki/Scaling
// ffplay -noborder -x 1920 -y 1080 无边框,强制设置宽高
play.send(`ffplay -noborder -x 1920 -y 1080 -loop 0 "${argv[0]}" `);
play.on("message", playCallback); function playCallback() {
let ffplayw = 0; // ffplay句柄
let t;
t = setInterval(() => {
ffplayw = getFFplayHandle();
if (ffplayw !== 0) {
clearInterval(t);
setDynamicWallpaper(ffplayw);
}
}, 1000);
} function setDynamicWallpaper(ffplayw) {
const progman = W32.FindWindowW(TEXT("Progman"), null); // 要触发在桌面图标和墙纸之间创建WorkerW窗口,我们必须向程序管理器发送一条消息。
// 该消息是未记录的消息,因此没有专用的Windows API名称,除了0x052C
W32.SendMessageTimeoutW(
progman,
0x052c, // 在程序管理器上生成墙纸工作程序的未记录消息
0,
0,
0x0000,
1000,
0
); // 我们枚举所有Windows
W32.EnumWindows(
ffi.Callback("bool", ["int32", "int32"], (tophandle, topparamhandle) => {
// 找到一个具有SHELLDLL_DefView的Windows
const SHELLDLL_DefView = W32.FindWindowExW(
tophandle,
0,
TEXT("SHELLDLL_DefView"),
0
);
if (SHELLDLL_DefView !== 0) {
// 将其下一个同级分配给workerw。
const workerw = W32.FindWindowExW(0, tophandle, TEXT("WorkerW"), 0);
W32.SetParent(ffplayw, workerw);
}
return true;
}),
0
);
}
function TEXT(text) {
return Buffer.from(`${text}\0`, "ucs2");
} // 获取ffplay句柄
function getFFplayHandle() {
return W32.FindWindowW(TEXT("SDL_app"), null);
}

play.js

const child_process = require("child_process");

process.on("message", (runFFplayCommand) => {
process.send(true);
child_process.execSync(runFFplayCommand);
});

w32.js

const ffi = require("@saleae/ffi");

// Import user32
const W32 = new ffi.Library("user32", {
// 检索顶级窗口的句柄,该顶级窗口的类名和窗口名与指定的字符串匹配。此功能不搜索子窗口。此功能不执行区分大小写的搜索。
FindWindowW: ["int32", ["string", "string"]], // 将指定的消息发送到一个或多个窗口
SendMessageTimeoutW: [
"int32",
["int32", "int32", "int32", "int32", "int32", "int32", "int32"],
], // 通过将句柄传递给每个窗口,依次传递到应用程序定义的回调函数,可以枚举屏幕上所有的顶级窗口
EnumWindows: ["bool", ["pointer", "int32"]], // 检索其类名和窗口名与指定字符串匹配的窗口的句柄。该功能搜索子窗口,从指定子窗口之后的子窗口开始。此功能不执行区分大小写的搜索。
FindWindowExW: ["int32", ["int32", "int32", "string", "int32"]], // 更改指定子窗口的父窗口。
// HWND SetParent(HWND hWndChild, HWND hWndNewParent);
SetParent: ["int32", ["int32", "int32"]], // int MessageBox(
// HWND hWnd, 要创建的消息框的所有者窗口的句柄。如果此参数为NULL,则消息框没有所有者窗口
// LPCTSTR lpText, 要显示的消息
// LPCTSTR lpCaption, 对话框标题
// UINT uType 对话框的内容和行为
// );
MessageBoxW: ["int32", ["int32", "string", "string", "int32"]], // 最小化(但不破坏)指定的窗口。
CloseWindow: ["bool", ["int32"]], // 销毁指定的窗口
DestroyWindow: ["bool", ["int32"]], // 打开指定的桌面对象
OpenDesktopW: ["int32", ["string", "int32", "bool", "int32"]], // 确定指定窗口的可见性状态。
IsWindowVisible: ["bool", ["int32"]], // 设置指定窗口的显示状态。
ShowWindow: ["bool", ["int32", "int32"]],
}); module.exports = W32;

运行

>node main.js "D:\dynamic wallpaper\Nightcore-We-Wish-You-A-Merry-Christmas-Live-Wallpaper.mp4"

运行前的窗口:

运行后的窗口:

将视频放在Progman下面

现在测试来看,这种方法要好些,关闭进程后不会显示残留壁纸

function setDynamicWallpaper(ffplayw) {
const progman = W32.FindWindowW(TEXT("Progman"), null); // 要触发在桌面图标和墙纸之间创建WorkerW窗口,我们必须向程序管理器发送一条消息。
// 该消息是未记录的消息,因此没有专用的Windows API名称,除了0x052C
W32.SendMessageTimeoutW(
progman,
0x052c, // 在程序管理器上生成墙纸工作程序的未记录消息
0,
0,
0x0000,
1000,
0
); // 我们枚举所有Windows
W32.EnumWindows(
ffi.Callback("bool", ["int32", "int32"], (tophandle, topparamhandle) => {
// 找到一个具有SHELLDLL_DefView的Windows
const SHELLDLL_DefView = W32.FindWindowExW(
tophandle,
0,
TEXT("SHELLDLL_DefView"),
0
);
if (SHELLDLL_DefView !== 0) {
// 将其下一个同级分配给workerw。
const workerw = W32.FindWindowExW(0, tophandle, TEXT("WorkerW"), 0);
const isVisible = W32.IsWindowVisible(workerw);
if (isVisible) {
// 设置窗口为未激活状态,否则这个窗口会遮挡视频
W32.ShowWindow(workerw, 0);
}
W32.SetParent(ffplayw, progman);
}
return true;
}),
0
);
}

现在按下Ctrl+c指令后,node进程结束,ffplay关闭,壁纸将显示之前的壁纸

使用ffplay你可以解析本地视频,图片,http视频,直播流,ts视频段,m3u8,等等...

参考连接

nodejs 在windows10中设置动态(视频)壁纸的更多相关文章

  1. [UWP开发]在windows10中设置壁纸~UserProfilePersonalizationSettings

    在之前的wp8.1和wp8中,微软没有公开设置壁纸的API,只有一个设置锁屏的API,但在Windows10中,微软为我们提供了设置壁纸的API:TrySetWallpaperImageAsync,他 ...

  2. vue 在微信中设置动态标题

    1.安装插件 cnpm install vue-wechat-title --save 2.在main.js中引入 import VueWechatTitle from 'vue-wechat-tit ...

  3. laydate中设置动态改变max与min值的方法

    参考网址: 原网址:https://blog.csdn.net/cherry_11qianqian/article/details/82259704 改进的网址:https://blog.csdn.n ...

  4. 【nodeJS】webstorm中设置nodej智能提示

  5. 为你的Windows7设置动态壁纸

    From:http://www.cnblogs.com/killerlegend/p/3644014.html By KillerLegend DreamScene是Vista上的一个功能,可以让你设 ...

  6. nodejs爬虫如何设置动态ip以及userAgent

    nodejs爬虫如何设置动态ip以及userAgent 转https://blog.csdn.net/u014374031/article/details/78833765 前言 在写nodejs爬虫 ...

  7. Quartz在Spring中动态设置cronExpression (spring设置动态定时任务)

    什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定).      这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户 ...

  8. 为TextView设置两种状态,程序中可以动态切换

    经常会需要用文字的两种状态来表示当前系统的某两种状态.比如:         这里的第一个TextView和后两个TextView就表示了两种状态.我们可以在程序的动态的切换状态(而不是直接修改颜色) ...

  9. windows下nodejs express安装及入门网站,视频资料,开源项目介绍

    windows下nodejs express安装及入门网站,视频资料,开源项目介绍,pm2,supervisor,npm,Pomelo,Grunt安装使用注意事项等总结 第一步:下载安装文件下载地址: ...

随机推荐

  1. The OAuth 2.0 Authorization Framework OAuth2.0的核心角色code 扫码登录

    RFC 6749 - The OAuth 2.0 Authorization Framework https://tools.ietf.org/html/rfc6749 The OAuth 2.0 a ...

  2. MySql(一)表类型(存储引擎)

    MySql(一)表类型(存储引擎) 一.MYSQL存储引擎概述 二.存储引擎的特性对比 2.1 MyISAM 2.2 InnoDB 2.2.1 自动增长列 2.2.2 外键约束 2.2.3 存储方式 ...

  3. svn 启动项目报错,项目被lock

    问题描述 问题解决 (一)Eclipse SVN 插件处理 (二)SVN 客户端处理 (三)删除lock文件 问题描述 在使用开发工具开发项目时(如Eclipse),在做项目的中途,有时候Eclips ...

  4. DEDECMS:安装百度UEDITOR编辑器

    第一步:下载相对应编辑器的版本 首先,去百度搜索"百度ueditor编辑器",然后点击进入官网,找到下载页面.找到我们想要的编辑器的版本,看自己网站的编码是UTF-8还是GBK,下 ...

  5. NodeMCU获取并解析心知天气信息

    NodeMCU获取并解析心知天气信息 1 注册心知天气并获取私钥 打开心知天气网站,点击注册按钮 填写基本信息注册心知天气账号,登录注册所填写的邮箱点击链接进行账号激活,随后出现如下界面 点击登录按钮 ...

  6. Gym 101485 E Elementary Math 网络流 或者 二分图

    题意: 输入一个n,后面输入n行,每一行两个数a.b.你可以对a.b进行三种操作:+.-.* 你需要保证对每一行a.b选取一个操作得到一个结果 你要保证这n行每一个式子选取的操作之后得到的结果都不一样 ...

  7. 【noi 2.6_7624】山区建小学(DP)

    题意:在m个村庄建n个小学,求所有村到最近小学的距离总的最小值. 解法:由于题目是求"离最近的学校",而不是前一个学校,所以枚举学校的具体位置不方便,可转化成区间(学校居区间中间) ...

  8. Gym 102263 ArabellaCPC 2019 J - Thanos Power (DP,数学)

    题意:有一个整数\(n\),每次可以对加\(10^x\)或减\(10^x\),问最少操作多少次能得到\(n\). 题解:对于某一位上的数,我们可以从\(0\)加几次得到,或者从前一位减几次得到.所以对 ...

  9. 牛客算法周周练20 F.紫魔法师 (二分图染色)

    题意:给你一张图,对其染色,使得相连的点的颜色两两不同求,最少使用多少种颜色. 题解:首先,若\(n=1\),只需要一种.然后我们再去判断是否是二分图,对于二分图,两种颜色就够了,若不是二分图,也就是 ...

  10. 关于markdown的入门使用

    关于标题 方式一: 使用 = - 标示一,二级标题 = 表示一级标题 - 表示二级标题 示例: 我展示的是一级标题 ================= 我展示的是二级标题 -------------- ...