2

是否有捷径可寻?我从来没有在任何地方看到过这个(除了 Adob​​e/... Firefox 插件),所以我怀疑它...

如果没有,是否有可靠的、hacky 的方式(例如通过 连接到该进程的Xlib调用LD_PRELOAD)?

如果重要的话,假设外部进程是mplayer,我的编程语言是C。我有一种预感,Xlib直接使用是我最好的选择,但请随时提出其他选择。-onlymplayer解决方案是不够的。

4

1 回答 1

3

如果您知道要嵌入的窗口的窗口 ID,即使它是由另一个进程创建的,您也可以将其重新设置为您的窗口(使用XReparentWindow )。

对于 mplayer,有“-wid”命令行选项。如果您将窗口 id 传递给它,mplayer 会自动将它的窗口创建为 wid 的子窗口:

-wid(另见 -gui-wid)(仅限 X11、OpenGL 和 DirectX)

这告诉 MPlayer 附加到现有窗口。用于在浏览器中嵌入 MPlayer(例如插件扩展)。此选项完全填充给定窗口,因此 MPlayer 不再处理纵横比缩放、平移扫描等,但必须由创建窗口的应用程序管理。

您可以通过传递'-slave'标志并将命令发送到stdin(或fifo)来控制mplayer

使用node-x11嵌入 mplayer 的示例:

var x11 = require('x11');
var spawn = require('child_process').spawn;
x11.createClient(function(err, display) {
    var X = display.client;
    var wid = X.AllocID();
    X.CreateWindow(wid, display.screen[0].root, 100, 100, 400, 300, 0, 0, 0, 0, {eventMask: x11.eventMask.SubstructureNotify|x11.eventMask.StructureNotify});
    X.MapWindow(wid);
    var mplayer = spawn('mplayer', ['-wid', wid, './video.mp4']);

    function pause() {
      mplayer.stdin.write('pause\n');
      setTimeout(play, 1000);
    }

    function play() {
      mplayer.stdin.write('play\n');
      setTimeout(pause, 1000);
    }

    pause();

   
    var mpid;
    X.on('event', function(ev) {
        console.log(ev);
        if (ev.name == 'CreateNotify')
            mpid = ev.wid;
        if (ev.name == 'ConfigureNotify' && ev.wid == wid) {
            X.ResizeWindow(mpid, ev.width, ev.height);
        }

    });
});
于 2014-10-13T23:11:42.683 回答