Grabar archivo de video (al grabar de esta forma solo estás usando el procesador sin la tarjeta gráfica):

amixer set ‘Internal Mic Boost’ 50%-

ffmpeg -f fbdev -framerate 60 -i /dev/fb0 -f v4l2 -i /dev/video0 -f alsa -i pipewire -filter_complex "[1:v]scale=320:-1[cam];[0:v][cam]overlay=main_w-overlay_w-20:20" -c:v libx264 -preset ultrafast -pix_fmt yuv420p -c:a aac -b:a 128k -async 1 -ar 48000 -latency 100 prueba.mp4

ffmpeg -f alsa -i pipewire -f fbdev -r 60 -i /dev/fb0 mamita.mkv

ffmpeg -f alsa -i pipewire -f fbdev -r 60 -i /dev/fb0 mamita.mp4
ffmpeg -f fbdev -framerate 30 -i /dev/fb0 \
       -f v4l2 -i /dev/video0 \
       -f alsa -i pipewire \
       -filter_complex "[1:v]scale=320:-1[cam];[0:v][cam]overlay=main_w-overlay_w-20:20" \
       -c:v libx264 -c:a aac output.mkv

Claude Code

ffmpeg -f alsa -i pipewire \
       -f fbdev -framerate 30 -i /dev/fb0 \
       -c:v libx264 -preset ultrafast -tune zerolatency -crf 23 \
       -threads 2 \
       -c:a aac -b:a 128k \
       -pix_fmt yuv420p \
       output.mkv

Con Webcam

ffmpeg -f fbdev -framerate 30 -i /dev/fb0 \
       -f v4l2 -framerate 15 -video_size 640x480 -i /dev/video0 \
       -f alsa -i pipewire \
       -filter_complex "[1:v]scale=240:-1[cam];[0:v][cam]overlay=main_w-overlay_w-10:10" \
       -c:v libx264 -preset ultrafast -tune zerolatency -crf 25 \
       -threads 2 \
       -c:a aac -b:a 128k \
       -pix_fmt yuv420p \
       output.mkv

Este es el que uso funciona de maravilla. (Claude AI).

ffmpeg -f alsa -i pipewire \
       -f fbdev -framerate 15 -i /dev/fb0 \
       -c:v libx264 -preset ultrafast -crf 28 \
       -threads 2 \
       -c:a aac -b:a 96k \
       -s 1024x576 \
       output.mkv

-s no sirve

ffmpeg -f alsa -i pipewire \
       -f fbdev -framerate 15 -i /dev/fb0 \
       -filter_complex "[1:v]scale=1024:576[scaled]" \
       -map 0:a -map "[scaled]" \
       -c:v libx264 -preset ultrafast -crf 28 \
       -threads 2 \
       -c:a aac -b:a 96k \
       output.mkv
Para accelerar el video eliminar el audio
ffmpeg -i output.mkv -vf "setpts=0.04*PTS" -an -c:v libx264 -preset slow -crf 28 output_acelerado.mkv

ffmpeg -i gentoo.mkv -vf "setpts=0.04*PTS" -an -c:v libx264 -preset ultrafast -crf 28 -threads 0 output_acelerado.mkv
ffmpeg -i output.mkv -vf "setpts=0.04*PTS,scale=854x480" -an -c:v libx264 -preset veryfast -crf 30 -threads 0 output_acelerado.mkv
ffmpeg -i output.mkv -vf "setpts=0.04*PTS" -an -c:v copy output_acelerado.mkv

-vf “setpts=0.04*PTS” - Acelera el video 25x (0.04 = 1/25). Tu video de 24 horas quedará en aproximadamente 58 minutos

ffprobe

ffprobe output.mkv 2>&1 | grep -E "Stream|Video:"

If CPU hits 100% constantly, the recording will stutter. Drop framerate to 20 or 15 if needed. Your hardware is pretty limited - expect some trade-offs between quality and smoothness. Start with 30fps, and if it lags, drop to 20 or 15fps.


Este es el comando que uso para grabar y tiene menos lag.

ffmpeg \
 -f fbdev -framerate 60 -i /dev/fb0 \
 -f v4l2 -i /dev/video0 \
 -f alsa -i pipewire \
 -filter_complex "[1:v]scale=320:-1[cam];[0:v][cam]overlay=main_w-overlay_w-20:20" \
 -c:v libx264 -preset ultrafast -pix_fmt yuv420p \
 -c:a aac -b:a 128k \
 -async 1 -ar 48000 -latency 100 \
 prueba.mp4

peg-this (ffmpeg TUI):

python -m venv peg_this
source peg_this/bin/activate or source peg_this/bin/activate.fish (si usas fish)
pip install peg-this
peg_this

Amplify sound with ffmpeg.

# Lento
ffmpeg -i input.mp4 -af "volume=4.0" output.mp4
# Rapido pero no anda (es rapido porque copia)
ffmpeg -i input.m4a -c:a copy -af "volume=4.0" output.m4a
ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 -f v4l2 -framerate 60 -video_size 320x240 -i /dev/video0 -filter_complex "[2:v]scale=320:240[cam];[1:v][cam]overlay=main_w-overlay_w-10:main_h-overlay_h-10[outv]" -map "[outv]" -map 0:a -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -c:a aac -b:a 128k -f flv -bufsize 1000k rtmp://a.rtmp.youtube.com/live2/stream

Para transmitir a YouTube:

Este funcionó bastante bien (sin cámara y con audio no se puede streamear sin audio en YouTube)

ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -c:a aac -b:a 128k -f flv -bufsize 1000k 

Transmitir solo la cámara a resolución HD podes ver la lista de resoluciones disponibles con el comando v4l2-ctl --list-formats-ext.

ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f v4l2 -framerate 60 -video_size 1280x720 -i /dev/video0 -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -c:a aac -b:a 128k -f flv -bufsize 1000k rtmp://a.rtmp.youtube.com/live2/stream_key
Leer el chat en vivo:
python -m venv chat-downloader
source chat-downloader/bin/active
pip install chat-downloader
chat_downloader "https://www.youtube.com/watch?v=TU_ID_DEL_VIDEO"

Camara y tty:

ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 -f v4l2 -framerate 60 -video_size 320x240 -i /dev/video0 -filter_complex "[2:v]scale=320:240[cam];[1:v][cam]overlay=main_w-overlay_w-10:main_h-overlay_h-10[outv]" -map "[outv]" -map 0:a -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -c:a aac -b:a 128k -f flv -bufsize 1000k rtmp://a.rtmp.youtube.com/live2/stream_key
Grabar video usando DRM (con kmscon), lo uso para capturar un navegador o un juego.

Para poder grabar kmscon sin sudo y grabar el audio:

sudo setcap cap_sys_admin+ep /usr/bin/ffmpeg
[esotericwarfare@arch ~]$ getcap /usr/bin/ffmpeg
/usr/bin/ffmpeg cap_sys_admin=ep

Y agrega sudo systemctl edit kmscon para arreglar colores de tmux

Para iniciar kmscon : sudo systemctl start kmscon

# no deberias usar sudo porque no vas a poder grabar el audio si te putea ejecuta lo que está mas arriba.

ffmpeg \
    -f kmsgrab -device /dev/dri/card1 -i - \
    -filter_complex "[0:v]hwdownload,format=bgr0[screen]" \
    -f v4l2 -i /dev/video0 \
    -f alsa -i pipewire \
    -filter_complex "\
        [1:v]scale=320:-1[cam]; \
        [screen][cam]overlay=main_w-overlay_w-20:20,format=yuv420p[outv]" \
    -map "[outv]" -map 2:a \
    -c:v libx264 -preset ultrafast \
    -c:a aac \
    out.mkv


ffmpeg -f alsa -i pipewire -f kmsgrab -device /dev/dri/card1 -i - -vf 'hwdownload,format=bgr0' -c:v libx264 -preset ultrafast out.mkv

ffmpeg -f v4l2 -i /dev/video0 \
       -f alsa -i pipewire \
       -filter_complex "[1:v]scale=320:-1[cam];[0:v][cam]overlay=main_w-overlay_w-20:20" \
       -f kmsgrab -device /dev/dri/card1 -i - -vf 'hwdownload,format=bgr0' -c:v libx264 -preset ultrafast out.mkv 





# Si queres usar sudo acá tenés.

sudo ffmpeg -f kmsgrab -device /dev/dri/card1 -i - -vf 'hwdownload,format=bgr0' -c:v libx264 -preset ultrafast out.mkv

ffmpeg -device /dev/dri/card1 -f kmsgrab -framerate 30 -i - -vf 'hwdownload,format=bgr0' -c:v libx264 output.mkv

ffmpeg -device /dev/dri/card1 -f kmsgrab -framerate 30 -i - -vf 'hwmap=derive_device=vaapi,format=nv12,hwdownload,format=bgr0' -c:v libx264 output.mkv
ffmpeg -device /dev/dri/card1 -f kmsgrab -framerate 30 -i - -vf 'hwmap=derive_device=vaapi,format=nv12,hwdownload,format=bgr0' -c:v libx264 output.mkv

Si tu hardware soporta VAAPI, podés ganar rendimiento cambiando -c:v libx264 por -c:v h264_vaapi.

sudo setcap cap_sys_admin+ep $(which ffmpeg)

Para bajar el volumen del micrófono: bajá el volumen Internal Mic B en alsamixer y Mic Boost y Mic.

Capturar pantalla desde Wayland y streamerlo a YouTube
ffmpeg -f pipewire -framerate 30 -video_size 1920x1080 -i @DEFAULT_VIDEOSOURCE@ \
-f pulse -i default \
-c:v libx264 -preset veryfast -b:v 4500k -c:a aac -b:a 128k -f flv \
"rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY"

Capturar pantalla con cámara.

ffmpeg -f pipewire -framerate 30 -video_size 1920x1080 -i @DEFAULT_VIDEOSOURCE@ \
-f pulse -i default \
-f v4l2 -framerate 60 -video_size 640x480 -i /dev/video0 
-filter_complex "[2:v]scale=320:240[cam];[1:v][cam]overlay=main_w-overlay_w-10:main_h-overlay_h-10[outv]" -map "[outv]" -map 0:a 
-c:v libx264 -preset veryfast -b:v 4500k -c:a aac -b:a 128k -f flv \
"rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY"
Cuando arranco stream siempre tengo que bajar el Internal Mic desde alsamixer porque sino el micrófono se satura.

Este es el script que uso para streamear desde la TTY stream.sh

#!/bin/bash
sudo chmod 666 /dev/input/event*
amixer set 'Internal Mic Boost' 50%-


falkon "https://www.youtube.com/live_dashboard"
### Solo tty
ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -c:a aac -b:a 128k -f flv -bufsize 1000k rtmp://a.rtmp.youtube.com/live2/STREAM_KEY 2> /dev/null

Este es el script que uso stream.sh

#!/bin/bash
sudo chmod 666 /dev/input/event*
amixer set 'Internal Mic Boost' 50%-


#falkon "https://www.youtube.com/live_dashboard"
### Solo tty
#ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -c:a aac -b:a 128k -f flv -async 1 -ar 48000 -latency 100 -bufsize 1000k rtmp://a.rtmp.youtube.com/live2/KEY 2> /dev/null


#### Camara con tty
ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 -f v4l2 -framerate 60 -video_size 320x240 -i /dev/video0 -filter_complex "[2:v]scale=320:240[cam];[1:v][cam]overlay=main_w-overlay_w-10:main_h-overlay_h-10[outv]" -map "[outv]" -map 0:a -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -c:a aac -b:a 128k -f flv -bufsize 1000k rtmp://a.rtmp.youtube.com/live2/KEY 2> /dev/null

### Solo camara
#ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f v4l2 -framerate 60 -video_size 1280x720 -i /dev/video0 -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -c:a aac -b:a 128k -f flv -bufsize 1000k rtmp://a.rtmp.youtube.com/live2/KEY 2> /dev/null

Para poder streamear falkon, angelfish o qutebrowser desde la TTY usa:

export QT_QPA_PLATFORM=linuxfb
export QTWEBENGINE_CHROMIUM_FLAGS="--ignore-gpu-blacklist --disable-gpu"

Para verificar si está transmitiendo:

mpv "https://www.youtube.com/channel/CHANNEL\_ID/live"

Wayland (stream)

ffmpeg \
    -f alsa -i pipewire \
    -thread_queue_size 1024 \
    -f pipewire -i pipewire \
    -f v4l2 -framerate 60 -video_size 320x240 -i /dev/video0 \
    -filter_complex "[2:v]scale=320:240[cam];[1:v][cam]overlay=main_w-overlay_w-10:main_h-overlay_h-10[outv]" \
    -map "[outv]" -map 0:a \
    -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
    -c:a aac -b:a 128k \
    -f flv -bufsize 1000k <TU_URL_RTMP>

Wayland (record)

ffmpeg \
    -f pipewire -i pipewire \        # captura de pantalla
    -f v4l2 -framerate 30 -video_size 1280x720 -i /dev/video0 \  # cámara
    -f alsa -i pipewire \            # audio del sistema (opcional)
    -filter_complex "[1:v]scale=320:240[cam];[0:v][cam]overlay=W-w-20:H-h-20[out]" \
    -map "[out]" -map 2:a \
    -c:v libx264 -preset veryfast -pix_fmt yuv420p \
    -c:a aac -b:a 128k \
    output.mp4

Grabar audios y subirlo a YouTube


#!/bin/sh
if [ $# -eq 0 ]
  then
    echo "Poné el nombre de archivo sin extension en el primer argumento"
    exit;
fi

sudo chmod 666 /dev/input/event*
amixer set 'Internal Mic Boost' 50%-


ffmpeg -f alsa -i pipewire $1.m4a
#ffmpeg -f alsa -i pulse $1.m4a



echo "Nombre de archivo $1.m4a"

echo "Generamos thumbnail para youtube"
echo "Uso el titulo del video como el nombre del audio lo mismo para el thumbnail porque no se pueden subir audios a YouTube"
echo "Gerando thumbnail..."
thumbnailg $1 "/tmp/$1.png"
echo "Creando un video a partir del audio..."
ffmpeg -i "/tmp/$1.png" -i "$1.m4a" -c:v libx264 -tune stillimage -c:a copy "/tmp/$1.mp4"

fail=1

while ((fail==1)); do
  source $HOME/youtube-upload/bin/activate
  $HOME/youtube-upload/youtube-upload/bin/youtube-upload \
    --title="$1" \
    --description="$1" \
    --recording-date="2011-03-10T15:32:17.0Z" \
    --default-language="es" \
    --default-audio-language="es" \
    --privacy="unlisted" \
    --embeddable=True "/tmp/$1.mp4" | tee -a urls
  
  fail=0;
  (($? != 0)) && echo "Falló la carga" && echo "Lo intentamos de nuevo?[y/n]" && read respuesta && ((respuesta=="y")) && fail=1
done
#!/bin/sh
if [ $# -eq 0 ]
  then
    echo "Poné el nombre de archivo sin extension en el primer argumento"
    exit;
fi

ffmpeg -f alsa -i pipewire $1.m4a
#ffmpeg -f alsa -i pulse $1.m4a

echo "Nombre de archivo $1.m4a"

echo "Generamos thumbnail para youtube"
echo "Uso el titulo del video como el nombre del audio lo mismo para el thumbnail porque no se pueden subir audios a YouTube"
echo "Gerando thumbnail..."
thumbnailg $1 "/tmp/$1.png"
echo "Creando un video a partir del audio..."
ffmpeg -i "/tmp/$1.png" -i "$1.m4a" -c:v libx264 -tune stillimage -c:a copy "/tmp/$1.mp4"

source $HOME/youtube-upload/bin/activate
$HOME/youtube-upload/youtube-upload/bin/youtube-upload \
  --title="$1" \
  --description="$1" \
  --recording-date="2011-03-10T15:32:17.0Z" \
  --default-language="es" \
  --default-audio-language="es" \
  --privacy="unlisted" \
  --embeddable=True "/tmp/$1.mp4"

Sin carpeta /tmp (me dio errores por estar llena)

#!/bin/sh
if [ $# -eq 0 ]
  then
    echo "Poné el nombre de archivo sin extension en el primer argumento"
    exit;
fi

sudo chmod 666 /dev/input/event*
amixer set 'Internal Mic Boost' 50%-

mkdir $PWD/tmp

ffmpeg -f alsa -i pipewire $1.m4a
#ffmpeg -f alsa -i pulse $1.m4a



echo "Nombre de archivo $1.m4a"

echo "Generamos thumbnail para youtube"
echo "Uso el titulo del video como el nombre del audio lo mismo para el thumbnail porque no se pueden subir audios a YouTube"
echo "Gerando thumbnail..."
thumbnailg $1 "$PWD/tmp/$1.png"
echo "Creando un video a partir del audio..."
ffmpeg -i "$PWD/tmp/$1.png" -i "$1.m4a" -c:v libx264 -tune stillimage -c:a copy "$PWD/tmp/$1.mp4"
echo "Video creado con exito?: $?"

fail=1

while ((fail==1)); do
  source $HOME/youtube-upload/bin/activate
  $HOME/youtube-upload/youtube-upload/bin/youtube-upload \
    --title="$1" \
    --description="$1" \
    --recording-date="2011-03-10T15:32:17.0Z" \
    --default-language="es" \
    --default-audio-language="es" \
    --privacy="unlisted" \
    --embeddable=True "$PWD/tmp/$1.mp4" | tee -a urls

  fail=0;
  (($? != 0)) && echo "Falló la carga" && echo "Lo intentamos de nuevo?[y/n]" && read respuesta && ((respuesta=="y")) && fail=1
done

rm -rf $PWD/tmp

Grabar pantalla y cámara.

#!/bin/bash
# Record TTY + webcam PiP + mic - low CPU version

amixer -c 0 sset 'Mic Boost' 0 2>/dev/null || amixer sset 'Mic Boost' 0 2>/dev/null

v4l2-ctl --device=/dev/video0 --set-fmt-video=width=640,height=480,pixelformat=MJPG

OUTPUT="/home/esotericwarfare/recording_$(date +%Y%m%d_%H%M%S).mkv"

ffmpeg -f v4l2 -input_format mjpeg -video_size 640x480 -framerate 15 -i /dev/video0 \
       -f fbdev -i /dev/fb0 \
       -f alsa -i hw:0 \
       -filter_complex "[0:v]scale=160:90[wc];[1:v][wc]overlay=main_w-170:main_h-100" \
       -c:v libx264 -preset ultrafast -tune zerolatency -crf 28 \
       -c:a aac -b:a 64k \
       -threads 1 \
       "$OUTPUT"

Stream: Podes usar este script (opencode):

just tty

#!/bin/bash

falkon https://studio.youtube.com/channel/UCtnEUzfISySqwOkWH4nRoww/livestreaming/dashboard

PIDFILE="/tmp/ffmpeg-stream.pid"
STREAM_URL="rtmp://a.rtmp.youtube.com/live2/XXXXXXXX"

kill_stream() {
    if [ -f "$PIDFILE" ]; then
        kill $(cat "$PIDFILE") 2>/dev/null
        rm "$PIDFILE"
        sleep 1
    fi
}

stream_tty() {
    kill_stream
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer -c 0 set "Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Internal Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Capture" 30 2>/dev/null
    ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k -f flv -bufsize 1000k "$STREAM_URL" 2>/dev/null &
    echo $! > "$PIDFILE"
}

stream_cam() {
    kill_stream
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer -c 0 set "Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Internal Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Capture" 30 2>/dev/null
    ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f v4l2 -framerate 60 -video_size 1280x720 -i /dev/video0 \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k -f flv -bufsize 1000k "$STREAM_URL" 2>/dev/null &
    echo $! > "$PIDFILE"
}

stream_tty_cam() {
    kill_stream
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer -c 0 set "Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Internal Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Capture" 30 2>/dev/null
    ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 \
        -f v4l2 -framerate 60 -video_size 320x240 -i /dev/video0 \
        -filter_complex "[2:v]scale=320:240[cam];[1:v][cam]overlay=main_w-overlay_w-10:main_h-overlay_h-10[outv]" \
        -map "[outv]" -map 0:a \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k -f flv -bufsize 1000k "$STREAM_URL" 2>/dev/null &
    echo $! > "$PIDFILE"
}

case "$1" in
    tty) stream_tty ;;
    cam) stream_cam ;;
    both) stream_tty_cam ;;
    stop) kill_stream; echo "Stream stopped" ;;
    *)
        echo "Usage: $0 {tty|cam|both|stop}"
        exit 1 ;;
esac

X11

#!/bin/bash
PIDFILE="/tmp/ffmpeg-stream.pid"
STREAM_URL="rtmp://a.rtmp.youtube.com/live2/XXXXXXX"

get_resolution() {
    if command -v xrandr &>/dev/null; then
        xrandr --current 2>/dev/null | grep -A1 'connected' | grep -oE '[0-9]+x[0-9]+' | head -1
    else
        echo "1366x768"
    fi
}

kill_stream() {
    if [ -f "$PIDFILE" ]; then
        kill $(cat "$PIDFILE") 2>/dev/null
        rm "$PIDFILE"
        sleep 1
    fi
}

stream_x11() {
    kill_stream
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer -c 0 set "Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Internal Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Capture" 30 2>/dev/null
    local res=$(get_resolution)
    ffmpeg -f x11grab -draw_mouse 1 -framerate 60 -video_size "$res" -i :0.0 \
        -f alsa -i pipewire -thread_queue_size 1024 \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k -f flv -bufsize 1000k "$STREAM_URL" 2>/dev/null &
    echo $! > "$PIDFILE"
}

stream_x11_cam() {
    kill_stream
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer -c 0 set "Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Internal Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Capture" 30 2>/dev/null
    local res=$(get_resolution)
    ffmpeg -f x11grab -draw_mouse 1 -framerate 60 -video_size "$res" -i :0.0 \
        -f alsa -i pipewire -thread_queue_size 1024 \
        -f v4l2 -framerate 60 -video_size 320x240 -i /dev/video0 \
        -filter_complex "[0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10[out]" \
        -map "[out]" -map 1:a \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k -f flv -bufsize 1000k "$STREAM_URL" 2>/dev/null &
    echo $! > "$PIDFILE"
}

stream_x11_audio() {
    kill_stream
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer set 'Internal Mic Boost' 50%- 2>/dev/null
    local res=$(get_resolution)
    ffmpeg -f x11grab -draw_mouse 1 -framerate 60 -video_size "$res" -i :0.0 \
        -f alsa -i hw:0,0 -thread_queue_size 1024 \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k -f flv -bufsize 1000k "$STREAM_URL" 2>/dev/null &
    echo $! > "$PIDFILE"
}

stream_x11_region() {
    kill_stream
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer set 'Internal Mic Boost' 50%- 2>/dev/null
    ffmpeg -f x11grab -draw_mouse 1 -framerate 60 -video_size 1366x768 -i :0.0+100,50 \
        -f alsa -i pipewire -thread_queue_size 1024 \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k -f flv -bufsize 1000k "$STREAM_URL" 2>/dev/null &
    echo $! > "$PIDFILE"
}

case "$1" in
    x11) stream_x11 ;;
    cam) stream_x11_cam ;;
    audio) stream_x11_audio ;;
    region) stream_x11_region ;;
    stop) kill_stream; echo "Stream stopped" ;;
    *)
        echo "Usage: $0 {x11|cam|audio|region|stop}"
        echo ""
        echo "  x11    - X11 screen + mic (detecta resolucion automaticamente)"
        echo "  cam   - X11 screen + webcam overlay + mic"
        echo "  audio - X11 screen + ALSA audio (no pipewire)"
        echo "  region - X11 screen region (1280x720 desde 100,50)"
        echo "  stop  - stop streaming"
        exit 1 ;;
esac

grabar_tty.sh sin streamear

#!/bin/bash
PIDFILE="/tmp/ffmpeg-grab.pid"
OUTPUT_DIR="${OUTPUT_DIR:-$HOME}"

kill_recording() {
    if [ -f "$PIDFILE" ]; then
        kill $(cat "$PIDFILE") 2>/dev/null
        rm "$PIDFILE"
        sleep 1
    fi
}

record_tty() {
    kill_recording
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer -c 0 set "Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Internal Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Capture" 30 2>/dev/null
    local output="${1:-$OUTPUT_DIR/tty_$(date +%Y%m%d_%H%M%S).mkv}"
    ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k "$output" 2>/dev/null &
    echo $! > "$PIDFILE"
    echo "Recording to: $output"
}

record_cam() {
    kill_recording
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer -c 0 set "Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Internal Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Capture" 30 2>/dev/null
    local output="${1:-$OUTPUT_DIR/cam_$(date +%Y%m%d_%H%M%S).mkv}"
    ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f v4l2 -framerate 60 -video_size 1280x720 -i /dev/video0 \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k "$output" 2>/dev/null &
    echo $! > "$PIDFILE"
    echo "Recording to: $output"
}

record_tty_cam() {
    kill_recording
    sudo chmod 666 /dev/input/event* 2>/dev/null
    amixer -c 0 set "Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Internal Mic Boost" 0 2>/dev/null
    amixer -c 0 set "Capture" 30 2>/dev/null
    local output="${1:-$OUTPUT_DIR/tty_cam_$(date +%Y%m%d_%H%M%S).mkv}"
    ffmpeg -f alsa -i pipewire -thread_queue_size 1024 -f fbdev -framerate 60 -i /dev/fb0 \
        -f v4l2 -framerate 60 -video_size 320x240 -i /dev/video0 \
        -filter_complex "[2:v]scale=320:240[cam];[1:v][cam]overlay=main_w-overlay_w-10:main_h-overlay_h-10[outv]" \
        -map "[outv]" -map 0:a \
        -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p \
        -c:a aac -b:a 128k "$output" 2>/dev/null &
    echo $! > "$PIDFILE"
    echo "Recording to: $output"
}

case "$1" in
    tty)
        record_tty "$2"
        ;;
    cam)
        record_cam "$2"
        ;;
    both)
        record_tty_cam "$2"
        ;;
    stop)
        kill_recording
        echo "Recording stopped"
        ;;
    *)
        echo "Usage: $0 {tty|cam|both|stop} [output_file]"
        exit 1
        ;;
esac