(esperançosamente) CÓDIGO MELHORADO NO FUNDO
Lendo o script fornecido em sua própria resposta, cheguei às seguintes conclusões sobre sua solução. Por favor, corrija-me sobre qualquer / todos os erros que eu possa ter cometido.
Você acrescenta um conjunto de dados xwininfo $GAME_WINDOW
-específico a um despejo de arquivo tmp
depois de especificar a geometria de $GAME_WINDOW
via wmctl
. Antes de iniciar o despejo, você trunca efetivamente seu arquivo tmp
para 0 bytes com rm -f
, o que presumivelmente ocorre apenas uma vez por sessão porque o fluxo é específico da sessão ou para evitar que o arquivo tmp
fique muito grande. Eu estou presumindo ambos. Eu baseio as conclusões acima nestas três linhas:
> rm -f twitch_tmp 2> /dev/null
> wmctrl -r "$GAME_WINDOW" -e 0, 411,51,160,144
> xwininfo -name "$GAME_WINDOW" >> twitch_tmp
Embora eu não esteja intimamente familiarizado com wmctl
ou xwininfo
, eu sei que eles são utilitários comuns para automatizar vários comportamentos de janelas X em X. Eu estou supondo que você está transmitindo esse conjunto de dados apenas para acompanhar quaisquer mudanças que possam ocorrer, então ffmpeg
pode fazer a coisa certa com seu transcodificador ao invés de realmente bombear os dados da fonte gráfica / sonora através dos dois seguintes > ambiente variáveis como eu duvido muito seriamente que o último comportamento funcionaria por mais do que alguns segundos se em todos:
> TOPXY=$(cat twitch_tmp | grep -oEe 'Corners:\s+\+[0-9]+\+[0-9]+' | grep -oEe '[0-9]+\+[0-9]+' | sed -e 's/\+/,/' )
> INRES=$(cat twitch_tmp | grep -oEe 'geometry [0-9]+x[0-9]+' | grep -oEe '[0-9]+x[0-9]+')
Aqui você:
- Abra dois sub-grupos
$(command substitution)
, um para cada atribuição de valor$TOPXY
e$INRES
.
Por $TOPXY
you:
- Con
cat
chame seu arquivotmp
comstdin
e anonimamente|pipe
os resultados paragrep
'stdin
que, então ... -
oEe
Omite qualquer linha e qualquer porção de qualquer linha não omitida que não contenha a string:- " Cantos: " seguido por ...
- em
+
pelo menos um caractere de espaço em branco\s
, então ... - um sinal de mais
\+
literal e, em seguida ... - em
+
menos um[0-9]
digit ... - outro
\+
literal mais ... - e, finalmente, pelo menos
+
mais um[0-9]
digit ...
- Os resultados são anonimamente
|piped
para outra instância degrep
, que subsequentemente-oEe
omite tudo antes de sua primeira captura[0-9]
dígito e anonimamente|pipe
de seus resultados para ... -
sed
whichtr
forma o literal\+
plus recebe para,
vírgulas e despeja para seustdout
que é ... - finalmente capturado e armazenado em
$TOPXY
por meio da atribuição da variável subshell$(command substituted)
.
O processo para $INRES
parece o mesmo, embora um pouco menos complexo.
O mais notável para mim é que todo o arquivo tmp
está con cat
enatado pelo menos duas vezes para cada chamada, o que é para não mencionar todos os |pipes
. Provavelmente, há muitas maneiras de fazer isso, mas não posso imaginar que isso esteja entre as melhores delas.
Depois disso, você invoca ffmpeg
referenciando as duas variáveis acima e várias outras opções, incluindo outras variáveis de ambiente que você especificou também:
ffmpeg -f x11grab -s "$INRES" -r "$FPS" -i $DISPLAY+$TOPXY \
-f pulse -i default \
-vcodec libx264 -preset $PRESET -crf 30 -x264opts keyint=50:min-keyint=20 -s $INRES \
-acodec libmp3lame -ab $AUDIO_BITRATE -ar $AUDIO_RATE_HZ \
-threads 0 -pix_fmt yuv420p \
-f flv "rtmp://$SERVER.twitch.tv/app/$STREAM_KEY"
PROBABLY MORE DIRECT
O que segue não envolve tmp
arquivos, um único |pipe
, chama apenas uma única invocação de sed
e um único subshell command substitution
para analisar suas configurações de geometria e está contido em uma única função. Todas as variáveis de ambiente são definidas em here-documents
transmitidas para seu stdin
e, portanto, estão efetivamente no escopo local. Eles também são definidos via parameter-substitution
e, portanto, são configuráveis. Por exemplo, para alterar o valor de $FPS
para uma única chamada que você precisa fazer somente:
% FPS=28 desk_stream
Por que vale a pena, no entanto, eu ainda acho que vlc
seria uma opção muito melhor.
desk_stream() { sed -rn '\
/.*((Corners:|geometry)\s*\+*([x|+|0-9]*\+)).*/{\
s///;\
/X/s/.*/\
INRES="&";/p;\
s/(.*)\+(.*)\+$/\
DISPLAY='"${DISPLAY}"'"+,,";/p;\
};$a\. 0<&3 /dev/stdin\n' | . /dev/stdin
} <<FFOPTS 3<<-\FFCMD
${FPS="15"} # target FPS
${PRESET="ultrafast"} # one of the many FFMPEG preset on (k)ubuntu found in /usr/share/ffmpeg
${THREADS="0"} #0 autostarts threads based on cpu cores.
${AUDIO_BITRATE="1k"} #Audio bitrate to 96k
${AUDIO_RATE_HZ ="44100"} #Audio rate 44100 hz
${GAME_WINDOW="MYGAMETEST"}
${STREAM_KEY=live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx}
${SERVER="live-jfk"} # NY server
$(wmctrl -r "$GAME_WINDOW" -e 0, 411,51,160,144 &&\
xwininfo -name "$GAME_WINDOW")
FFOPTS
ffmpeg -f x11grab -s "$INRES" -r "$FPS" -i $DISPLAY \
-f pulse -i default \
-vcodec libx264 -preset $PRESET -crf 30 -x264opts keyint=50:min-keyint=20 -s $INRES \
-acodec libmp3lame -ab $AUDIO_BITRATE -ar $AUDIO_RATE_HZ \
-threads 0 -pix_fmt yuv420p \
-f flv "rtmp://$SERVER.twitch.tv/app/$STREAM_KEY"
FFCMD