• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Tastatur Befehl von Shell an Browser Brave senden

Guten Abend,

OS: LMDE7
Anwendungen: <simplescreenrecord>, <at>, <xdotool>, <brave>(Version 1.88.122)

Ich möchte meinen Bildschirm aufnehmen, wenn Ich ein Video über meinen Browser schaue. Dazu verwende Ich <simplescreenrecord>, welches zeitgesteuert starten soll, sowie das Video in meinem Browser Brave per gesendetem Tasten-Befehl auch gestartet werden soll.

Leider kommt meine gesendete Taste nicht durch.

Aktuell habe Ich folgenden Befehl ausgearbeitet,

echo "DISPLAY=:0 simplescreenrecorder --start-recording --start-hidden && sleep 2 && xdotool key --window \$(xdotool search --class Brave | head -1) space" | at 11:32

<xdotool search --class Brave | head -1> soll sich die Anwendungs ID, was auch klappt und dann die Taste <space> übersenden. Und das Alles zu einer bestimmten Zeit.

Weiß Jemand wie Ich es besser machen kann?
Oder ist Brave da der falsche Browser für Sowas?

Danke und Grüße
 
Ich würde das erstmal ohne "at" probieren.
Ich kann oft z.B. grafische Programme nicht über "at" öffnen. Das liegt vermutlich daran, daß das unter einem anderen Benutzer ausgeführt wird, und der nicht die Rechte am Display hat.
Wie gesagt, erstmal ohne "at" probieren, und wenn das geht, sich auf die Probleme mit "at" konzentrieren.
 
Super, habe folgenden Befehl probiert xdotool search --onlyvisible --class "Brave" windowactivate --sync key --clearmodifiers space und anscheinend klappt es jetzt. :)
 
Sehr gut, freut mich!

Ich hatte auch noch etwas recherechiert. Wenn ich z.B. versuche, eine Taste an Google-Chrome zu senden, erhalte ich mehrere IDs. Du hattest die erste genommen, mit "| head 1", aber unter Umständen ist es nicht die erste.
Man bekommt zusätzlich noch den Namen des Fensters (Tabs), und wenn da z.B. "YouTube" drin ist, kann man direkt dahin senden, wobei ich für die Datenverarbeitung Perl einsetze. Ist dann 'n bißchen kompliziert, geht aber. Grober Entwurf war so (ich brauch' es ja nicht weiter auszuarbeiten, wenn es bei Dir schon läuft):
Code:
#!/usr/bin/perl

use warnings;
use strict;

my $searchstring = "hrome";
my $sendkey = "space";

sub sendKeyToWindow {
    my $windowid = shift;
    my $sendkey = shift;
    my @commands = ("xdotool windowactivate \"$windowid\"",
                    "xdotool windowfocus \"$windowid\"",
                    "xdotool key \"$sendkey\"");
    my $e;
    for $e (@commands) {
        print "$e\n";
        system($e);
    }
}

# my $e = "export DISPLAY=:0.0"; print "$e\n"; system($e);

my @a = `xdotool search --class "$searchstring"`;
my $i;
my $name;
for $i (@a) {
    chomp $i;
    $name = `xdotool getwindowname $i`;
    if ($name =~ /YouTube/) {
        sendKeyToWindow($i, "space");
    }
}
(Perl wüßte natürlich auch, wie spät es ist, so daß man auch "at" ersetzen könnte, wenn es kein Problem ist, das Perl-Skript die ganze Zeit laufen zu lassen, damit es die Zeit prüft.)
 
Danke, Ich will es möglichst einfach halten in BASH. Habe mir jetzt ein BASH Skript gebastelt.


Bash:
#!/bin/bash

# Funktion: HH:MM:SS in Sekunden umwandeln
to_seconds() {
    IFS=: read -r h m s <<< "$1"
    echo $((10#$h * 3600 + 10#$m * 60 + 10#$s))
}


simplescreenrecorder --start-recording --start-hidden &
SSR_PID=$!
sleep 2
xdotool search --onlyvisible --class "Brave" windowactivate --sync
sleep 1
xdotool key --clearmodifiers space


# Pause
sleep $(to_seconds "00:00:10")
echo "record-pause" | /proc/$SSR_PID/exe


# Save
sleep $(to_seconds "00:00:02")
echo "record-save" | /proc/$SSR_PID/exe

Es funktioniert fast. Also Ich bekomme die PAUSE/SAVE Befehle nicht an den interaktiven SSR. Er startet einfach eine neue Instanz.
 
Zuletzt bearbeitet:
Nach viel Rumgebastel habe Ich mein erstes funktionierendes Skript hinbekommen,

Bash:
#!/bin/bash

# Funktion: HH:MM:SS in Sekunden umwandeln
to_seconds() {
    IFS=: read -r h m s <<< "$1"
    echo $((10#$h * 3600 + 10#$m * 60 + 10#$s))
}


# In einem Terminal: Pipe erstellen und SSR starten
mkfifo /tmp/ssr_control.pipe
simplescreenrecorder --start-hidden < /tmp/ssr_control.pipe &

sleep 2
xdotool search --onlyvisible --class "Brave" windowactivate --sync
sleep 1
xdotool key --clearmodifiers space

(
    # Start
    sleep 1
    echo "record-start"

    # Pause
    sleep $(to_seconds "00:00:10")
    echo "record-pause"

    # Pause
    sleep 1
    echo "record-save"
) > /tmp/ssr_control.pipe


# Beenden
sleep 2
pkill -f simplescreenrec
 
Eine Ergänzung. Anscheinend nimmt SSR den ersten Befehl über STDIN an und danach keinen weiteren oder wartet auf Beendigung des Befehls. So ganz klar ist mir das noch nicht. Auf jeden Fall habe Ich mehrere Befehle in Klammern zusammengefasst und schicke diese gleiche Alle zu SSR über die Fifo-Pipe.
 
Eine Ergänzung. Anscheinend nimmt SSR den ersten Befehl über STDIN an und danach keinen weiteren oder wartet auf Beendigung des Befehls. So ganz klar ist mir das noch nicht.
Tja, also, obwohl ich in dem Thema auch (noch) kein Fachmann bin, kann ich das mit Perl machen: Eine längere Verbindung zu "simplescreenrecorder" mit einer Pipe aufrechterhalten, mehrere Befehle dort reinschicken, und - vor allem - auch den Buffer von SSR flushen, so daß die Befehle dort auch verarbeitet werden:
Perl:
#!/usr/bin/perl

use warnings;
use strict;

use IPC::Run qw(start);

start(["simplescreenrecorder", "--start-hidden"], '<pipe', \*IN, '>pipe', \*OUT);

sleep 5;
print IN "window-show\n";
IN->flush();

sleep 3;
print IN "window-hide\n";
IN->flush();

sleep 3;
print IN "window-show\n";
IN->flush();

sleep 3;
print IN "quit\n";
IN->flush();
sleep 5;
Bei dem, was Du gesendet hattest, war ja auch "sleep" dabei - das ist aber kein Befehl, den SSR verarbeiten kann; sollte mich wundern, wenn das so geklappt hatte.
 
sleep gibt nichts auf STDOUT aus, die Bash-Funktion echo (ebenso wie das Programm /bin/echo) schon. Beitrag 6 scheint laut Beitrag 7 nicht die endgültige Version zu sein.
 
sleep gibt nichts auf STDOUT aus, die Bash-Funktion echo (ebenso wie das Programm /bin/echo) schon. Beitrag 6 scheint laut Beitrag 7 nicht die endgültige Version zu sein.
Genau, Ich modifziere noch und werde meine endgültige Version hier hochladen. D.h. Ich lese mir das Kapitel PIPES und Dateideskriptoren nochmal durch und hier speziell das Folgende,

Bash:
3>
Ist so gut wie nicht in meiner Linux Literatur vorhanden, also nur in meinem BASH Buch von 1999 ! Traurig, sehr traurig.

Das zeigt wo die Bildungs-Literatur hingeht. Das Warum steht hier auf einem anderen Blatt und darf hier noch nicht mal genannt werden.
 
Das ist natürlich cool. Da muss es doch ein Äquivalent im BASH zu geben? Ansonsten bin Ich eher ein PYTHON Mensch. :geek::)
Python geht auch (>= 3.4):
Python:
#!/usr/bin/env python
# coding: utf-8

import subprocess
import time
import sys

if not sys.version_info >= (3, 4):
    print("Error: Needs at least Python 3.4 to work this way.")
    sys.exit(1)

p = subprocess.Popen(["simplescreenrecorder", "--start-hidden"], stdin = subprocess.PIPE, stdout = subprocess.PIPE, bufsize=1)

time.sleep(5)
p.stdin.write("window-show\n".encode())
p.stdin.flush()

time.sleep(3)
p.stdin.write("window-hide\n".encode())
p.stdin.flush()

time.sleep(3)
p.stdin.write("window-show\n".encode())
p.stdin.flush()

time.sleep(3)
p.communicate("quit\n".encode())
 
Vielleicht hilft Dir noch, was Googles KI bzgl. bash in dem Zusammenhang ausspuckt:
KI schrieb:
> Ich will mehrfach und verzögert in STDIN des Subprocesses schreiben, und muß dazu auch ein flush des STDIN des Subprocesses vornehmen.

Um dieses Verhalten in der Bash nachzubauen, ist die Verwendung einer Named Pipe (FIFO) der sauberste Weg. Eine einfache Pipe (|) würde sich schließen, sobald der erste echo-Befehl fertig ist, was den Subprozess beenden könnte.
Hier ist der Aufbau, um verzögert zu schreiben und den Stream offen zu halten:

Lösung mit Named Pipe (FIFO)
  1. Pipe erstellen: mkfifo my_pipe erzeugt eine Datei, die als Kommunikationskanal dient.
  2. Eingabe offen halten: Normalerweise schließt sich eine Pipe, wenn kein Schreiber mehr da ist. Ein Trick ist, einen Hintergrundprozess (wie sleep infinity oder einen permanenten Dateideskriptor) auf die Pipe zu legen.
  3. Subprozess starten: Er liest aus dieser Pipe.
Beispiel-Skript

bash
# 1. Named Pipe anlegen
mkfifo my_pipe

# 2. Einen Dateideskriptor (FD 3) zum Schreiben auf die Pipe öffnen.
# Das hält die Pipe offen, auch wenn einzelne Echos fertig sind.
exec 3> my_pipe

# 3. Den Subprozess im Hintergrund starten, der von der Pipe liest
cat < my_pipe &
SUB_PID=$!

# 4. Verzögert in die Pipe schreiben (über den FD 3)
echo "Erste Nachricht" >&3
sleep 2
echo "Zweite Nachricht nach 2 Sek" >&3
sleep 1
echo "Dritte Nachricht" >&3

# 5. Aufräumen: FD schließen (sendet EOF an den Subprozess) und Pipe löschen
exec 3>&-
wait $SUB_PID
rm my_pipe

Verwende Code mit Vorsicht.

Das Thema "Flush" in der Bash
In der Bash gibt es keinen expliziten flush-Befehl wie in Python (sys.stdin.flush()), da die Shell standardmäßig zeilenweise in die Pipe schreibt, sobald ein Zeilenumbruch (\n) gesendet wird. Das Betriebssystem reicht diese Daten sofort an den Leseprozess weiter.
Wichtig: Falls der Subprozess selbst die Daten puffert und nicht reagiert, liegt das meist an der C-Standard-Bibliothek des Subprozesses. In diesem Fall hilft oft das Tool stdbuf (z. B. stdbuf -i0 -o0 mein_befehl < my_pipe &), um die Pufferung des Programms komplett zu deaktivieren.
 
Oben